Message ID | 20220408122813.1357045-4-maxime.coquelin@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Vhost-user: add Virtio RSS support | expand |
在 2022/4/8 20:28, Maxime Coquelin 写道: > This patch introduces new Vhost backend callbacks to > support RSS, and makes them called in Virtio-net > device. > > It will be used by Vhost-user backend implementation to > support RSS feature. > > Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com> > --- > hw/net/vhost_net-stub.c | 10 ++++++ > hw/net/vhost_net.c | 22 +++++++++++++ > hw/net/virtio-net.c | 53 +++++++++++++++++++++---------- > include/hw/virtio/vhost-backend.h | 7 ++++ > include/net/vhost_net.h | 4 +++ > 5 files changed, 79 insertions(+), 17 deletions(-) > > diff --git a/hw/net/vhost_net-stub.c b/hw/net/vhost_net-stub.c > index 89d71cfb8e..cc05e07c1f 100644 > --- a/hw/net/vhost_net-stub.c > +++ b/hw/net/vhost_net-stub.c > @@ -101,3 +101,13 @@ int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu) > { > return 0; > } > + > +int vhost_net_get_rss(struct vhost_net *net, VirtioNetRssCapa *rss_capa) > +{ > + return 0; > +} > + > +int vhost_net_set_rss(struct vhost_net *net, VirtioNetRssData *rss_data) > +{ > + return 0; > +} > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c > index 30379d2ca4..aa2a1e8e5f 100644 > --- a/hw/net/vhost_net.c > +++ b/hw/net/vhost_net.c > @@ -512,3 +512,25 @@ int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu) > > return vhost_ops->vhost_net_set_mtu(&net->dev, mtu); > } > + > +int vhost_net_get_rss(struct vhost_net *net, VirtioNetRssCapa *rss_capa) > +{ > + const VhostOps *vhost_ops = net->dev.vhost_ops; > + > + if (!vhost_ops->vhost_net_get_rss) { > + return 0; > + } > + > + return vhost_ops->vhost_net_get_rss(&net->dev, rss_capa); > +} > + > +int vhost_net_set_rss(struct vhost_net *net, VirtioNetRssData *rss_data) > +{ > + const VhostOps *vhost_ops = net->dev.vhost_ops; > + > + if (!vhost_ops->vhost_net_set_rss) { > + return 0; > + } > + > + return vhost_ops->vhost_net_set_rss(&net->dev, rss_data); > +} > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c > index 38436e472b..237bbdb1b3 100644 > --- a/hw/net/virtio-net.c > +++ b/hw/net/virtio-net.c > @@ -741,8 +741,10 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features, > return features; > } > > - if (!ebpf_rss_is_loaded(&n->ebpf_rss)) { > - virtio_clear_feature(&features, VIRTIO_NET_F_RSS); > + if (nc->peer->info->type == NET_CLIENT_DRIVER_TAP) { > + if (!ebpf_rss_is_loaded(&n->ebpf_rss)) { > + virtio_clear_feature(&features, VIRTIO_NET_F_RSS); > + } > } > features = vhost_net_get_features(get_vhost_net(nc->peer), features); > vdev->backend_features = features; > @@ -1161,11 +1163,17 @@ static void virtio_net_detach_epbf_rss(VirtIONet *n); > > static void virtio_net_disable_rss(VirtIONet *n) > { > + NetClientState *nc = qemu_get_queue(n->nic); > + > if (n->rss_data.enabled) { > trace_virtio_net_rss_disable(); > } > n->rss_data.enabled = false; > > + if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_USER) { > + vhost_net_set_rss(get_vhost_net(nc->peer), &n->rss_data); > + } > + > virtio_net_detach_epbf_rss(n); > } > > @@ -1239,6 +1247,7 @@ static uint16_t virtio_net_handle_rss(VirtIONet *n, > bool do_rss) > { > VirtIODevice *vdev = VIRTIO_DEVICE(n); > + NetClientState *nc = qemu_get_queue(n->nic); > struct virtio_net_rss_config cfg; > size_t s, offset = 0, size_get; > uint16_t queue_pairs, i; > @@ -1354,22 +1363,29 @@ static uint16_t virtio_net_handle_rss(VirtIONet *n, > } > n->rss_data.enabled = true; > > - if (!n->rss_data.populate_hash) { > - if (!virtio_net_attach_epbf_rss(n)) { > - /* EBPF must be loaded for vhost */ > - if (get_vhost_net(qemu_get_queue(n->nic)->peer)) { > - warn_report("Can't load eBPF RSS for vhost"); > - goto error; > + if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_USER) { > + if (vhost_net_set_rss(get_vhost_net(nc->peer), &n->rss_data)) { > + warn_report("Failed to configure RSS for vhost-user"); > + goto error; > + } > + } else { > + if (!n->rss_data.populate_hash) { > + if (!virtio_net_attach_epbf_rss(n)) { > + /* EBPF must be loaded for vhost */ > + if (get_vhost_net(nc->peer)) { > + warn_report("Can't load eBPF RSS for vhost"); > + goto error; > + } > + /* fallback to software RSS */ > + warn_report("Can't load eBPF RSS - fallback to software RSS"); > + n->rss_data.enabled_software_rss = true; > } > - /* fallback to software RSS */ > - warn_report("Can't load eBPF RSS - fallback to software RSS"); > + } else { > + /* use software RSS for hash populating */ > + /* and detach eBPF if was loaded before */ > + virtio_net_detach_epbf_rss(n); > n->rss_data.enabled_software_rss = true; > } > - } else { > - /* use software RSS for hash populating */ > - /* and detach eBPF if was loaded before */ > - virtio_net_detach_epbf_rss(n); > - n->rss_data.enabled_software_rss = true; > } > > trace_virtio_net_rss_enable(n->rss_data.hash_types, > @@ -3534,8 +3550,11 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) > n->rss_capa.max_key_size = VIRTIO_NET_RSS_DEFAULT_KEY_SIZE; > n->rss_capa.max_indirection_len = VIRTIO_NET_RSS_DEFAULT_TABLE_LEN; > n->rss_capa.supported_hashes = VIRTIO_NET_RSS_SUPPORTED_HASHES; > - > - virtio_net_load_ebpf(n); > + if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_USER) { > + vhost_net_get_rss(get_vhost_net(nc->peer), &n->rss_capa); I wonder if we need a command parameter for the capability instead of silently get those from the vhost-user backhand (since there's no guarantee that the capability in src and dst are matched). Thanks > + } else { > + virtio_net_load_ebpf(n); > + } > } else { > n->rss_capa.max_indirection_len = 1; > } > diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h > index 81bf3109f8..0b9e2ea26e 100644 > --- a/include/hw/virtio/vhost-backend.h > +++ b/include/hw/virtio/vhost-backend.h > @@ -12,6 +12,7 @@ > #define VHOST_BACKEND_H > > #include "exec/memory.h" > +#include "hw/virtio/virtio-net.h" > > typedef enum VhostBackendType { > VHOST_BACKEND_TYPE_NONE = 0, > @@ -45,6 +46,10 @@ typedef int (*vhost_backend_memslots_limit)(struct vhost_dev *dev); > typedef int (*vhost_net_set_backend_op)(struct vhost_dev *dev, > struct vhost_vring_file *file); > typedef int (*vhost_net_set_mtu_op)(struct vhost_dev *dev, uint16_t mtu); > +typedef int (*vhost_net_get_rss_op)(struct vhost_dev *dev, > + VirtioNetRssCapa *rss_capa); > +typedef int (*vhost_net_set_rss_op)(struct vhost_dev *dev, > + VirtioNetRssData *rss_data); > typedef int (*vhost_scsi_set_endpoint_op)(struct vhost_dev *dev, > struct vhost_scsi_target *target); > typedef int (*vhost_scsi_clear_endpoint_op)(struct vhost_dev *dev, > @@ -133,6 +138,8 @@ typedef struct VhostOps { > vhost_backend_memslots_limit vhost_backend_memslots_limit; > vhost_net_set_backend_op vhost_net_set_backend; > vhost_net_set_mtu_op vhost_net_set_mtu; > + vhost_net_get_rss_op vhost_net_get_rss; > + vhost_net_set_rss_op vhost_net_set_rss; > vhost_scsi_set_endpoint_op vhost_scsi_set_endpoint; > vhost_scsi_clear_endpoint_op vhost_scsi_clear_endpoint; > vhost_scsi_get_abi_version_op vhost_scsi_get_abi_version; > diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h > index 387e913e4e..9cf702e7e3 100644 > --- a/include/net/vhost_net.h > +++ b/include/net/vhost_net.h > @@ -48,4 +48,8 @@ uint64_t vhost_net_get_acked_features(VHostNetState *net); > > int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu); > > +int vhost_net_get_rss(struct vhost_net *net, VirtioNetRssCapa *rss_capa); > + > +int vhost_net_set_rss(struct vhost_net *net, VirtioNetRssData *rss_data); > + > #endif
diff --git a/hw/net/vhost_net-stub.c b/hw/net/vhost_net-stub.c index 89d71cfb8e..cc05e07c1f 100644 --- a/hw/net/vhost_net-stub.c +++ b/hw/net/vhost_net-stub.c @@ -101,3 +101,13 @@ int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu) { return 0; } + +int vhost_net_get_rss(struct vhost_net *net, VirtioNetRssCapa *rss_capa) +{ + return 0; +} + +int vhost_net_set_rss(struct vhost_net *net, VirtioNetRssData *rss_data) +{ + return 0; +} diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 30379d2ca4..aa2a1e8e5f 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -512,3 +512,25 @@ int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu) return vhost_ops->vhost_net_set_mtu(&net->dev, mtu); } + +int vhost_net_get_rss(struct vhost_net *net, VirtioNetRssCapa *rss_capa) +{ + const VhostOps *vhost_ops = net->dev.vhost_ops; + + if (!vhost_ops->vhost_net_get_rss) { + return 0; + } + + return vhost_ops->vhost_net_get_rss(&net->dev, rss_capa); +} + +int vhost_net_set_rss(struct vhost_net *net, VirtioNetRssData *rss_data) +{ + const VhostOps *vhost_ops = net->dev.vhost_ops; + + if (!vhost_ops->vhost_net_set_rss) { + return 0; + } + + return vhost_ops->vhost_net_set_rss(&net->dev, rss_data); +} diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 38436e472b..237bbdb1b3 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -741,8 +741,10 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features, return features; } - if (!ebpf_rss_is_loaded(&n->ebpf_rss)) { - virtio_clear_feature(&features, VIRTIO_NET_F_RSS); + if (nc->peer->info->type == NET_CLIENT_DRIVER_TAP) { + if (!ebpf_rss_is_loaded(&n->ebpf_rss)) { + virtio_clear_feature(&features, VIRTIO_NET_F_RSS); + } } features = vhost_net_get_features(get_vhost_net(nc->peer), features); vdev->backend_features = features; @@ -1161,11 +1163,17 @@ static void virtio_net_detach_epbf_rss(VirtIONet *n); static void virtio_net_disable_rss(VirtIONet *n) { + NetClientState *nc = qemu_get_queue(n->nic); + if (n->rss_data.enabled) { trace_virtio_net_rss_disable(); } n->rss_data.enabled = false; + if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_USER) { + vhost_net_set_rss(get_vhost_net(nc->peer), &n->rss_data); + } + virtio_net_detach_epbf_rss(n); } @@ -1239,6 +1247,7 @@ static uint16_t virtio_net_handle_rss(VirtIONet *n, bool do_rss) { VirtIODevice *vdev = VIRTIO_DEVICE(n); + NetClientState *nc = qemu_get_queue(n->nic); struct virtio_net_rss_config cfg; size_t s, offset = 0, size_get; uint16_t queue_pairs, i; @@ -1354,22 +1363,29 @@ static uint16_t virtio_net_handle_rss(VirtIONet *n, } n->rss_data.enabled = true; - if (!n->rss_data.populate_hash) { - if (!virtio_net_attach_epbf_rss(n)) { - /* EBPF must be loaded for vhost */ - if (get_vhost_net(qemu_get_queue(n->nic)->peer)) { - warn_report("Can't load eBPF RSS for vhost"); - goto error; + if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_USER) { + if (vhost_net_set_rss(get_vhost_net(nc->peer), &n->rss_data)) { + warn_report("Failed to configure RSS for vhost-user"); + goto error; + } + } else { + if (!n->rss_data.populate_hash) { + if (!virtio_net_attach_epbf_rss(n)) { + /* EBPF must be loaded for vhost */ + if (get_vhost_net(nc->peer)) { + warn_report("Can't load eBPF RSS for vhost"); + goto error; + } + /* fallback to software RSS */ + warn_report("Can't load eBPF RSS - fallback to software RSS"); + n->rss_data.enabled_software_rss = true; } - /* fallback to software RSS */ - warn_report("Can't load eBPF RSS - fallback to software RSS"); + } else { + /* use software RSS for hash populating */ + /* and detach eBPF if was loaded before */ + virtio_net_detach_epbf_rss(n); n->rss_data.enabled_software_rss = true; } - } else { - /* use software RSS for hash populating */ - /* and detach eBPF if was loaded before */ - virtio_net_detach_epbf_rss(n); - n->rss_data.enabled_software_rss = true; } trace_virtio_net_rss_enable(n->rss_data.hash_types, @@ -3534,8 +3550,11 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) n->rss_capa.max_key_size = VIRTIO_NET_RSS_DEFAULT_KEY_SIZE; n->rss_capa.max_indirection_len = VIRTIO_NET_RSS_DEFAULT_TABLE_LEN; n->rss_capa.supported_hashes = VIRTIO_NET_RSS_SUPPORTED_HASHES; - - virtio_net_load_ebpf(n); + if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_USER) { + vhost_net_get_rss(get_vhost_net(nc->peer), &n->rss_capa); + } else { + virtio_net_load_ebpf(n); + } } else { n->rss_capa.max_indirection_len = 1; } diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h index 81bf3109f8..0b9e2ea26e 100644 --- a/include/hw/virtio/vhost-backend.h +++ b/include/hw/virtio/vhost-backend.h @@ -12,6 +12,7 @@ #define VHOST_BACKEND_H #include "exec/memory.h" +#include "hw/virtio/virtio-net.h" typedef enum VhostBackendType { VHOST_BACKEND_TYPE_NONE = 0, @@ -45,6 +46,10 @@ typedef int (*vhost_backend_memslots_limit)(struct vhost_dev *dev); typedef int (*vhost_net_set_backend_op)(struct vhost_dev *dev, struct vhost_vring_file *file); typedef int (*vhost_net_set_mtu_op)(struct vhost_dev *dev, uint16_t mtu); +typedef int (*vhost_net_get_rss_op)(struct vhost_dev *dev, + VirtioNetRssCapa *rss_capa); +typedef int (*vhost_net_set_rss_op)(struct vhost_dev *dev, + VirtioNetRssData *rss_data); typedef int (*vhost_scsi_set_endpoint_op)(struct vhost_dev *dev, struct vhost_scsi_target *target); typedef int (*vhost_scsi_clear_endpoint_op)(struct vhost_dev *dev, @@ -133,6 +138,8 @@ typedef struct VhostOps { vhost_backend_memslots_limit vhost_backend_memslots_limit; vhost_net_set_backend_op vhost_net_set_backend; vhost_net_set_mtu_op vhost_net_set_mtu; + vhost_net_get_rss_op vhost_net_get_rss; + vhost_net_set_rss_op vhost_net_set_rss; vhost_scsi_set_endpoint_op vhost_scsi_set_endpoint; vhost_scsi_clear_endpoint_op vhost_scsi_clear_endpoint; vhost_scsi_get_abi_version_op vhost_scsi_get_abi_version; diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h index 387e913e4e..9cf702e7e3 100644 --- a/include/net/vhost_net.h +++ b/include/net/vhost_net.h @@ -48,4 +48,8 @@ uint64_t vhost_net_get_acked_features(VHostNetState *net); int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu); +int vhost_net_get_rss(struct vhost_net *net, VirtioNetRssCapa *rss_capa); + +int vhost_net_set_rss(struct vhost_net *net, VirtioNetRssData *rss_data); + #endif
This patch introduces new Vhost backend callbacks to support RSS, and makes them called in Virtio-net device. It will be used by Vhost-user backend implementation to support RSS feature. Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com> --- hw/net/vhost_net-stub.c | 10 ++++++ hw/net/vhost_net.c | 22 +++++++++++++ hw/net/virtio-net.c | 53 +++++++++++++++++++++---------- include/hw/virtio/vhost-backend.h | 7 ++++ include/net/vhost_net.h | 4 +++ 5 files changed, 79 insertions(+), 17 deletions(-)