diff options
author | Laurent Vivier <lvivier@redhat.com> | 2025-07-09 10:24:19 +0200 |
---|---|---|
committer | Jason Wang <jasowang@redhat.com> | 2025-07-14 13:27:09 +0800 |
commit | effdacbf28d76ca0eec9086539649e547e510bbc (patch) | |
tree | 6a631996bcf35b5d59237e904d7829a15a05198a | |
parent | 8f6e5c620a5b21c070eed93721236cad48b6f9d7 (diff) | |
download | qemu-effdacbf28d76ca0eec9086539649e547e510bbc.zip qemu-effdacbf28d76ca0eec9086539649e547e510bbc.tar.gz qemu-effdacbf28d76ca0eec9086539649e547e510bbc.tar.bz2 |
net: Consolidate vhost feature bits into vhost_net structure
Previously, the vhost_net_get_feature_bits() function in
hw/net/vhost_net.c used a large switch statement to determine
the appropriate feature bits based on the NetClientDriver type.
This created unnecessary coupling between the generic vhost layer
and specific network backends (like TAP, vhost-user, and
vhost-vdpa).
This patch moves the definition of vhost feature bits directly into the
vhost_net structure for each relevant network client.
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
-rw-r--r-- | hw/net/vhost_net.c | 90 | ||||
-rw-r--r-- | include/hw/virtio/vhost.h | 1 | ||||
-rw-r--r-- | include/net/vhost-vdpa.h | 2 | ||||
-rw-r--r-- | include/net/vhost_net.h | 1 | ||||
-rw-r--r-- | net/tap.c | 19 | ||||
-rw-r--r-- | net/vhost-user.c | 43 | ||||
-rw-r--r-- | net/vhost-vdpa.c | 3 |
7 files changed, 69 insertions, 90 deletions
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index db8b97b..787c769 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -36,94 +36,9 @@ #include "hw/virtio/virtio-bus.h" #include "linux-headers/linux/vhost.h" - -/* 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, - VIRTIO_F_VERSION_1, - VIRTIO_NET_F_MTU, - VIRTIO_F_IOMMU_PLATFORM, - VIRTIO_F_RING_PACKED, - VIRTIO_F_RING_RESET, - VIRTIO_F_IN_ORDER, - VIRTIO_F_NOTIFICATION_DATA, - VIRTIO_NET_F_RSC_EXT, - VIRTIO_NET_F_HASH_REPORT, - VHOST_INVALID_FEATURE_BIT -}; - -/* Features supported by others. */ -static const int user_feature_bits[] = { - VIRTIO_F_NOTIFY_ON_EMPTY, - VIRTIO_F_NOTIFICATION_DATA, - VIRTIO_RING_F_INDIRECT_DESC, - VIRTIO_RING_F_EVENT_IDX, - - VIRTIO_F_ANY_LAYOUT, - VIRTIO_F_VERSION_1, - 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, - VIRTIO_NET_F_MTU, - VIRTIO_F_IOMMU_PLATFORM, - VIRTIO_F_RING_PACKED, - VIRTIO_F_RING_RESET, - VIRTIO_F_IN_ORDER, - VIRTIO_NET_F_RSS, - VIRTIO_NET_F_RSC_EXT, - VIRTIO_NET_F_HASH_REPORT, - VIRTIO_NET_F_GUEST_USO4, - VIRTIO_NET_F_GUEST_USO6, - VIRTIO_NET_F_HOST_USO, - - /* This bit implies RARP isn't sent by QEMU out of band */ - VIRTIO_NET_F_GUEST_ANNOUNCE, - - VIRTIO_NET_F_MQ, - - VHOST_INVALID_FEATURE_BIT -}; - -static const int *vhost_net_get_feature_bits(struct vhost_net *net) -{ - const int *feature_bits = 0; - - switch (net->nc->info->type) { - case NET_CLIENT_DRIVER_TAP: - feature_bits = kernel_feature_bits; - break; - case NET_CLIENT_DRIVER_VHOST_USER: - feature_bits = user_feature_bits; - break; -#ifdef CONFIG_VHOST_NET_VDPA - case NET_CLIENT_DRIVER_VHOST_VDPA: - feature_bits = vdpa_feature_bits; - break; -#endif - default: - error_report("Feature bits not defined for this type: %d", - net->nc->info->type); - break; - } - - return feature_bits; -} - uint64_t vhost_net_get_features(struct vhost_net *net, uint64_t features) { - return vhost_get_features(&net->dev, vhost_net_get_feature_bits(net), + return vhost_get_features(&net->dev, net->feature_bits, features); } int vhost_net_get_config(struct vhost_net *net, uint8_t *config, @@ -140,7 +55,7 @@ int vhost_net_set_config(struct vhost_net *net, const uint8_t *data, void vhost_net_ack_features(struct vhost_net *net, uint64_t features) { net->dev.acked_features = net->dev.backend_features; - vhost_ack_features(&net->dev, vhost_net_get_feature_bits(net), features); + vhost_ack_features(&net->dev, net->feature_bits, features); } uint64_t vhost_net_get_max_queues(VHostNetState *net) @@ -329,6 +244,7 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options) } net->nc = options->net_backend; net->dev.nvqs = options->nvqs; + net->feature_bits = options->feature_bits; net->dev.max_queues = 1; net->dev.vqs = net->vqs; diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h index 38800a7..6a75fdc 100644 --- a/include/hw/virtio/vhost.h +++ b/include/hw/virtio/vhost.h @@ -143,6 +143,7 @@ struct vhost_net { struct vhost_dev dev; struct vhost_virtqueue vqs[2]; int backend; + const int *feature_bits; NetClientState *nc; }; diff --git a/include/net/vhost-vdpa.h b/include/net/vhost-vdpa.h index 916ead3..f8d7d6c 100644 --- a/include/net/vhost-vdpa.h +++ b/include/net/vhost-vdpa.h @@ -14,6 +14,4 @@ #define TYPE_VHOST_VDPA "vhost-vdpa" -extern const int vdpa_feature_bits[]; - #endif /* VHOST_VDPA_H */ diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h index 0f40049..fbed373 100644 --- a/include/net/vhost_net.h +++ b/include/net/vhost_net.h @@ -12,6 +12,7 @@ typedef struct VhostNetOptions { NetClientState *net_backend; uint32_t busyloop_timeout; unsigned int nvqs; + const int *feature_bits; void *opaque; } VhostNetOptions; @@ -42,11 +42,29 @@ #include "qemu/error-report.h" #include "qemu/main-loop.h" #include "qemu/sockets.h" +#include "hw/virtio/vhost.h" #include "net/tap.h" #include "net/vhost_net.h" +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, + VIRTIO_F_VERSION_1, + VIRTIO_NET_F_MTU, + VIRTIO_F_IOMMU_PLATFORM, + VIRTIO_F_RING_PACKED, + VIRTIO_F_RING_RESET, + VIRTIO_F_IN_ORDER, + VIRTIO_F_NOTIFICATION_DATA, + VIRTIO_NET_F_RSC_EXT, + VIRTIO_NET_F_HASH_REPORT, + VHOST_INVALID_FEATURE_BIT +}; + typedef struct TAPState { NetClientState nc; int fd; @@ -725,6 +743,7 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, } options.opaque = (void *)(uintptr_t)vhostfd; options.nvqs = 2; + options.feature_bits = kernel_feature_bits; s->vhost_net = vhost_net_init(&options); if (!s->vhost_net) { diff --git a/net/vhost-user.c b/net/vhost-user.c index b7bf0d2..bc8e82a 100644 --- a/net/vhost-user.c +++ b/net/vhost-user.c @@ -12,7 +12,9 @@ #include "clients.h" #include "net/vhost_net.h" #include "net/vhost-user.h" +#include "hw/virtio/vhost.h" #include "hw/virtio/vhost-user.h" +#include "standard-headers/linux/virtio_net.h" #include "chardev/char-fe.h" #include "qapi/error.h" #include "qapi/qapi-commands-net.h" @@ -22,6 +24,46 @@ #include "qemu/option.h" #include "trace.h" +static const int user_feature_bits[] = { + VIRTIO_F_NOTIFY_ON_EMPTY, + VIRTIO_F_NOTIFICATION_DATA, + VIRTIO_RING_F_INDIRECT_DESC, + VIRTIO_RING_F_EVENT_IDX, + + VIRTIO_F_ANY_LAYOUT, + VIRTIO_F_VERSION_1, + 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, + VIRTIO_NET_F_MTU, + VIRTIO_F_IOMMU_PLATFORM, + VIRTIO_F_RING_PACKED, + VIRTIO_F_RING_RESET, + VIRTIO_F_IN_ORDER, + VIRTIO_NET_F_RSS, + VIRTIO_NET_F_RSC_EXT, + VIRTIO_NET_F_HASH_REPORT, + VIRTIO_NET_F_GUEST_USO4, + VIRTIO_NET_F_GUEST_USO6, + VIRTIO_NET_F_HOST_USO, + + /* This bit implies RARP isn't sent by QEMU out of band */ + VIRTIO_NET_F_GUEST_ANNOUNCE, + + VIRTIO_NET_F_MQ, + + VHOST_INVALID_FEATURE_BIT +}; + typedef struct NetVhostUserState { NetClientState nc; CharBackend chr; /* only queue index 0 */ @@ -96,6 +138,7 @@ static int vhost_user_start(int queues, NetClientState *ncs[], options.opaque = be; options.busyloop_timeout = 0; options.nvqs = 2; + options.feature_bits = user_feature_bits; net = vhost_net_init(&options); if (!net) { error_report("failed to init vhost_net for queue %d", i); diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c index 0b86c91..cbbea0e 100644 --- a/net/vhost-vdpa.c +++ b/net/vhost-vdpa.c @@ -55,7 +55,7 @@ typedef struct VhostVDPAState { * with the exception of VHOST_INVALID_FEATURE_BIT, * which should always be the last entry. */ -const int vdpa_feature_bits[] = { +static const int vdpa_feature_bits[] = { VIRTIO_F_ANY_LAYOUT, VIRTIO_F_IOMMU_PLATFORM, VIRTIO_F_NOTIFY_ON_EMPTY, @@ -201,6 +201,7 @@ static int vhost_vdpa_add(NetClientState *ncs, void *be, options.opaque = be; options.busyloop_timeout = 0; options.nvqs = nvqs; + options.feature_bits = vdpa_feature_bits; net = vhost_net_init(&options); if (!net) { |