2010-03-17 12:08:17 +01:00
|
|
|
/*
|
|
|
|
* vhost-net support
|
|
|
|
*
|
|
|
|
* Copyright Red Hat, Inc. 2010
|
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Michael S. Tsirkin <mst@redhat.com>
|
|
|
|
*
|
|
|
|
* This work is licensed under the terms of the GNU GPL, version 2. See
|
|
|
|
* the COPYING file in the top-level directory.
|
2012-01-13 17:44:23 +01:00
|
|
|
*
|
|
|
|
* Contributions after 2012-01-13 are licensed under the terms of the
|
|
|
|
* GNU GPL, version 2 or (at your option) any later version.
|
2010-03-17 12:08:17 +01:00
|
|
|
*/
|
|
|
|
|
2016-01-26 19:17:11 +01:00
|
|
|
#include "qemu/osdep.h"
|
2012-10-24 08:43:34 +02:00
|
|
|
#include "net/net.h"
|
2010-03-17 12:08:17 +01:00
|
|
|
#include "net/tap.h"
|
2014-06-10 12:02:16 +02:00
|
|
|
#include "net/vhost-user.h"
|
2020-07-01 16:55:37 +02:00
|
|
|
#include "net/vhost-vdpa.h"
|
2010-03-17 12:08:17 +01:00
|
|
|
|
2019-02-14 18:35:50 +01:00
|
|
|
#include "standard-headers/linux/vhost_types.h"
|
2013-02-05 17:06:20 +01:00
|
|
|
#include "hw/virtio/virtio-net.h"
|
|
|
|
#include "net/vhost_net.h"
|
2021-06-09 17:46:52 +02:00
|
|
|
#include "qapi/error.h"
|
2012-12-17 18:20:00 +01:00
|
|
|
#include "qemu/error-report.h"
|
Include qemu/main-loop.h less
In my "build everything" tree, changing qemu/main-loop.h triggers a
recompile of some 5600 out of 6600 objects (not counting tests and
objects that don't depend on qemu/osdep.h). It includes block/aio.h,
which in turn includes qemu/event_notifier.h, qemu/notify.h,
qemu/processor.h, qemu/qsp.h, qemu/queue.h, qemu/thread-posix.h,
qemu/thread.h, qemu/timer.h, and a few more.
Include qemu/main-loop.h only where it's needed. Touching it now
recompiles only some 1700 objects. For block/aio.h and
qemu/event_notifier.h, these numbers drop from 5600 to 2800. For the
others, they shrink only slightly.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20190812052359.30071-21-armbru@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
2019-08-12 07:23:50 +02:00
|
|
|
#include "qemu/main-loop.h"
|
2010-03-17 12:08:17 +01:00
|
|
|
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <net/if.h>
|
|
|
|
#include <netinet/in.h>
|
|
|
|
|
|
|
|
|
2015-02-16 22:35:40 +01:00
|
|
|
#include "standard-headers/linux/virtio_ring.h"
|
2013-02-05 17:06:20 +01:00
|
|
|
#include "hw/virtio/vhost.h"
|
2013-04-24 10:21:21 +02:00
|
|
|
#include "hw/virtio/virtio-bus.h"
|
2022-10-17 11:25:53 +02:00
|
|
|
#include "linux-headers/linux/vhost.h"
|
2010-03-17 12:08:17 +01:00
|
|
|
|
|
|
|
|
2014-05-27 14:04:42 +02:00
|
|
|
/* Features supported by host kernel. */
|
|
|
|
static const int kernel_feature_bits[] = {
|
|
|
|
VIRTIO_F_NOTIFY_ON_EMPTY,
|
|
|
|
VIRTIO_RING_F_INDIRECT_DESC,
|
|
|
|
VIRTIO_RING_F_EVENT_IDX,
|
|
|
|
VIRTIO_NET_F_MRG_RXBUF,
|
2015-06-04 12:34:19 +02:00
|
|
|
VIRTIO_F_VERSION_1,
|
2016-12-10 16:30:37 +01:00
|
|
|
VIRTIO_NET_F_MTU,
|
2017-01-11 05:32:12 +01:00
|
|
|
VIRTIO_F_IOMMU_PLATFORM,
|
2019-10-25 10:35:26 +02:00
|
|
|
VIRTIO_F_RING_PACKED,
|
2022-10-17 11:25:57 +02:00
|
|
|
VIRTIO_F_RING_RESET,
|
2021-05-14 13:48:33 +02:00
|
|
|
VIRTIO_NET_F_HASH_REPORT,
|
2014-05-27 14:04:42 +02:00
|
|
|
VHOST_INVALID_FEATURE_BIT
|
|
|
|
};
|
|
|
|
|
2014-05-27 14:06:16 +02:00
|
|
|
/* Features supported by others. */
|
2015-02-28 19:19:17 +01:00
|
|
|
static const int user_feature_bits[] = {
|
2014-05-27 14:06:16 +02:00
|
|
|
VIRTIO_F_NOTIFY_ON_EMPTY,
|
|
|
|
VIRTIO_RING_F_INDIRECT_DESC,
|
|
|
|
VIRTIO_RING_F_EVENT_IDX,
|
|
|
|
|
|
|
|
VIRTIO_F_ANY_LAYOUT,
|
2015-06-04 12:34:19 +02:00
|
|
|
VIRTIO_F_VERSION_1,
|
2014-05-27 14:06:16 +02:00
|
|
|
VIRTIO_NET_F_CSUM,
|
|
|
|
VIRTIO_NET_F_GUEST_CSUM,
|
|
|
|
VIRTIO_NET_F_GSO,
|
|
|
|
VIRTIO_NET_F_GUEST_TSO4,
|
|
|
|
VIRTIO_NET_F_GUEST_TSO6,
|
|
|
|
VIRTIO_NET_F_GUEST_ECN,
|
|
|
|
VIRTIO_NET_F_GUEST_UFO,
|
|
|
|
VIRTIO_NET_F_HOST_TSO4,
|
|
|
|
VIRTIO_NET_F_HOST_TSO6,
|
|
|
|
VIRTIO_NET_F_HOST_ECN,
|
|
|
|
VIRTIO_NET_F_HOST_UFO,
|
|
|
|
VIRTIO_NET_F_MRG_RXBUF,
|
2016-12-10 16:30:37 +01:00
|
|
|
VIRTIO_NET_F_MTU,
|
2017-06-02 12:18:31 +02:00
|
|
|
VIRTIO_F_IOMMU_PLATFORM,
|
2019-10-25 10:35:26 +02:00
|
|
|
VIRTIO_F_RING_PACKED,
|
2022-11-21 11:11:01 +01:00
|
|
|
VIRTIO_F_RING_RESET,
|
2021-05-14 13:48:33 +02:00
|
|
|
VIRTIO_NET_F_RSS,
|
|
|
|
VIRTIO_NET_F_HASH_REPORT,
|
2023-08-01 00:31:47 +02:00
|
|
|
VIRTIO_NET_F_GUEST_USO4,
|
|
|
|
VIRTIO_NET_F_GUEST_USO6,
|
|
|
|
VIRTIO_NET_F_HOST_USO,
|
2014-05-27 14:06:16 +02:00
|
|
|
|
2015-11-17 15:55:17 +01:00
|
|
|
/* This bit implies RARP isn't sent by QEMU out of band */
|
2015-10-09 17:17:31 +02:00
|
|
|
VIRTIO_NET_F_GUEST_ANNOUNCE,
|
|
|
|
|
2014-05-27 14:06:16 +02:00
|
|
|
VIRTIO_NET_F_MQ,
|
|
|
|
|
|
|
|
VHOST_INVALID_FEATURE_BIT
|
|
|
|
};
|
|
|
|
|
2014-05-27 14:04:42 +02:00
|
|
|
static const int *vhost_net_get_feature_bits(struct vhost_net *net)
|
2010-03-17 12:08:17 +01:00
|
|
|
{
|
2014-05-27 14:04:42 +02:00
|
|
|
const int *feature_bits = 0;
|
|
|
|
|
|
|
|
switch (net->nc->info->type) {
|
qapi: Change Netdev into a flat union
This is a mostly-mechanical conversion that creates a new flat
union 'Netdev' QAPI type that covers all the branches of the
former 'NetClientOptions' simple union, where the branches are
now listed in a new 'NetClientDriver' enum rather than generated
from the simple union. The existence of a flat union has no
change to the command line syntax accepted for new code, and
will make it possible for a future patch to switch the QMP
command to parse a boxed union for no change to valid QMP; but
it does have some ripple effect on the C code when dealing with
the new types.
While making the conversion, note that the 'NetLegacy' type
remains unchanged: it applies only to legacy command line options,
and will not be ported to QMP, so it should remain a wrapper
around a simple union; to avoid confusion, the type named
'NetClientOptions' is now gone, and we introduce 'NetLegacyOptions'
in its place. Then, in the C code, we convert from NetLegacy to
Netdev as soon as possible, so that the bulk of the net stack
only has to deal with one QAPI type, not two. Note that since
the old legacy code always rejected 'hubport', we can just omit
that branch from the new 'NetLegacyOptions' simple union.
Based on an idea originally by Zoltán Kővágó <DirtY.iCE.hu@gmail.com>:
Message-Id: <01a527fbf1a5de880091f98cf011616a78adeeee.1441627176.git.DirtY.iCE.hu@gmail.com>
although the sed script in that patch no longer applies due to
other changes in the tree since then, and I also did some manual
cleanups (such as fixing whitespace to keep checkpatch happy).
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1468468228-27827-13-git-send-email-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[Fixup from Eric squashed in]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2016-07-14 05:50:23 +02:00
|
|
|
case NET_CLIENT_DRIVER_TAP:
|
2014-05-27 14:04:42 +02:00
|
|
|
feature_bits = kernel_feature_bits;
|
|
|
|
break;
|
qapi: Change Netdev into a flat union
This is a mostly-mechanical conversion that creates a new flat
union 'Netdev' QAPI type that covers all the branches of the
former 'NetClientOptions' simple union, where the branches are
now listed in a new 'NetClientDriver' enum rather than generated
from the simple union. The existence of a flat union has no
change to the command line syntax accepted for new code, and
will make it possible for a future patch to switch the QMP
command to parse a boxed union for no change to valid QMP; but
it does have some ripple effect on the C code when dealing with
the new types.
While making the conversion, note that the 'NetLegacy' type
remains unchanged: it applies only to legacy command line options,
and will not be ported to QMP, so it should remain a wrapper
around a simple union; to avoid confusion, the type named
'NetClientOptions' is now gone, and we introduce 'NetLegacyOptions'
in its place. Then, in the C code, we convert from NetLegacy to
Netdev as soon as possible, so that the bulk of the net stack
only has to deal with one QAPI type, not two. Note that since
the old legacy code always rejected 'hubport', we can just omit
that branch from the new 'NetLegacyOptions' simple union.
Based on an idea originally by Zoltán Kővágó <DirtY.iCE.hu@gmail.com>:
Message-Id: <01a527fbf1a5de880091f98cf011616a78adeeee.1441627176.git.DirtY.iCE.hu@gmail.com>
although the sed script in that patch no longer applies due to
other changes in the tree since then, and I also did some manual
cleanups (such as fixing whitespace to keep checkpatch happy).
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1468468228-27827-13-git-send-email-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[Fixup from Eric squashed in]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2016-07-14 05:50:23 +02:00
|
|
|
case NET_CLIENT_DRIVER_VHOST_USER:
|
2014-05-27 14:06:16 +02:00
|
|
|
feature_bits = user_feature_bits;
|
|
|
|
break;
|
2020-07-01 16:55:37 +02:00
|
|
|
#ifdef CONFIG_VHOST_NET_VDPA
|
|
|
|
case NET_CLIENT_DRIVER_VHOST_VDPA:
|
|
|
|
feature_bits = vdpa_feature_bits;
|
|
|
|
break;
|
|
|
|
#endif
|
2014-05-27 14:04:42 +02:00
|
|
|
default:
|
|
|
|
error_report("Feature bits not defined for this type: %d",
|
|
|
|
net->nc->info->type);
|
|
|
|
break;
|
2010-07-16 10:43:43 +02:00
|
|
|
}
|
2014-05-27 14:04:42 +02:00
|
|
|
|
|
|
|
return feature_bits;
|
|
|
|
}
|
|
|
|
|
2015-06-04 12:34:20 +02:00
|
|
|
uint64_t vhost_net_get_features(struct vhost_net *net, uint64_t features)
|
2014-05-27 14:04:42 +02:00
|
|
|
{
|
|
|
|
return vhost_get_features(&net->dev, vhost_net_get_feature_bits(net),
|
|
|
|
features);
|
2010-03-17 12:08:17 +01:00
|
|
|
}
|
2020-07-01 16:55:36 +02:00
|
|
|
int vhost_net_get_config(struct vhost_net *net, uint8_t *config,
|
|
|
|
uint32_t config_len)
|
|
|
|
{
|
2021-06-09 17:46:56 +02:00
|
|
|
return vhost_dev_get_config(&net->dev, config, config_len, NULL);
|
2020-07-01 16:55:36 +02:00
|
|
|
}
|
|
|
|
int vhost_net_set_config(struct vhost_net *net, const uint8_t *data,
|
|
|
|
uint32_t offset, uint32_t size, uint32_t flags)
|
|
|
|
{
|
|
|
|
return vhost_dev_set_config(&net->dev, data, offset, size, flags);
|
|
|
|
}
|
2010-03-17 12:08:17 +01:00
|
|
|
|
2015-06-04 12:34:20 +02:00
|
|
|
void vhost_net_ack_features(struct vhost_net *net, uint64_t features)
|
2010-03-17 12:08:17 +01:00
|
|
|
{
|
2014-09-03 08:25:30 +02:00
|
|
|
net->dev.acked_features = net->dev.backend_features;
|
2014-05-27 14:04:42 +02:00
|
|
|
vhost_ack_features(&net->dev, vhost_net_get_feature_bits(net), features);
|
2010-03-17 12:08:17 +01:00
|
|
|
}
|
|
|
|
|
2015-09-23 06:19:58 +02:00
|
|
|
uint64_t vhost_net_get_max_queues(VHostNetState *net)
|
|
|
|
{
|
|
|
|
return net->dev.max_queues;
|
|
|
|
}
|
|
|
|
|
2016-06-06 18:45:05 +02:00
|
|
|
uint64_t vhost_net_get_acked_features(VHostNetState *net)
|
|
|
|
{
|
|
|
|
return net->dev.acked_features;
|
|
|
|
}
|
|
|
|
|
2022-12-21 14:06:40 +01:00
|
|
|
void vhost_net_save_acked_features(NetClientState *nc)
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_VHOST_NET_USER
|
|
|
|
if (nc->info->type == NET_CLIENT_DRIVER_VHOST_USER) {
|
|
|
|
vhost_user_save_acked_features(nc);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2012-07-24 17:35:13 +02:00
|
|
|
static int vhost_net_get_fd(NetClientState *backend)
|
2010-03-17 12:08:17 +01:00
|
|
|
{
|
|
|
|
switch (backend->info->type) {
|
qapi: Change Netdev into a flat union
This is a mostly-mechanical conversion that creates a new flat
union 'Netdev' QAPI type that covers all the branches of the
former 'NetClientOptions' simple union, where the branches are
now listed in a new 'NetClientDriver' enum rather than generated
from the simple union. The existence of a flat union has no
change to the command line syntax accepted for new code, and
will make it possible for a future patch to switch the QMP
command to parse a boxed union for no change to valid QMP; but
it does have some ripple effect on the C code when dealing with
the new types.
While making the conversion, note that the 'NetLegacy' type
remains unchanged: it applies only to legacy command line options,
and will not be ported to QMP, so it should remain a wrapper
around a simple union; to avoid confusion, the type named
'NetClientOptions' is now gone, and we introduce 'NetLegacyOptions'
in its place. Then, in the C code, we convert from NetLegacy to
Netdev as soon as possible, so that the bulk of the net stack
only has to deal with one QAPI type, not two. Note that since
the old legacy code always rejected 'hubport', we can just omit
that branch from the new 'NetLegacyOptions' simple union.
Based on an idea originally by Zoltán Kővágó <DirtY.iCE.hu@gmail.com>:
Message-Id: <01a527fbf1a5de880091f98cf011616a78adeeee.1441627176.git.DirtY.iCE.hu@gmail.com>
although the sed script in that patch no longer applies due to
other changes in the tree since then, and I also did some manual
cleanups (such as fixing whitespace to keep checkpatch happy).
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1468468228-27827-13-git-send-email-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[Fixup from Eric squashed in]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2016-07-14 05:50:23 +02:00
|
|
|
case NET_CLIENT_DRIVER_TAP:
|
2010-03-17 12:08:17 +01:00
|
|
|
return tap_get_fd(backend);
|
|
|
|
default:
|
|
|
|
fprintf(stderr, "vhost-net requires tap backend\n");
|
2019-02-14 18:35:52 +01:00
|
|
|
return -ENOSYS;
|
2010-03-17 12:08:17 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-27 14:05:22 +02:00
|
|
|
struct vhost_net *vhost_net_init(VhostNetOptions *options)
|
2010-03-17 12:08:17 +01:00
|
|
|
{
|
|
|
|
int r;
|
2014-05-27 14:05:49 +02:00
|
|
|
bool backend_kernel = options->backend_type == VHOST_BACKEND_TYPE_KERNEL;
|
2016-07-26 23:15:03 +02:00
|
|
|
struct vhost_net *net = g_new0(struct vhost_net, 1);
|
2016-06-06 18:45:05 +02:00
|
|
|
uint64_t features = 0;
|
2021-06-09 17:46:52 +02:00
|
|
|
Error *local_err = NULL;
|
2014-05-27 14:05:22 +02:00
|
|
|
|
|
|
|
if (!options->net_backend) {
|
|
|
|
fprintf(stderr, "vhost-net requires net backend to be setup\n");
|
2010-03-17 12:08:17 +01:00
|
|
|
goto fail;
|
|
|
|
}
|
vhost-user: add multiple queue support
This patch is initially based a patch from Nikolay Nikolaev.
This patch adds vhost-user multiple queue support, by creating a nc
and vhost_net pair for each queue.
Qemu exits if find that the backend can't support the number of requested
queues (by providing queues=# option). The max number is queried by a
new message, VHOST_USER_GET_QUEUE_NUM, and is sent only when protocol
feature VHOST_USER_PROTOCOL_F_MQ is present first.
The max queue check is done at vhost-user initiation stage. We initiate
one queue first, which, in the meantime, also gets the max_queues the
backend supports.
In older version, it was reported that some messages are sent more times
than necessary. Here we came an agreement with Michael that we could
categorize vhost user messages to 2 types: non-vring specific messages,
which should be sent only once, and vring specific messages, which should
be sent per queue.
Here I introduced a helper function vhost_user_one_time_request(), which
lists following messages as non-vring specific messages:
VHOST_USER_SET_OWNER
VHOST_USER_RESET_DEVICE
VHOST_USER_SET_MEM_TABLE
VHOST_USER_GET_QUEUE_NUM
For above messages, we simply ignore them when they are not sent the first
time.
Signed-off-by: Nikolay Nikolaev <n.nikolaev@virtualopensystems.com>
Signed-off-by: Changchun Ouyang <changchun.ouyang@intel.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Tested-by: Marcel Apfelbaum <marcel@redhat.com>
2015-09-23 06:20:00 +02:00
|
|
|
net->nc = options->net_backend;
|
2021-09-03 11:10:15 +02:00
|
|
|
net->dev.nvqs = options->nvqs;
|
2014-05-27 14:05:22 +02:00
|
|
|
|
2015-09-23 06:19:58 +02:00
|
|
|
net->dev.max_queues = 1;
|
vhost-user: add multiple queue support
This patch is initially based a patch from Nikolay Nikolaev.
This patch adds vhost-user multiple queue support, by creating a nc
and vhost_net pair for each queue.
Qemu exits if find that the backend can't support the number of requested
queues (by providing queues=# option). The max number is queried by a
new message, VHOST_USER_GET_QUEUE_NUM, and is sent only when protocol
feature VHOST_USER_PROTOCOL_F_MQ is present first.
The max queue check is done at vhost-user initiation stage. We initiate
one queue first, which, in the meantime, also gets the max_queues the
backend supports.
In older version, it was reported that some messages are sent more times
than necessary. Here we came an agreement with Michael that we could
categorize vhost user messages to 2 types: non-vring specific messages,
which should be sent only once, and vring specific messages, which should
be sent per queue.
Here I introduced a helper function vhost_user_one_time_request(), which
lists following messages as non-vring specific messages:
VHOST_USER_SET_OWNER
VHOST_USER_RESET_DEVICE
VHOST_USER_SET_MEM_TABLE
VHOST_USER_GET_QUEUE_NUM
For above messages, we simply ignore them when they are not sent the first
time.
Signed-off-by: Nikolay Nikolaev <n.nikolaev@virtualopensystems.com>
Signed-off-by: Changchun Ouyang <changchun.ouyang@intel.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Tested-by: Marcel Apfelbaum <marcel@redhat.com>
2015-09-23 06:20:00 +02:00
|
|
|
net->dev.vqs = net->vqs;
|
2015-09-23 06:19:58 +02:00
|
|
|
|
2014-05-27 14:05:49 +02:00
|
|
|
if (backend_kernel) {
|
|
|
|
r = vhost_net_get_fd(options->net_backend);
|
|
|
|
if (r < 0) {
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
net->dev.backend_features = qemu_has_vnet_hdr(options->net_backend)
|
2015-06-04 12:34:20 +02:00
|
|
|
? 0 : (1ULL << VHOST_NET_F_VIRTIO_NET_HDR);
|
2014-05-27 14:05:49 +02:00
|
|
|
net->backend = r;
|
2015-09-23 06:19:56 +02:00
|
|
|
net->dev.protocol_features = 0;
|
2014-05-27 14:05:49 +02:00
|
|
|
} else {
|
|
|
|
net->dev.backend_features = 0;
|
2015-09-23 06:19:56 +02:00
|
|
|
net->dev.protocol_features = 0;
|
2014-05-27 14:05:49 +02:00
|
|
|
net->backend = -1;
|
2010-03-17 12:08:17 +01:00
|
|
|
|
vhost-user: add multiple queue support
This patch is initially based a patch from Nikolay Nikolaev.
This patch adds vhost-user multiple queue support, by creating a nc
and vhost_net pair for each queue.
Qemu exits if find that the backend can't support the number of requested
queues (by providing queues=# option). The max number is queried by a
new message, VHOST_USER_GET_QUEUE_NUM, and is sent only when protocol
feature VHOST_USER_PROTOCOL_F_MQ is present first.
The max queue check is done at vhost-user initiation stage. We initiate
one queue first, which, in the meantime, also gets the max_queues the
backend supports.
In older version, it was reported that some messages are sent more times
than necessary. Here we came an agreement with Michael that we could
categorize vhost user messages to 2 types: non-vring specific messages,
which should be sent only once, and vring specific messages, which should
be sent per queue.
Here I introduced a helper function vhost_user_one_time_request(), which
lists following messages as non-vring specific messages:
VHOST_USER_SET_OWNER
VHOST_USER_RESET_DEVICE
VHOST_USER_SET_MEM_TABLE
VHOST_USER_GET_QUEUE_NUM
For above messages, we simply ignore them when they are not sent the first
time.
Signed-off-by: Nikolay Nikolaev <n.nikolaev@virtualopensystems.com>
Signed-off-by: Changchun Ouyang <changchun.ouyang@intel.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Tested-by: Marcel Apfelbaum <marcel@redhat.com>
2015-09-23 06:20:00 +02:00
|
|
|
/* vhost-user needs vq_index to initiate a specific queue pair */
|
|
|
|
net->dev.vq_index = net->nc->queue_index * net->dev.nvqs;
|
|
|
|
}
|
2012-12-24 16:37:01 +01:00
|
|
|
|
2014-05-27 14:05:22 +02:00
|
|
|
r = vhost_dev_init(&net->dev, options->opaque,
|
2021-06-09 17:46:52 +02:00
|
|
|
options->backend_type, options->busyloop_timeout,
|
|
|
|
&local_err);
|
2010-03-17 12:08:17 +01:00
|
|
|
if (r < 0) {
|
2021-06-09 17:46:52 +02:00
|
|
|
error_report_err(local_err);
|
2010-03-17 12:08:17 +01:00
|
|
|
goto fail;
|
|
|
|
}
|
2014-05-27 14:05:49 +02:00
|
|
|
if (backend_kernel) {
|
2014-09-11 23:55:48 +02:00
|
|
|
if (!qemu_has_vnet_hdr_len(options->net_backend,
|
|
|
|
sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
|
2015-06-04 12:34:20 +02:00
|
|
|
net->dev.features &= ~(1ULL << VIRTIO_NET_F_MRG_RXBUF);
|
2014-09-11 23:55:48 +02:00
|
|
|
}
|
2014-05-27 14:05:49 +02:00
|
|
|
if (~net->dev.features & net->dev.backend_features) {
|
2022-03-18 15:04:40 +01:00
|
|
|
fprintf(stderr, "vhost lacks feature mask 0x%" PRIx64
|
2014-05-27 14:05:49 +02:00
|
|
|
" for backend\n",
|
|
|
|
(uint64_t)(~net->dev.features & net->dev.backend_features));
|
|
|
|
goto fail;
|
|
|
|
}
|
2010-03-17 12:08:17 +01:00
|
|
|
}
|
2016-06-06 18:45:05 +02:00
|
|
|
|
2010-03-17 12:08:17 +01:00
|
|
|
/* Set sane init value. Override when guest acks. */
|
2019-02-14 18:35:49 +01:00
|
|
|
#ifdef CONFIG_VHOST_NET_USER
|
qapi: Change Netdev into a flat union
This is a mostly-mechanical conversion that creates a new flat
union 'Netdev' QAPI type that covers all the branches of the
former 'NetClientOptions' simple union, where the branches are
now listed in a new 'NetClientDriver' enum rather than generated
from the simple union. The existence of a flat union has no
change to the command line syntax accepted for new code, and
will make it possible for a future patch to switch the QMP
command to parse a boxed union for no change to valid QMP; but
it does have some ripple effect on the C code when dealing with
the new types.
While making the conversion, note that the 'NetLegacy' type
remains unchanged: it applies only to legacy command line options,
and will not be ported to QMP, so it should remain a wrapper
around a simple union; to avoid confusion, the type named
'NetClientOptions' is now gone, and we introduce 'NetLegacyOptions'
in its place. Then, in the C code, we convert from NetLegacy to
Netdev as soon as possible, so that the bulk of the net stack
only has to deal with one QAPI type, not two. Note that since
the old legacy code always rejected 'hubport', we can just omit
that branch from the new 'NetLegacyOptions' simple union.
Based on an idea originally by Zoltán Kővágó <DirtY.iCE.hu@gmail.com>:
Message-Id: <01a527fbf1a5de880091f98cf011616a78adeeee.1441627176.git.DirtY.iCE.hu@gmail.com>
although the sed script in that patch no longer applies due to
other changes in the tree since then, and I also did some manual
cleanups (such as fixing whitespace to keep checkpatch happy).
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1468468228-27827-13-git-send-email-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[Fixup from Eric squashed in]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2016-07-14 05:50:23 +02:00
|
|
|
if (net->nc->info->type == NET_CLIENT_DRIVER_VHOST_USER) {
|
2016-06-06 18:45:05 +02:00
|
|
|
features = vhost_user_get_acked_features(net->nc);
|
|
|
|
if (~net->dev.features & features) {
|
2022-03-18 15:04:40 +01:00
|
|
|
fprintf(stderr, "vhost lacks feature mask 0x%" PRIx64
|
2016-06-06 18:45:05 +02:00
|
|
|
" for backend\n",
|
|
|
|
(uint64_t)(~net->dev.features & features));
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
}
|
2019-02-14 18:35:49 +01:00
|
|
|
#endif
|
2016-06-06 18:45:05 +02:00
|
|
|
|
|
|
|
vhost_net_ack_features(net, features);
|
|
|
|
|
2010-03-17 12:08:17 +01:00
|
|
|
return net;
|
2016-07-26 23:15:03 +02:00
|
|
|
|
2010-03-17 12:08:17 +01:00
|
|
|
fail:
|
2016-07-26 23:15:03 +02:00
|
|
|
vhost_dev_cleanup(&net->dev);
|
2011-08-21 05:09:37 +02:00
|
|
|
g_free(net);
|
2010-03-17 12:08:17 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2021-10-20 06:55:58 +02:00
|
|
|
static void vhost_net_set_vq_index(struct vhost_net *net, int vq_index,
|
2021-11-04 09:56:24 +01:00
|
|
|
int vq_index_end)
|
2014-08-19 06:56:29 +02:00
|
|
|
{
|
|
|
|
net->dev.vq_index = vq_index;
|
2021-11-04 09:56:24 +01:00
|
|
|
net->dev.vq_index_end = vq_index_end;
|
2014-08-19 06:56:29 +02:00
|
|
|
}
|
|
|
|
|
2013-01-30 12:12:35 +01:00
|
|
|
static int vhost_net_start_one(struct vhost_net *net,
|
2014-08-19 06:56:29 +02:00
|
|
|
VirtIODevice *dev)
|
2010-03-17 12:08:17 +01:00
|
|
|
{
|
|
|
|
struct vhost_vring_file file = { };
|
|
|
|
int r;
|
2011-08-11 09:21:18 +02:00
|
|
|
|
2022-08-23 20:30:30 +02:00
|
|
|
if (net->nc->info->start) {
|
|
|
|
r = net->nc->info->start(net->nc);
|
|
|
|
if (r < 0) {
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-11 09:21:18 +02:00
|
|
|
r = vhost_dev_enable_notifiers(&net->dev, dev);
|
|
|
|
if (r < 0) {
|
|
|
|
goto fail_notifiers;
|
|
|
|
}
|
2010-03-17 12:08:17 +01:00
|
|
|
|
2022-11-30 12:24:36 +01:00
|
|
|
r = vhost_dev_start(&net->dev, dev, false);
|
2010-03-17 12:08:17 +01:00
|
|
|
if (r < 0) {
|
2011-08-11 09:21:18 +02:00
|
|
|
goto fail_start;
|
2010-03-17 12:08:17 +01:00
|
|
|
}
|
|
|
|
|
2014-05-27 14:04:55 +02:00
|
|
|
if (net->nc->info->poll) {
|
|
|
|
net->nc->info->poll(net->nc, false);
|
|
|
|
}
|
|
|
|
|
qapi: Change Netdev into a flat union
This is a mostly-mechanical conversion that creates a new flat
union 'Netdev' QAPI type that covers all the branches of the
former 'NetClientOptions' simple union, where the branches are
now listed in a new 'NetClientDriver' enum rather than generated
from the simple union. The existence of a flat union has no
change to the command line syntax accepted for new code, and
will make it possible for a future patch to switch the QMP
command to parse a boxed union for no change to valid QMP; but
it does have some ripple effect on the C code when dealing with
the new types.
While making the conversion, note that the 'NetLegacy' type
remains unchanged: it applies only to legacy command line options,
and will not be ported to QMP, so it should remain a wrapper
around a simple union; to avoid confusion, the type named
'NetClientOptions' is now gone, and we introduce 'NetLegacyOptions'
in its place. Then, in the C code, we convert from NetLegacy to
Netdev as soon as possible, so that the bulk of the net stack
only has to deal with one QAPI type, not two. Note that since
the old legacy code always rejected 'hubport', we can just omit
that branch from the new 'NetLegacyOptions' simple union.
Based on an idea originally by Zoltán Kővágó <DirtY.iCE.hu@gmail.com>:
Message-Id: <01a527fbf1a5de880091f98cf011616a78adeeee.1441627176.git.DirtY.iCE.hu@gmail.com>
although the sed script in that patch no longer applies due to
other changes in the tree since then, and I also did some manual
cleanups (such as fixing whitespace to keep checkpatch happy).
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1468468228-27827-13-git-send-email-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[Fixup from Eric squashed in]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2016-07-14 05:50:23 +02:00
|
|
|
if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) {
|
2014-05-27 14:05:49 +02:00
|
|
|
qemu_set_fd_handler(net->backend, NULL, NULL, NULL);
|
|
|
|
file.fd = net->backend;
|
|
|
|
for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
|
2019-03-25 04:40:36 +01:00
|
|
|
if (!virtio_queue_enabled(dev, net->dev.vq_index +
|
|
|
|
file.index)) {
|
|
|
|
/* Queue might not be ready for start */
|
|
|
|
continue;
|
|
|
|
}
|
2016-07-26 23:15:25 +02:00
|
|
|
r = vhost_net_set_backend(&net->dev, &file);
|
2014-05-27 14:05:49 +02:00
|
|
|
if (r < 0) {
|
|
|
|
r = -errno;
|
|
|
|
goto fail;
|
|
|
|
}
|
2010-03-17 12:08:17 +01:00
|
|
|
}
|
|
|
|
}
|
2022-08-23 20:30:35 +02:00
|
|
|
|
|
|
|
if (net->nc->info->load) {
|
|
|
|
r = net->nc->info->load(net->nc);
|
|
|
|
if (r < 0) {
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
}
|
2010-03-17 12:08:17 +01:00
|
|
|
return 0;
|
|
|
|
fail:
|
|
|
|
file.fd = -1;
|
qapi: Change Netdev into a flat union
This is a mostly-mechanical conversion that creates a new flat
union 'Netdev' QAPI type that covers all the branches of the
former 'NetClientOptions' simple union, where the branches are
now listed in a new 'NetClientDriver' enum rather than generated
from the simple union. The existence of a flat union has no
change to the command line syntax accepted for new code, and
will make it possible for a future patch to switch the QMP
command to parse a boxed union for no change to valid QMP; but
it does have some ripple effect on the C code when dealing with
the new types.
While making the conversion, note that the 'NetLegacy' type
remains unchanged: it applies only to legacy command line options,
and will not be ported to QMP, so it should remain a wrapper
around a simple union; to avoid confusion, the type named
'NetClientOptions' is now gone, and we introduce 'NetLegacyOptions'
in its place. Then, in the C code, we convert from NetLegacy to
Netdev as soon as possible, so that the bulk of the net stack
only has to deal with one QAPI type, not two. Note that since
the old legacy code always rejected 'hubport', we can just omit
that branch from the new 'NetLegacyOptions' simple union.
Based on an idea originally by Zoltán Kővágó <DirtY.iCE.hu@gmail.com>:
Message-Id: <01a527fbf1a5de880091f98cf011616a78adeeee.1441627176.git.DirtY.iCE.hu@gmail.com>
although the sed script in that patch no longer applies due to
other changes in the tree since then, and I also did some manual
cleanups (such as fixing whitespace to keep checkpatch happy).
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1468468228-27827-13-git-send-email-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[Fixup from Eric squashed in]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2016-07-14 05:50:23 +02:00
|
|
|
if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) {
|
2014-05-27 14:05:49 +02:00
|
|
|
while (file.index-- > 0) {
|
2019-03-25 04:40:36 +01:00
|
|
|
if (!virtio_queue_enabled(dev, net->dev.vq_index +
|
|
|
|
file.index)) {
|
|
|
|
/* Queue might not be ready for start */
|
|
|
|
continue;
|
|
|
|
}
|
2023-10-04 10:49:39 +02:00
|
|
|
int ret = vhost_net_set_backend(&net->dev, &file);
|
|
|
|
assert(ret >= 0);
|
2014-05-27 14:05:49 +02:00
|
|
|
}
|
2010-03-17 12:08:17 +01:00
|
|
|
}
|
2014-05-27 14:04:55 +02:00
|
|
|
if (net->nc->info->poll) {
|
|
|
|
net->nc->info->poll(net->nc, true);
|
|
|
|
}
|
2022-11-30 12:24:36 +01:00
|
|
|
vhost_dev_stop(&net->dev, dev, false);
|
2011-08-11 09:21:18 +02:00
|
|
|
fail_start:
|
|
|
|
vhost_dev_disable_notifiers(&net->dev, dev);
|
|
|
|
fail_notifiers:
|
2010-03-17 12:08:17 +01:00
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2013-01-30 12:12:35 +01:00
|
|
|
static void vhost_net_stop_one(struct vhost_net *net,
|
|
|
|
VirtIODevice *dev)
|
2010-03-17 12:08:17 +01:00
|
|
|
{
|
|
|
|
struct vhost_vring_file file = { .fd = -1 };
|
|
|
|
|
qapi: Change Netdev into a flat union
This is a mostly-mechanical conversion that creates a new flat
union 'Netdev' QAPI type that covers all the branches of the
former 'NetClientOptions' simple union, where the branches are
now listed in a new 'NetClientDriver' enum rather than generated
from the simple union. The existence of a flat union has no
change to the command line syntax accepted for new code, and
will make it possible for a future patch to switch the QMP
command to parse a boxed union for no change to valid QMP; but
it does have some ripple effect on the C code when dealing with
the new types.
While making the conversion, note that the 'NetLegacy' type
remains unchanged: it applies only to legacy command line options,
and will not be ported to QMP, so it should remain a wrapper
around a simple union; to avoid confusion, the type named
'NetClientOptions' is now gone, and we introduce 'NetLegacyOptions'
in its place. Then, in the C code, we convert from NetLegacy to
Netdev as soon as possible, so that the bulk of the net stack
only has to deal with one QAPI type, not two. Note that since
the old legacy code always rejected 'hubport', we can just omit
that branch from the new 'NetLegacyOptions' simple union.
Based on an idea originally by Zoltán Kővágó <DirtY.iCE.hu@gmail.com>:
Message-Id: <01a527fbf1a5de880091f98cf011616a78adeeee.1441627176.git.DirtY.iCE.hu@gmail.com>
although the sed script in that patch no longer applies due to
other changes in the tree since then, and I also did some manual
cleanups (such as fixing whitespace to keep checkpatch happy).
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1468468228-27827-13-git-send-email-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[Fixup from Eric squashed in]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2016-07-14 05:50:23 +02:00
|
|
|
if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) {
|
2014-05-27 14:05:49 +02:00
|
|
|
for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
|
2016-07-26 23:15:25 +02:00
|
|
|
int r = vhost_net_set_backend(&net->dev, &file);
|
2014-05-27 14:05:49 +02:00
|
|
|
assert(r >= 0);
|
|
|
|
}
|
2010-03-17 12:08:17 +01:00
|
|
|
}
|
2014-05-27 14:04:55 +02:00
|
|
|
if (net->nc->info->poll) {
|
|
|
|
net->nc->info->poll(net->nc, true);
|
|
|
|
}
|
2022-11-30 12:24:36 +01:00
|
|
|
vhost_dev_stop(&net->dev, dev, false);
|
2022-08-23 20:30:31 +02:00
|
|
|
if (net->nc->info->stop) {
|
|
|
|
net->nc->info->stop(net->nc);
|
|
|
|
}
|
2011-08-11 09:21:18 +02:00
|
|
|
vhost_dev_disable_notifiers(&net->dev, dev);
|
2010-03-17 12:08:17 +01:00
|
|
|
}
|
|
|
|
|
2013-01-30 12:12:35 +01:00
|
|
|
int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
|
2021-10-20 06:55:56 +02:00
|
|
|
int data_queue_pairs, int cvq)
|
2013-01-30 12:12:35 +01:00
|
|
|
{
|
2013-04-24 10:21:21 +02:00
|
|
|
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(dev)));
|
|
|
|
VirtioBusState *vbus = VIRTIO_BUS(qbus);
|
|
|
|
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
|
2021-10-20 06:55:56 +02:00
|
|
|
int total_notifiers = data_queue_pairs * 2 + cvq;
|
|
|
|
VirtIONet *n = VIRTIO_NET(dev);
|
|
|
|
int nvhosts = data_queue_pairs + cvq;
|
2020-07-01 16:55:26 +02:00
|
|
|
struct vhost_net *net;
|
vhost: Fix last vq queue index of devices with no cvq
The -1 assumes that cvq device model is accounted in data_queue_pairs,
if cvq does not exists, but it's actually the opposite: Devices with
!cvq are ok but devices with cvq does not add the last queue to
data_queue_pairs.
This is not a problem to vhost-net, but it is to vhost-vdpa:
* Devices with cvq gets initialized at last data vq device model, not
at cvq one.
* Devices with !cvq never gets initialized, since last_index is the
first queue of the last device model.
Because of that, the right change in last_index is to actually add the
cvq, not to remove the missing one.
This is not a problem to vhost-net, but it is to vhost-vdpa, which
device model trust to reach the last index to finish starting the
device.
Also, as the previous commit, rename it to index_end.
Tested with vp_vdpa with host's vhost=on and vhost=off, with ctrl_vq=on
and ctrl_vq=off.
Fixes: 049eb15b5fc9 ("vhost: record the last virtqueue index for the virtio device")
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Message-Id: <20211104085625.2054959-3-eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2021-11-04 09:56:25 +01:00
|
|
|
int r, e, i, index_end = data_queue_pairs * 2;
|
2020-07-01 16:55:26 +02:00
|
|
|
NetClientState *peer;
|
2013-01-30 12:12:35 +01:00
|
|
|
|
vhost: Fix last vq queue index of devices with no cvq
The -1 assumes that cvq device model is accounted in data_queue_pairs,
if cvq does not exists, but it's actually the opposite: Devices with
!cvq are ok but devices with cvq does not add the last queue to
data_queue_pairs.
This is not a problem to vhost-net, but it is to vhost-vdpa:
* Devices with cvq gets initialized at last data vq device model, not
at cvq one.
* Devices with !cvq never gets initialized, since last_index is the
first queue of the last device model.
Because of that, the right change in last_index is to actually add the
cvq, not to remove the missing one.
This is not a problem to vhost-net, but it is to vhost-vdpa, which
device model trust to reach the last index to finish starting the
device.
Also, as the previous commit, rename it to index_end.
Tested with vp_vdpa with host's vhost=on and vhost=off, with ctrl_vq=on
and ctrl_vq=off.
Fixes: 049eb15b5fc9 ("vhost: record the last virtqueue index for the virtio device")
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Message-Id: <20211104085625.2054959-3-eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2021-11-04 09:56:25 +01:00
|
|
|
if (cvq) {
|
|
|
|
index_end += 1;
|
2021-10-20 06:55:58 +02:00
|
|
|
}
|
|
|
|
|
2013-04-24 10:21:21 +02:00
|
|
|
if (!k->set_guest_notifiers) {
|
error: Strip trailing '\n' from error string arguments (again)
Commit 6daf194d and be62a2eb got rid of a bunch, but they keep coming
back. Tracked down with this Coccinelle semantic patch:
@r@
expression err, eno, cls, fmt;
position p;
@@
(
error_report(fmt, ...)@p
|
error_set(err, cls, fmt, ...)@p
|
error_set_errno(err, eno, cls, fmt, ...)@p
|
error_setg(err, fmt, ...)@p
|
error_setg_errno(err, eno, fmt, ...)@p
)
@script:python@
fmt << r.fmt;
p << r.p;
@@
if "\\n" in str(fmt):
print "%s:%s:%s:%s" % (p[0].file, p[0].line, p[0].column, fmt)
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-id: 1360354939-10994-4-git-send-email-armbru@redhat.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-02-08 21:22:16 +01:00
|
|
|
error_report("binding does not support guest notifiers");
|
2016-01-13 20:26:25 +01:00
|
|
|
return -ENOSYS;
|
2013-01-30 12:12:35 +01:00
|
|
|
}
|
|
|
|
|
2021-10-20 06:55:56 +02:00
|
|
|
for (i = 0; i < nvhosts; i++) {
|
|
|
|
|
|
|
|
if (i < data_queue_pairs) {
|
|
|
|
peer = qemu_get_peer(ncs, i);
|
|
|
|
} else { /* Control Virtqueue */
|
2021-10-20 06:55:57 +02:00
|
|
|
peer = qemu_get_peer(ncs, n->max_queue_pairs);
|
2021-10-20 06:55:56 +02:00
|
|
|
}
|
2016-02-18 15:12:23 +01:00
|
|
|
|
2020-07-01 16:55:26 +02:00
|
|
|
net = get_vhost_net(peer);
|
vhost: Fix last vq queue index of devices with no cvq
The -1 assumes that cvq device model is accounted in data_queue_pairs,
if cvq does not exists, but it's actually the opposite: Devices with
!cvq are ok but devices with cvq does not add the last queue to
data_queue_pairs.
This is not a problem to vhost-net, but it is to vhost-vdpa:
* Devices with cvq gets initialized at last data vq device model, not
at cvq one.
* Devices with !cvq never gets initialized, since last_index is the
first queue of the last device model.
Because of that, the right change in last_index is to actually add the
cvq, not to remove the missing one.
This is not a problem to vhost-net, but it is to vhost-vdpa, which
device model trust to reach the last index to finish starting the
device.
Also, as the previous commit, rename it to index_end.
Tested with vp_vdpa with host's vhost=on and vhost=off, with ctrl_vq=on
and ctrl_vq=off.
Fixes: 049eb15b5fc9 ("vhost: record the last virtqueue index for the virtio device")
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Message-Id: <20211104085625.2054959-3-eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2021-11-04 09:56:25 +01:00
|
|
|
vhost_net_set_vq_index(net, i * 2, index_end);
|
2016-02-18 15:12:23 +01:00
|
|
|
|
|
|
|
/* Suppress the masking guest notifiers on vhost user
|
|
|
|
* because vhost user doesn't interrupt masking/unmasking
|
|
|
|
* properly.
|
|
|
|
*/
|
qapi: Change Netdev into a flat union
This is a mostly-mechanical conversion that creates a new flat
union 'Netdev' QAPI type that covers all the branches of the
former 'NetClientOptions' simple union, where the branches are
now listed in a new 'NetClientDriver' enum rather than generated
from the simple union. The existence of a flat union has no
change to the command line syntax accepted for new code, and
will make it possible for a future patch to switch the QMP
command to parse a boxed union for no change to valid QMP; but
it does have some ripple effect on the C code when dealing with
the new types.
While making the conversion, note that the 'NetLegacy' type
remains unchanged: it applies only to legacy command line options,
and will not be ported to QMP, so it should remain a wrapper
around a simple union; to avoid confusion, the type named
'NetClientOptions' is now gone, and we introduce 'NetLegacyOptions'
in its place. Then, in the C code, we convert from NetLegacy to
Netdev as soon as possible, so that the bulk of the net stack
only has to deal with one QAPI type, not two. Note that since
the old legacy code always rejected 'hubport', we can just omit
that branch from the new 'NetLegacyOptions' simple union.
Based on an idea originally by Zoltán Kővágó <DirtY.iCE.hu@gmail.com>:
Message-Id: <01a527fbf1a5de880091f98cf011616a78adeeee.1441627176.git.DirtY.iCE.hu@gmail.com>
although the sed script in that patch no longer applies due to
other changes in the tree since then, and I also did some manual
cleanups (such as fixing whitespace to keep checkpatch happy).
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1468468228-27827-13-git-send-email-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[Fixup from Eric squashed in]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2016-07-14 05:50:23 +02:00
|
|
|
if (net->nc->info->type == NET_CLIENT_DRIVER_VHOST_USER) {
|
2016-07-26 23:14:55 +02:00
|
|
|
dev->use_guest_notifier_mask = false;
|
2016-02-18 15:12:23 +01:00
|
|
|
}
|
|
|
|
}
|
2013-01-30 12:12:35 +01:00
|
|
|
|
2021-10-20 06:55:56 +02:00
|
|
|
r = k->set_guest_notifiers(qbus->parent, total_notifiers, true);
|
2013-01-30 12:12:35 +01:00
|
|
|
if (r < 0) {
|
error: Strip trailing '\n' from error string arguments (again)
Commit 6daf194d and be62a2eb got rid of a bunch, but they keep coming
back. Tracked down with this Coccinelle semantic patch:
@r@
expression err, eno, cls, fmt;
position p;
@@
(
error_report(fmt, ...)@p
|
error_set(err, cls, fmt, ...)@p
|
error_set_errno(err, eno, cls, fmt, ...)@p
|
error_setg(err, fmt, ...)@p
|
error_setg_errno(err, eno, fmt, ...)@p
)
@script:python@
fmt << r.fmt;
p << r.p;
@@
if "\\n" in str(fmt):
print "%s:%s:%s:%s" % (p[0].file, p[0].line, p[0].column, fmt)
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-id: 1360354939-10994-4-git-send-email-armbru@redhat.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-02-08 21:22:16 +01:00
|
|
|
error_report("Error binding guest notifier: %d", -r);
|
2016-02-05 11:45:26 +01:00
|
|
|
goto err;
|
2013-01-30 12:12:35 +01:00
|
|
|
}
|
|
|
|
|
2021-10-20 06:55:56 +02:00
|
|
|
for (i = 0; i < nvhosts; i++) {
|
|
|
|
if (i < data_queue_pairs) {
|
|
|
|
peer = qemu_get_peer(ncs, i);
|
|
|
|
} else {
|
2021-10-20 06:55:57 +02:00
|
|
|
peer = qemu_get_peer(ncs, n->max_queue_pairs);
|
2021-10-20 06:55:56 +02:00
|
|
|
}
|
2016-06-06 18:45:06 +02:00
|
|
|
|
2020-07-01 16:55:26 +02:00
|
|
|
if (peer->vring_enable) {
|
2016-06-06 18:45:06 +02:00
|
|
|
/* restore vring enable state */
|
2020-07-01 16:55:26 +02:00
|
|
|
r = vhost_set_vring_enable(peer, peer->vring_enable);
|
2016-06-06 18:45:06 +02:00
|
|
|
|
|
|
|
if (r < 0) {
|
|
|
|
goto err_start;
|
|
|
|
}
|
|
|
|
}
|
2022-10-17 08:44:51 +02:00
|
|
|
|
|
|
|
r = vhost_net_start_one(get_vhost_net(peer), dev);
|
|
|
|
if (r < 0) {
|
|
|
|
goto err_start;
|
|
|
|
}
|
2014-08-19 06:56:29 +02:00
|
|
|
}
|
|
|
|
|
2013-01-30 12:12:35 +01:00
|
|
|
return 0;
|
|
|
|
|
2014-08-19 06:56:29 +02:00
|
|
|
err_start:
|
2013-01-30 12:12:35 +01:00
|
|
|
while (--i >= 0) {
|
2022-05-07 04:28:15 +02:00
|
|
|
peer = qemu_get_peer(ncs, i < data_queue_pairs ?
|
|
|
|
i : n->max_queue_pairs);
|
2020-07-01 16:55:26 +02:00
|
|
|
vhost_net_stop_one(get_vhost_net(peer), dev);
|
2013-01-30 12:12:35 +01:00
|
|
|
}
|
2021-10-20 06:55:56 +02:00
|
|
|
e = k->set_guest_notifiers(qbus->parent, total_notifiers, false);
|
2014-08-19 06:56:29 +02:00
|
|
|
if (e < 0) {
|
|
|
|
fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", e);
|
|
|
|
fflush(stderr);
|
|
|
|
}
|
2016-02-05 11:45:26 +01:00
|
|
|
err:
|
2013-01-30 12:12:35 +01:00
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs,
|
2021-10-20 06:55:56 +02:00
|
|
|
int data_queue_pairs, int cvq)
|
2013-01-30 12:12:35 +01:00
|
|
|
{
|
2013-04-24 10:21:21 +02:00
|
|
|
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(dev)));
|
|
|
|
VirtioBusState *vbus = VIRTIO_BUS(qbus);
|
|
|
|
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
|
2021-10-20 06:55:56 +02:00
|
|
|
VirtIONet *n = VIRTIO_NET(dev);
|
|
|
|
NetClientState *peer;
|
|
|
|
int total_notifiers = data_queue_pairs * 2 + cvq;
|
|
|
|
int nvhosts = data_queue_pairs + cvq;
|
2013-01-30 12:12:35 +01:00
|
|
|
int i, r;
|
|
|
|
|
2021-10-20 06:55:56 +02:00
|
|
|
for (i = 0; i < nvhosts; i++) {
|
|
|
|
if (i < data_queue_pairs) {
|
|
|
|
peer = qemu_get_peer(ncs, i);
|
|
|
|
} else {
|
2021-10-20 06:55:57 +02:00
|
|
|
peer = qemu_get_peer(ncs, n->max_queue_pairs);
|
2021-10-20 06:55:56 +02:00
|
|
|
}
|
|
|
|
vhost_net_stop_one(get_vhost_net(peer), dev);
|
2014-08-19 06:56:29 +02:00
|
|
|
}
|
|
|
|
|
2021-10-20 06:55:56 +02:00
|
|
|
r = k->set_guest_notifiers(qbus->parent, total_notifiers, false);
|
2013-01-30 12:12:35 +01:00
|
|
|
if (r < 0) {
|
|
|
|
fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", r);
|
|
|
|
fflush(stderr);
|
|
|
|
}
|
|
|
|
assert(r >= 0);
|
|
|
|
}
|
|
|
|
|
2010-03-17 12:08:17 +01:00
|
|
|
void vhost_net_cleanup(struct vhost_net *net)
|
|
|
|
{
|
|
|
|
vhost_dev_cleanup(&net->dev);
|
|
|
|
}
|
2012-12-24 16:37:01 +01:00
|
|
|
|
2015-10-09 17:17:32 +02:00
|
|
|
int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr)
|
|
|
|
{
|
|
|
|
const VhostOps *vhost_ops = net->dev.vhost_ops;
|
|
|
|
|
2016-07-26 23:15:15 +02:00
|
|
|
assert(vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
|
|
|
|
assert(vhost_ops->vhost_migration_done);
|
2015-10-09 17:17:32 +02:00
|
|
|
|
2016-07-26 23:15:15 +02:00
|
|
|
return vhost_ops->vhost_migration_done(&net->dev, mac_addr);
|
2015-10-09 17:17:32 +02:00
|
|
|
}
|
|
|
|
|
2012-12-24 16:37:01 +01:00
|
|
|
bool vhost_net_virtqueue_pending(VHostNetState *net, int idx)
|
|
|
|
{
|
|
|
|
return vhost_virtqueue_pending(&net->dev, idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
|
|
|
|
int idx, bool mask)
|
|
|
|
{
|
|
|
|
vhost_virtqueue_mask(&net->dev, dev, idx, mask);
|
|
|
|
}
|
2014-05-27 14:05:08 +02:00
|
|
|
|
2022-12-22 08:04:49 +01:00
|
|
|
bool vhost_net_config_pending(VHostNetState *net)
|
|
|
|
{
|
|
|
|
return vhost_config_pending(&net->dev);
|
|
|
|
}
|
|
|
|
|
|
|
|
void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool mask)
|
|
|
|
{
|
|
|
|
vhost_config_mask(&net->dev, dev, mask);
|
|
|
|
}
|
2014-05-27 14:05:08 +02:00
|
|
|
VHostNetState *get_vhost_net(NetClientState *nc)
|
|
|
|
{
|
|
|
|
VHostNetState *vhost_net = 0;
|
|
|
|
|
|
|
|
if (!nc) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (nc->info->type) {
|
qapi: Change Netdev into a flat union
This is a mostly-mechanical conversion that creates a new flat
union 'Netdev' QAPI type that covers all the branches of the
former 'NetClientOptions' simple union, where the branches are
now listed in a new 'NetClientDriver' enum rather than generated
from the simple union. The existence of a flat union has no
change to the command line syntax accepted for new code, and
will make it possible for a future patch to switch the QMP
command to parse a boxed union for no change to valid QMP; but
it does have some ripple effect on the C code when dealing with
the new types.
While making the conversion, note that the 'NetLegacy' type
remains unchanged: it applies only to legacy command line options,
and will not be ported to QMP, so it should remain a wrapper
around a simple union; to avoid confusion, the type named
'NetClientOptions' is now gone, and we introduce 'NetLegacyOptions'
in its place. Then, in the C code, we convert from NetLegacy to
Netdev as soon as possible, so that the bulk of the net stack
only has to deal with one QAPI type, not two. Note that since
the old legacy code always rejected 'hubport', we can just omit
that branch from the new 'NetLegacyOptions' simple union.
Based on an idea originally by Zoltán Kővágó <DirtY.iCE.hu@gmail.com>:
Message-Id: <01a527fbf1a5de880091f98cf011616a78adeeee.1441627176.git.DirtY.iCE.hu@gmail.com>
although the sed script in that patch no longer applies due to
other changes in the tree since then, and I also did some manual
cleanups (such as fixing whitespace to keep checkpatch happy).
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1468468228-27827-13-git-send-email-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[Fixup from Eric squashed in]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2016-07-14 05:50:23 +02:00
|
|
|
case NET_CLIENT_DRIVER_TAP:
|
2014-05-27 14:05:08 +02:00
|
|
|
vhost_net = tap_get_vhost_net(nc);
|
2023-06-28 13:28:04 +02:00
|
|
|
/*
|
|
|
|
* tap_get_vhost_net() can return NULL if a tap net-device backend is
|
|
|
|
* created with 'vhost=off' option, 'vhostforce=off' or no vhost or
|
|
|
|
* vhostforce or vhostfd options at all. Please see net_init_tap_one().
|
|
|
|
* Hence, we omit the assertion here.
|
|
|
|
*/
|
2014-05-27 14:05:08 +02:00
|
|
|
break;
|
2019-02-14 18:35:49 +01:00
|
|
|
#ifdef CONFIG_VHOST_NET_USER
|
qapi: Change Netdev into a flat union
This is a mostly-mechanical conversion that creates a new flat
union 'Netdev' QAPI type that covers all the branches of the
former 'NetClientOptions' simple union, where the branches are
now listed in a new 'NetClientDriver' enum rather than generated
from the simple union. The existence of a flat union has no
change to the command line syntax accepted for new code, and
will make it possible for a future patch to switch the QMP
command to parse a boxed union for no change to valid QMP; but
it does have some ripple effect on the C code when dealing with
the new types.
While making the conversion, note that the 'NetLegacy' type
remains unchanged: it applies only to legacy command line options,
and will not be ported to QMP, so it should remain a wrapper
around a simple union; to avoid confusion, the type named
'NetClientOptions' is now gone, and we introduce 'NetLegacyOptions'
in its place. Then, in the C code, we convert from NetLegacy to
Netdev as soon as possible, so that the bulk of the net stack
only has to deal with one QAPI type, not two. Note that since
the old legacy code always rejected 'hubport', we can just omit
that branch from the new 'NetLegacyOptions' simple union.
Based on an idea originally by Zoltán Kővágó <DirtY.iCE.hu@gmail.com>:
Message-Id: <01a527fbf1a5de880091f98cf011616a78adeeee.1441627176.git.DirtY.iCE.hu@gmail.com>
although the sed script in that patch no longer applies due to
other changes in the tree since then, and I also did some manual
cleanups (such as fixing whitespace to keep checkpatch happy).
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1468468228-27827-13-git-send-email-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[Fixup from Eric squashed in]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2016-07-14 05:50:23 +02:00
|
|
|
case NET_CLIENT_DRIVER_VHOST_USER:
|
2014-06-10 12:02:16 +02:00
|
|
|
vhost_net = vhost_user_get_vhost_net(nc);
|
2016-07-26 23:15:13 +02:00
|
|
|
assert(vhost_net);
|
2014-06-10 12:02:16 +02:00
|
|
|
break;
|
2020-07-01 16:55:37 +02:00
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_VHOST_NET_VDPA
|
|
|
|
case NET_CLIENT_DRIVER_VHOST_VDPA:
|
|
|
|
vhost_net = vhost_vdpa_get_vhost_net(nc);
|
|
|
|
assert(vhost_net);
|
|
|
|
break;
|
2019-02-14 18:35:49 +01:00
|
|
|
#endif
|
2014-05-27 14:05:08 +02:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return vhost_net;
|
|
|
|
}
|
2015-09-23 06:20:01 +02:00
|
|
|
|
|
|
|
int vhost_set_vring_enable(NetClientState *nc, int enable)
|
|
|
|
{
|
|
|
|
VHostNetState *net = get_vhost_net(nc);
|
2016-07-26 23:15:14 +02:00
|
|
|
const VhostOps *vhost_ops = net->dev.vhost_ops;
|
2016-06-06 18:45:04 +02:00
|
|
|
|
2016-06-06 18:45:06 +02:00
|
|
|
nc->vring_enable = enable;
|
|
|
|
|
2016-08-03 07:22:49 +02:00
|
|
|
if (vhost_ops && vhost_ops->vhost_set_vring_enable) {
|
2015-10-09 17:17:28 +02:00
|
|
|
return vhost_ops->vhost_set_vring_enable(&net->dev, enable);
|
2015-09-23 06:20:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-12-10 16:30:37 +01:00
|
|
|
int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu)
|
|
|
|
{
|
|
|
|
const VhostOps *vhost_ops = net->dev.vhost_ops;
|
|
|
|
|
|
|
|
if (!vhost_ops->vhost_net_set_mtu) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return vhost_ops->vhost_net_set_mtu(&net->dev, mtu);
|
|
|
|
}
|
2022-10-17 11:25:52 +02:00
|
|
|
|
|
|
|
void vhost_net_virtqueue_reset(VirtIODevice *vdev, NetClientState *nc,
|
|
|
|
int vq_index)
|
|
|
|
{
|
|
|
|
VHostNetState *net = get_vhost_net(nc->peer);
|
|
|
|
const VhostOps *vhost_ops = net->dev.vhost_ops;
|
|
|
|
struct vhost_vring_file file = { .fd = -1 };
|
|
|
|
int idx;
|
|
|
|
|
|
|
|
/* should only be called after backend is connected */
|
|
|
|
assert(vhost_ops);
|
|
|
|
|
|
|
|
idx = vhost_ops->vhost_get_vq_index(&net->dev, vq_index);
|
|
|
|
|
|
|
|
if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) {
|
|
|
|
file.index = idx;
|
|
|
|
int r = vhost_net_set_backend(&net->dev, &file);
|
|
|
|
assert(r >= 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
vhost_virtqueue_stop(&net->dev,
|
|
|
|
vdev,
|
|
|
|
net->dev.vqs + idx,
|
|
|
|
net->dev.vq_index + idx);
|
|
|
|
}
|
2022-10-17 11:25:53 +02:00
|
|
|
|
|
|
|
int vhost_net_virtqueue_restart(VirtIODevice *vdev, NetClientState *nc,
|
|
|
|
int vq_index)
|
|
|
|
{
|
|
|
|
VHostNetState *net = get_vhost_net(nc->peer);
|
|
|
|
const VhostOps *vhost_ops = net->dev.vhost_ops;
|
|
|
|
struct vhost_vring_file file = { };
|
|
|
|
int idx, r;
|
|
|
|
|
|
|
|
if (!net->dev.started) {
|
|
|
|
return -EBUSY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* should only be called after backend is connected */
|
|
|
|
assert(vhost_ops);
|
|
|
|
|
|
|
|
idx = vhost_ops->vhost_get_vq_index(&net->dev, vq_index);
|
|
|
|
|
|
|
|
r = vhost_virtqueue_start(&net->dev,
|
|
|
|
vdev,
|
|
|
|
net->dev.vqs + idx,
|
|
|
|
net->dev.vq_index + idx);
|
|
|
|
if (r < 0) {
|
|
|
|
goto err_start;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) {
|
|
|
|
file.index = idx;
|
|
|
|
file.fd = net->backend;
|
|
|
|
r = vhost_net_set_backend(&net->dev, &file);
|
|
|
|
if (r < 0) {
|
|
|
|
r = -errno;
|
|
|
|
goto err_start;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
err_start:
|
|
|
|
error_report("Error when restarting the queue.");
|
|
|
|
|
|
|
|
if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) {
|
|
|
|
file.fd = VHOST_FILE_UNBIND;
|
|
|
|
file.index = idx;
|
2023-10-04 10:49:39 +02:00
|
|
|
int ret = vhost_net_set_backend(&net->dev, &file);
|
|
|
|
assert(ret >= 0);
|
2022-10-17 11:25:53 +02:00
|
|
|
}
|
|
|
|
|
2022-11-30 12:24:36 +01:00
|
|
|
vhost_dev_stop(&net->dev, vdev, false);
|
2022-10-17 11:25:53 +02:00
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|