Message ID | 20200420093241.4238-3-lulu@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | vDPA support in qemu | expand |
On 4/20/20 4:32 AM, Cindy Lu wrote: > This patch set introduces a new net client type: vhost-vdpa. > vhost-vdpa net client will set up a vDPA device which is svhostdevpecified looks like you pasted 'vhostdev' in the middle of 'specified' > by a "vhostdev" parameter. > > Author: Tiwei Bie Should this be a 'Signed-off-by' tag? > Signed-off-by: Cindy Lu <lulu@redhat.com> > --- > +++ b/include/net/vhost-vdpa.h > @@ -0,0 +1,18 @@ > +/* > + * vhost-vdpa.h > + * > + * Copyright(c) 2017 Intel Corporation. All rights reserved. > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or later. Claiming "All rights reserved" is at odds with claiming "GPL", which specifically requires that you are NOT reserving all rights but are instead granting various rights to others insofar as they preserve this code as free software. I can overlook it on BSD licenses (as there are lots of examples of bad copy-and-paste on various templates that uses the misleading term), but not on GPL licenses. Also, you may want to consider if adding 2020 to your copyright date is appropriate. > +++ b/net/vhost-vdpa.c > @@ -0,0 +1,211 @@ > +/* > + * vhost-vdpa.c > + * > + * Copyright(c) 2017-2018 Intel Corporation. All rights reserved. > + * Copyright(c) 2020 Red Hat, Inc. > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or later. Another inconsistent license. > +++ b/qapi/net.json > @@ -441,6 +441,22 @@ > '*queues': 'int' } } > > ## > +# @NetdevVhostVDPAOptions: > +# > +# Vhost-vdpa network backend > +# > +# @vhostdev: name of a mdev dev path in sysfs > +# > +# @queues: number of queues to be created for multiqueue vhost-vdpa > +# (default: 1) (Since 2.11) There's no need to add a 'since' tag for an individual member if... > +# > +# Since: 2.11 ...the struct itself was introduced in the same release. However, using 2.11 as the release is wrong; the next release will be 5.1. > +## > +{ 'struct': 'NetdevVhostVDPAOptions', > + 'data': { > + '*vhostdev': 'str', > + '*queues': 'int' } } > +## > # @NetClientDriver: > # > # Available netdev drivers. > @@ -451,7 +467,7 @@ > ## > { 'enum': 'NetClientDriver', Missing documentation that 'vhost-vdpa' was added in 5.1. > 'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde', > - 'bridge', 'hubport', 'netmap', 'vhost-user' ] } > + 'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa' ] } > > ## > # @Netdev: > @@ -479,7 +495,8 @@ > 'bridge': 'NetdevBridgeOptions', > 'hubport': 'NetdevHubPortOptions', > 'netmap': 'NetdevNetmapOptions', > - 'vhost-user': 'NetdevVhostUserOptions' } } > + 'vhost-user': 'NetdevVhostUserOptions', > + 'vhost-vdpa': 'NetdevVhostVDPAOptions' } } > > ## > # @NetLegacy: >
On 2020/4/20 下午5:32, Cindy Lu wrote: > This patch set introduces a new net client type: vhost-vdpa. > vhost-vdpa net client will set up a vDPA device which is svhostdevpecified typo. > by a "vhostdev" parameter. > > Author: Tiwei Bie Please keep the sobs from the original patch. > Signed-off-by: Cindy Lu <lulu@redhat.com> > --- > include/net/vhost-vdpa.h | 18 ++++ > include/net/vhost_net.h | 1 + > net/Makefile.objs | 2 +- > net/clients.h | 2 + > net/net.c | 1 + > net/vhost-vdpa.c | 211 +++++++++++++++++++++++++++++++++++++++ > qapi/net.json | 21 +++- > 7 files changed, 253 insertions(+), 3 deletions(-) > create mode 100644 include/net/vhost-vdpa.h > create mode 100644 net/vhost-vdpa.c I think this patch should come after patch 3. And it's better to make this as a module like vhost-user. > > diff --git a/include/net/vhost-vdpa.h b/include/net/vhost-vdpa.h > new file mode 100644 > index 0000000000..9ddd538dad > --- /dev/null > +++ b/include/net/vhost-vdpa.h > @@ -0,0 +1,18 @@ > +/* > + * vhost-vdpa.h > + * > + * Copyright(c) 2017 Intel Corporation. All rights reserved. 2020 and please add Red Hat here as well. > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or later. > + * See the COPYING file in the top-level directory. > + * > + */ > + > +#ifndef VHOST_VDPA_H > +#define VHOST_VDPA_H > + > +struct vhost_net; > +struct vhost_net *vhost_vdpa_get_vhost_net(NetClientState *nc); > +uint64_t vhost_vdpa_get_acked_features(NetClientState *nc); > + > +#endif /* VHOST_VDPA_H */ > diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h > index 77e47398c4..6f3a624cf7 100644 > --- a/include/net/vhost_net.h > +++ b/include/net/vhost_net.h > @@ -39,5 +39,6 @@ int vhost_set_vring_enable(NetClientState * nc, int enable); > uint64_t vhost_net_get_acked_features(VHostNetState *net); > > int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu); > +int vhost_set_state(NetClientState *nc, int state); This function is not used in this patch. > > #endif > diff --git a/net/Makefile.objs b/net/Makefile.objs > index c5d076d19c..da459cfc19 100644 > --- a/net/Makefile.objs > +++ b/net/Makefile.objs > @@ -26,7 +26,7 @@ tap-obj-$(CONFIG_SOLARIS) = tap-solaris.o > tap-obj-y ?= tap-stub.o > common-obj-$(CONFIG_POSIX) += tap.o $(tap-obj-y) > common-obj-$(CONFIG_WIN32) += tap-win32.o > - > +common-obj-$(CONFIG_VHOST_KERNEL) += vhost-vdpa.o > vde.o-libs = $(VDE_LIBS) > > common-obj-$(CONFIG_CAN_BUS) += can/ > diff --git a/net/clients.h b/net/clients.h > index a6ef267e19..92f9b59aed 100644 > --- a/net/clients.h > +++ b/net/clients.h > @@ -61,4 +61,6 @@ int net_init_netmap(const Netdev *netdev, const char *name, > int net_init_vhost_user(const Netdev *netdev, const char *name, > NetClientState *peer, Error **errp); > > +int net_init_vhost_vdpa(const Netdev *netdev, const char *name, > + NetClientState *peer, Error **errp); > #endif /* QEMU_NET_CLIENTS_H */ > diff --git a/net/net.c b/net/net.c > index ac5080dda1..2beb95388a 100644 > --- a/net/net.c > +++ b/net/net.c > @@ -964,6 +964,7 @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])( > [NET_CLIENT_DRIVER_HUBPORT] = net_init_hubport, > #ifdef CONFIG_VHOST_NET_USER > [NET_CLIENT_DRIVER_VHOST_USER] = net_init_vhost_user, > + [NET_CLIENT_DRIVER_VHOST_VDPA] = net_init_vhost_vdpa, > #endif > #ifdef CONFIG_L2TPV3 > [NET_CLIENT_DRIVER_L2TPV3] = net_init_l2tpv3, > diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c > new file mode 100644 > index 0000000000..5daeba0b76 > --- /dev/null > +++ b/net/vhost-vdpa.c > @@ -0,0 +1,211 @@ > +/* > + * vhost-vdpa.c > + * > + * Copyright(c) 2017-2018 Intel Corporation. All rights reserved. > + * Copyright(c) 2020 Red Hat, Inc. > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or later. > + * See the COPYING file in the top-level directory. > + * > + */ > + > +#include "qemu/osdep.h" > +#include "clients.h" > +#include "net/vhost_net.h" > +#include "net/vhost-vdpa.h" > +#include "hw/virtio/vhost-vdpa.h" > +#include "chardev/char-fe.h" I don't think we use charfe in this file. > +#include "qemu/config-file.h" > +#include "qemu/error-report.h" > +#include "qemu/option.h" > +#include "qapi/error.h" > +#include "trace.h" I think we don't use tracing in this file. > +#include <linux/vfio.h> > +#include <sys/ioctl.h> > +#include <err.h> > +#include <linux/virtio_net.h> > + > + > +typedef struct VhostVDPAState { > + NetClientState nc; This may not work for the case of multiqueue, you can either fix this or just leave a comment for TODO. > + struct vhost_vdpa vhost_vdpa; This explains why patch 3 should come first. > + VHostNetState *vhost_net; > + uint64_t acked_features; > + bool started; > +} VhostVDPAState; > + > +VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc) > +{ > + VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); > + assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); > + return s->vhost_net; > +} > + > +uint64_t vhost_vdpa_get_acked_features(NetClientState *nc) > +{ > + VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); > + assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); > + return s->acked_features; > +} > + > +static void vhost_vdpa_stop(NetClientState *ncs) > +{ > + VhostVDPAState *s; > + > + assert(ncs->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); > + > + s = DO_UPCAST(VhostVDPAState, nc, ncs); > + > + if (s->vhost_net) { > + /* save acked features */ > + uint64_t features = vhost_net_get_acked_features(s->vhost_net); > + if (features) { > + s->acked_features = features; > + } > + vhost_net_cleanup(s->vhost_net); > + } > +} > + > +static int vhost_vdpa_start(NetClientState *ncs, void *be) > +{ The name of this function is confusing, we don't start vhost_vdpa actually. > + VhostNetOptions options; > + struct vhost_net *net = NULL; > + VhostVDPAState *s; > + > + options.backend_type = VHOST_BACKEND_TYPE_VDPA; > + > + assert(ncs->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); > + > + s = DO_UPCAST(VhostVDPAState, nc, ncs); > + > + options.net_backend = ncs; > + options.opaque = be; > + options.busyloop_timeout = 0; > + net = vhost_net_init(&options); > + if (!net) { > + error_report("failed to init vhost_net for queue"); > + goto err; > + } > + > + if (s->vhost_net) { > + vhost_net_cleanup(s->vhost_net); > + g_free(s->vhost_net); > + } > + s->vhost_net = net; > + > + return 0; > + > +err: > + if (net) { > + vhost_net_cleanup(net); > + } > + vhost_vdpa_stop(ncs); > + return -1; > +} > +static void vhost_vdpa_cleanup(NetClientState *nc) > +{ > + VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); > + > + if (s->vhost_net) { > + vhost_net_cleanup(s->vhost_net); > + g_free(s->vhost_net); > + s->vhost_net = NULL; > + } > + > + qemu_purge_queued_packets(nc); > +} > + > +static bool vhost_vdpa_has_vnet_hdr(NetClientState *nc) > +{ > + assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); > + > + return true; > +} > + > +static bool vhost_vdpa_has_ufo(NetClientState *nc) > +{ > + assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); > + VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); > + uint64_t features = 0; > + > + features |= (1ULL << VIRTIO_NET_F_HOST_UFO); > + features = vhost_net_get_features(s->vhost_net, features); > + return !!(features & (1ULL << VIRTIO_NET_F_HOST_UFO)); > + > +} > + > +static NetClientInfo net_vhost_vdpa_info = { > + .type = NET_CLIENT_DRIVER_VHOST_VDPA, > + .size = sizeof(VhostVDPAState), > + .cleanup = vhost_vdpa_cleanup, > + .has_vnet_hdr = vhost_vdpa_has_vnet_hdr, > + .has_ufo = vhost_vdpa_has_ufo, > +}; > + > +static int net_vhost_vdpa_init(NetClientState *peer, const char *device, > + const char *name, const char *vhostdev) > +{ > + NetClientState *nc = NULL; > + VhostVDPAState *s; > + int vdpa_device_fd; > + assert(name); > + > + nc = qemu_new_net_client(&net_vhost_vdpa_info, peer, device, name); > + snprintf(nc->info_str, sizeof(nc->info_str), "vhost-vdpa"); > + nc->queue_index = 0; > + > + s = DO_UPCAST(VhostVDPAState, nc, nc); > + > + vdpa_device_fd = open(vhostdev, O_RDWR); > + if (vdpa_device_fd == -1) { > + return -errno; > + } > + s->vhost_vdpa.device_fd = vdpa_device_fd; Need to add a step to verify the device type and fail if it was not a networking device. > + vhost_vdpa_start(nc, (void *)&s->vhost_vdpa); > + > + assert(s->vhost_net); > + > + return 0; > +} > + > +static int net_vhost_check_net(void *opaque, QemuOpts *opts, Error **errp) > +{ > + const char *name = opaque; > + const char *driver, *netdev; > + > + driver = qemu_opt_get(opts, "driver"); > + netdev = qemu_opt_get(opts, "netdev"); > + > + if (!driver || !netdev) { > + return 0; > + } > + > + if (strcmp(netdev, name) == 0 && > + !g_str_has_prefix(driver, "virtio-net-")) { > + error_setg(errp, "vhost-vdpa requires frontend driver virtio-net-*"); > + return -1; > + } > + > + return 0; > +} > + > +int net_init_vhost_vdpa(const Netdev *netdev, const char *name, > + NetClientState *peer, Error **errp) > +{ > + const NetdevVhostVDPAOptions *vhost_vdpa_opts; > + > + assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA); > + vhost_vdpa_opts = &netdev->u.vhost_vdpa; > + > + /* verify net frontend */ > + if (qemu_opts_foreach(qemu_find_opts("device"), net_vhost_check_net, > + (char *)name, errp)) { > + return -1; > + } > + > + > + return net_vhost_vdpa_init(peer, "vhost_vdpa", name, > + vhost_vdpa_opts->vhostdev); Please add the support for passing fd via command line. > + > + return 0; > +} > diff --git a/qapi/net.json b/qapi/net.json > index 335295be50..35a5ccee39 100644 > --- a/qapi/net.json > +++ b/qapi/net.json > @@ -441,6 +441,22 @@ > '*queues': 'int' } } > > ## > +# @NetdevVhostVDPAOptions: > +# > +# Vhost-vdpa network backend > +# > +# @vhostdev: name of a mdev dev path in sysfs > +# > +# @queues: number of queues to be created for multiqueue vhost-vdpa > +# (default: 1) (Since 2.11) > +# > +# Since: 2.11 The version number is wrong, I guess it's probably 5.1. Thanks > +## > +{ 'struct': 'NetdevVhostVDPAOptions', > + 'data': { > + '*vhostdev': 'str', > + '*queues': 'int' } } > +## > # @NetClientDriver: > # > # Available netdev drivers. > @@ -451,7 +467,7 @@ > ## > { 'enum': 'NetClientDriver', > 'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde', > - 'bridge', 'hubport', 'netmap', 'vhost-user' ] } > + 'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa' ] } > > ## > # @Netdev: > @@ -479,7 +495,8 @@ > 'bridge': 'NetdevBridgeOptions', > 'hubport': 'NetdevHubPortOptions', > 'netmap': 'NetdevNetmapOptions', > - 'vhost-user': 'NetdevVhostUserOptions' } } > + 'vhost-user': 'NetdevVhostUserOptions', > + 'vhost-vdpa': 'NetdevVhostVDPAOptions' } } > > ## > # @NetLegacy:
On Tue, Apr 21, 2020 at 11:40 AM Jason Wang <jasowang@redhat.com> wrote: > > On 2020/4/20 下午5:32, Cindy Lu wrote: > > This patch set introduces a new net client type: vhost-vdpa. > > vhost-vdpa net client will set up a vDPA device which is > svhostdevpecified > > > typo. > > Will fix this > > > by a "vhostdev" parameter. > > > > Author: Tiwei Bie > > > Please keep the sobs from the original patch. > > > Will fix this > > Signed-off-by: Cindy Lu <lulu@redhat.com> > > --- > > include/net/vhost-vdpa.h | 18 ++++ > > include/net/vhost_net.h | 1 + > > net/Makefile.objs | 2 +- > > net/clients.h | 2 + > > net/net.c | 1 + > > net/vhost-vdpa.c | 211 +++++++++++++++++++++++++++++++++++++++ > > qapi/net.json | 21 +++- > > 7 files changed, 253 insertions(+), 3 deletions(-) > > create mode 100644 include/net/vhost-vdpa.h > > create mode 100644 net/vhost-vdpa.c > > > I think this patch should come after patch 3. > > And it's better to make this as a module like vhost-user. > > Got it, Will fix this > > > > > diff --git a/include/net/vhost-vdpa.h b/include/net/vhost-vdpa.h > > new file mode 100644 > > index 0000000000..9ddd538dad > > --- /dev/null > > +++ b/include/net/vhost-vdpa.h > > @@ -0,0 +1,18 @@ > > +/* > > + * vhost-vdpa.h > > + * > > + * Copyright(c) 2017 Intel Corporation. All rights reserved. > > > 2020 and please add Red Hat here as well. > > > Will fix this > > + * > > + * This work is licensed under the terms of the GNU GPL, version 2 or > later. > > + * See the COPYING file in the top-level directory. > > + * > > + */ > > + > > +#ifndef VHOST_VDPA_H > > +#define VHOST_VDPA_H > > + > > +struct vhost_net; > > +struct vhost_net *vhost_vdpa_get_vhost_net(NetClientState *nc); > > +uint64_t vhost_vdpa_get_acked_features(NetClientState *nc); > > + > > +#endif /* VHOST_VDPA_H */ > > diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h > > index 77e47398c4..6f3a624cf7 100644 > > --- a/include/net/vhost_net.h > > +++ b/include/net/vhost_net.h > > @@ -39,5 +39,6 @@ int vhost_set_vring_enable(NetClientState * nc, int > enable); > > uint64_t vhost_net_get_acked_features(VHostNetState *net); > > > > int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu); > > +int vhost_set_state(NetClientState *nc, int state); > > > This function is not used in this patch. > > Will fix this > > > > > #endif > > diff --git a/net/Makefile.objs b/net/Makefile.objs > > index c5d076d19c..da459cfc19 100644 > > --- a/net/Makefile.objs > > +++ b/net/Makefile.objs > > @@ -26,7 +26,7 @@ tap-obj-$(CONFIG_SOLARIS) = tap-solaris.o > > tap-obj-y ?= tap-stub.o > > common-obj-$(CONFIG_POSIX) += tap.o $(tap-obj-y) > > common-obj-$(CONFIG_WIN32) += tap-win32.o > > - > > +common-obj-$(CONFIG_VHOST_KERNEL) += vhost-vdpa.o > > vde.o-libs = $(VDE_LIBS) > > > > common-obj-$(CONFIG_CAN_BUS) += can/ > > diff --git a/net/clients.h b/net/clients.h > > index a6ef267e19..92f9b59aed 100644 > > --- a/net/clients.h > > +++ b/net/clients.h > > @@ -61,4 +61,6 @@ int net_init_netmap(const Netdev *netdev, const char > *name, > > int net_init_vhost_user(const Netdev *netdev, const char *name, > > NetClientState *peer, Error **errp); > > > > +int net_init_vhost_vdpa(const Netdev *netdev, const char *name, > > + NetClientState *peer, Error **errp); > > #endif /* QEMU_NET_CLIENTS_H */ > > diff --git a/net/net.c b/net/net.c > > index ac5080dda1..2beb95388a 100644 > > --- a/net/net.c > > +++ b/net/net.c > > @@ -964,6 +964,7 @@ static int (* const > net_client_init_fun[NET_CLIENT_DRIVER__MAX])( > > [NET_CLIENT_DRIVER_HUBPORT] = net_init_hubport, > > #ifdef CONFIG_VHOST_NET_USER > > [NET_CLIENT_DRIVER_VHOST_USER] = net_init_vhost_user, > > + [NET_CLIENT_DRIVER_VHOST_VDPA] = net_init_vhost_vdpa, > > #endif > > #ifdef CONFIG_L2TPV3 > > [NET_CLIENT_DRIVER_L2TPV3] = net_init_l2tpv3, > > diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c > > new file mode 100644 > > index 0000000000..5daeba0b76 > > --- /dev/null > > +++ b/net/vhost-vdpa.c > > @@ -0,0 +1,211 @@ > > +/* > > + * vhost-vdpa.c > > + * > > + * Copyright(c) 2017-2018 Intel Corporation. All rights reserved. > > + * Copyright(c) 2020 Red Hat, Inc. > > + * > > + * This work is licensed under the terms of the GNU GPL, version 2 or > later. > > + * See the COPYING file in the top-level directory. > > + * > > + */ > > + > > +#include "qemu/osdep.h" > > +#include "clients.h" > > +#include "net/vhost_net.h" > > +#include "net/vhost-vdpa.h" > > +#include "hw/virtio/vhost-vdpa.h" > > +#include "chardev/char-fe.h" > > > I don't think we use charfe in this file. > > > > +#include "qemu/config-file.h" > > +#include "qemu/error-report.h" > > +#include "qemu/option.h" > > +#include "qapi/error.h" > > +#include "trace.h" > > > I think we don't use tracing in this file. > > Will fix this > > > +#include <linux/vfio.h> > > +#include <sys/ioctl.h> > > +#include <err.h> > > +#include <linux/virtio_net.h> > > + > > + > > +typedef struct VhostVDPAState { > > + NetClientState nc; > > > This may not work for the case of multiqueue, you can either fix this or > just leave a comment for TODO. > > Will fix this > > > + struct vhost_vdpa vhost_vdpa; > > > This explains why patch 3 should come first. > > > > + VHostNetState *vhost_net; > > + uint64_t acked_features; > > + bool started; > > +} VhostVDPAState; > > + > > +VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc) > > +{ > > + VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); > > + assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); > > + return s->vhost_net; > > +} > > + > > +uint64_t vhost_vdpa_get_acked_features(NetClientState *nc) > > +{ > > + VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); > > + assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); > > + return s->acked_features; > > +} > > + > > +static void vhost_vdpa_stop(NetClientState *ncs) > > +{ > > + VhostVDPAState *s; > > + > > + assert(ncs->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); > > + > > + s = DO_UPCAST(VhostVDPAState, nc, ncs); > > + > > + if (s->vhost_net) { > > + /* save acked features */ > > + uint64_t features = vhost_net_get_acked_features(s->vhost_net); > > + if (features) { > > + s->acked_features = features; > > + } > > + vhost_net_cleanup(s->vhost_net); > > + } > > +} > > + > > +static int vhost_vdpa_start(NetClientState *ncs, void *be) > > +{ > > > The name of this function is confusing, we don't start vhost_vdpa actually. > > ok Got it , I will change it > > > + VhostNetOptions options; > > + struct vhost_net *net = NULL; > > + VhostVDPAState *s; > > + > > + options.backend_type = VHOST_BACKEND_TYPE_VDPA; > > + > > + assert(ncs->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); > > + > > + s = DO_UPCAST(VhostVDPAState, nc, ncs); > > + > > + options.net_backend = ncs; > > + options.opaque = be; > > + options.busyloop_timeout = 0; > > + net = vhost_net_init(&options); > > + if (!net) { > > + error_report("failed to init vhost_net for queue"); > > + goto err; > > + } > > + > > + if (s->vhost_net) { > > + vhost_net_cleanup(s->vhost_net); > > + g_free(s->vhost_net); > > + } > > + s->vhost_net = net; > > + > > + return 0; > > + > > +err: > > + if (net) { > > + vhost_net_cleanup(net); > > + } > > + vhost_vdpa_stop(ncs); > > + return -1; > > +} > > +static void vhost_vdpa_cleanup(NetClientState *nc) > > +{ > > + VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); > > + > > + if (s->vhost_net) { > > + vhost_net_cleanup(s->vhost_net); > > + g_free(s->vhost_net); > > + s->vhost_net = NULL; > > + } > > + > > + qemu_purge_queued_packets(nc); > > +} > > + > > +static bool vhost_vdpa_has_vnet_hdr(NetClientState *nc) > > +{ > > + assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); > > + > > + return true; > > +} > > + > > +static bool vhost_vdpa_has_ufo(NetClientState *nc) > > +{ > > + assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); > > + VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); > > + uint64_t features = 0; > > + > > + features |= (1ULL << VIRTIO_NET_F_HOST_UFO); > > + features = vhost_net_get_features(s->vhost_net, features); > > + return !!(features & (1ULL << VIRTIO_NET_F_HOST_UFO)); > > + > > +} > > + > > +static NetClientInfo net_vhost_vdpa_info = { > > + .type = NET_CLIENT_DRIVER_VHOST_VDPA, > > + .size = sizeof(VhostVDPAState), > > + .cleanup = vhost_vdpa_cleanup, > > + .has_vnet_hdr = vhost_vdpa_has_vnet_hdr, > > + .has_ufo = vhost_vdpa_has_ufo, > > +}; > > + > > +static int net_vhost_vdpa_init(NetClientState *peer, const char *device, > > + const char *name, const char *vhostdev) > > +{ > > + NetClientState *nc = NULL; > > + VhostVDPAState *s; > > + int vdpa_device_fd; > > + assert(name); > > + > > + nc = qemu_new_net_client(&net_vhost_vdpa_info, peer, device, name); > > + snprintf(nc->info_str, sizeof(nc->info_str), "vhost-vdpa"); > > + nc->queue_index = 0; > > + > > + s = DO_UPCAST(VhostVDPAState, nc, nc); > > + > > + vdpa_device_fd = open(vhostdev, O_RDWR); > > + if (vdpa_device_fd == -1) { > > + return -errno; > > + } > > + s->vhost_vdpa.device_fd = vdpa_device_fd; > > > Need to add a step to verify the device type and fail if it was not a > networking device. > > sure will add the check . > > > + vhost_vdpa_start(nc, (void *)&s->vhost_vdpa); > > + > > + assert(s->vhost_net); > > + > > + return 0; > > +} > > + > > +static int net_vhost_check_net(void *opaque, QemuOpts *opts, Error > **errp) > > +{ > > + const char *name = opaque; > > + const char *driver, *netdev; > > + > > + driver = qemu_opt_get(opts, "driver"); > > + netdev = qemu_opt_get(opts, "netdev"); > > + > > + if (!driver || !netdev) { > > + return 0; > > + } > > + > > + if (strcmp(netdev, name) == 0 && > > + !g_str_has_prefix(driver, "virtio-net-")) { > > + error_setg(errp, "vhost-vdpa requires frontend driver > virtio-net-*"); > > + return -1; > > + } > > + > > + return 0; > > +} > > + > > +int net_init_vhost_vdpa(const Netdev *netdev, const char *name, > > + NetClientState *peer, Error **errp) > > +{ > > + const NetdevVhostVDPAOptions *vhost_vdpa_opts; > > + > > + assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA); > > + vhost_vdpa_opts = &netdev->u.vhost_vdpa; > > + > > + /* verify net frontend */ > > + if (qemu_opts_foreach(qemu_find_opts("device"), net_vhost_check_net, > > + (char *)name, errp)) { > > + return -1; > > + } > > + > > + > > + return net_vhost_vdpa_init(peer, "vhost_vdpa", name, > > + vhost_vdpa_opts->vhostdev); > > > Please add the support for passing fd via command line. > Will add the support > > > + > > + return 0; > > +} > > diff --git a/qapi/net.json b/qapi/net.json > > index 335295be50..35a5ccee39 100644 > > --- a/qapi/net.json > > +++ b/qapi/net.json > > @@ -441,6 +441,22 @@ > > '*queues': 'int' } } > > > > ## > > +# @NetdevVhostVDPAOptions: > > +# > > +# Vhost-vdpa network backend > > +# > > +# @vhostdev: name of a mdev dev path in sysfs > > +# > > +# @queues: number of queues to be created for multiqueue vhost-vdpa > > +# (default: 1) (Since 2.11) > > +# > > +# Since: 2.11 > > > The version number is wrong, I guess it's probably 5.1. > > Thanks > > Will fix this > > > +## > > +{ 'struct': 'NetdevVhostVDPAOptions', > > + 'data': { > > + '*vhostdev': 'str', > > + '*queues': 'int' } } > > +## > > # @NetClientDriver: > > # > > # Available netdev drivers. > > @@ -451,7 +467,7 @@ > > ## > > { 'enum': 'NetClientDriver', > > 'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde', > > - 'bridge', 'hubport', 'netmap', 'vhost-user' ] } > > + 'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa' ] > } > > > > ## > > # @Netdev: > > @@ -479,7 +495,8 @@ > > 'bridge': 'NetdevBridgeOptions', > > 'hubport': 'NetdevHubPortOptions', > > 'netmap': 'NetdevNetmapOptions', > > - 'vhost-user': 'NetdevVhostUserOptions' } } > > + 'vhost-user': 'NetdevVhostUserOptions', > > + 'vhost-vdpa': 'NetdevVhostVDPAOptions' } } > > > > ## > > # @NetLegacy: > >
On 21/04/2020 11:46, Cindy Lu wrote: > > > On Tue, Apr 21, 2020 at 11:40 AM Jason Wang <jasowang@redhat.com > <mailto:jasowang@redhat.com>> wrote: > > > On 2020/4/20 下午5:32, Cindy Lu wrote: > > This patch set introduces a new net client type: vhost-vdpa. > > vhost-vdpa net client will set up a vDPA device which is > svhostdevpecified > > > typo. > > Will fix this > > > > by a "vhostdev" parameter. > > > > Author: Tiwei Bie > > > Please keep the sobs from the original patch. > > > Will fix this If you want to set Tiwei Bie as the original author of the patch you can use "git commit --author="Tiwei Bie <XXXX>" --amend" to update your patch. When you will send the series, git-send-email will add the line "From: Tiwei Bie <XXXX>" at the beginning of the email to identify the original author. Don't remove his Sob and don't forget yo add yours. Thanks, Laurent
On 20/04/2020 11:32, Cindy Lu wrote: > This patch set introduces a new net client type: vhost-vdpa. > vhost-vdpa net client will set up a vDPA device which is svhostdevpecified > by a "vhostdev" parameter. > > Author: Tiwei Bie > Signed-off-by: Cindy Lu <lulu@redhat.com> > --- > include/net/vhost-vdpa.h | 18 ++++ > include/net/vhost_net.h | 1 + > net/Makefile.objs | 2 +- > net/clients.h | 2 + > net/net.c | 1 + > net/vhost-vdpa.c | 211 +++++++++++++++++++++++++++++++++++++++ > qapi/net.json | 21 +++- > 7 files changed, 253 insertions(+), 3 deletions(-) > create mode 100644 include/net/vhost-vdpa.h > create mode 100644 net/vhost-vdpa.c > > diff --git a/include/net/vhost-vdpa.h b/include/net/vhost-vdpa.h > new file mode 100644 > index 0000000000..9ddd538dad > --- /dev/null > +++ b/include/net/vhost-vdpa.h > @@ -0,0 +1,18 @@ > +/* > + * vhost-vdpa.h > + * > + * Copyright(c) 2017 Intel Corporation. All rights reserved. > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or later. > + * See the COPYING file in the top-level directory. > + * > + */ > + > +#ifndef VHOST_VDPA_H > +#define VHOST_VDPA_H > + > +struct vhost_net; > +struct vhost_net *vhost_vdpa_get_vhost_net(NetClientState *nc); > +uint64_t vhost_vdpa_get_acked_features(NetClientState *nc); > + > +#endif /* VHOST_VDPA_H */ > diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h > index 77e47398c4..6f3a624cf7 100644 > --- a/include/net/vhost_net.h > +++ b/include/net/vhost_net.h > @@ -39,5 +39,6 @@ int vhost_set_vring_enable(NetClientState * nc, int enable); > uint64_t vhost_net_get_acked_features(VHostNetState *net); > > int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu); > +int vhost_set_state(NetClientState *nc, int state); > > #endif > diff --git a/net/Makefile.objs b/net/Makefile.objs > index c5d076d19c..da459cfc19 100644 > --- a/net/Makefile.objs > +++ b/net/Makefile.objs > @@ -26,7 +26,7 @@ tap-obj-$(CONFIG_SOLARIS) = tap-solaris.o > tap-obj-y ?= tap-stub.o > common-obj-$(CONFIG_POSIX) += tap.o $(tap-obj-y) > common-obj-$(CONFIG_WIN32) += tap-win32.o > - > +common-obj-$(CONFIG_VHOST_KERNEL) += vhost-vdpa.o should it be CONFIG_VHOST_NET_USER as you use net_init_vhost_vdpa() below inside a "#ifdef CONFIG_VHOST_NET_USER"? Why don't you define a CONFIG_VHOST_VDPA? > vde.o-libs = $(VDE_LIBS) > > common-obj-$(CONFIG_CAN_BUS) += can/ > diff --git a/net/clients.h b/net/clients.h > index a6ef267e19..92f9b59aed 100644 > --- a/net/clients.h > +++ b/net/clients.h > @@ -61,4 +61,6 @@ int net_init_netmap(const Netdev *netdev, const char *name, > int net_init_vhost_user(const Netdev *netdev, const char *name, > NetClientState *peer, Error **errp); > > +int net_init_vhost_vdpa(const Netdev *netdev, const char *name, > + NetClientState *peer, Error **errp); > #endif /* QEMU_NET_CLIENTS_H */ > diff --git a/net/net.c b/net/net.c > index ac5080dda1..2beb95388a 100644 > --- a/net/net.c > +++ b/net/net.c > @@ -964,6 +964,7 @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])( > [NET_CLIENT_DRIVER_HUBPORT] = net_init_hubport, > #ifdef CONFIG_VHOST_NET_USER ^^^^^^^^^^^^^^^^^^^^^ here > [NET_CLIENT_DRIVER_VHOST_USER] = net_init_vhost_user, > + [NET_CLIENT_DRIVER_VHOST_VDPA] = net_init_vhost_vdpa, > #endif > #ifdef CONFIG_L2TPV3 > [NET_CLIENT_DRIVER_L2TPV3] = net_init_l2tpv3, > diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c > new file mode 100644 > index 0000000000..5daeba0b76 > --- /dev/null > +++ b/net/vhost-vdpa.c ... > +static int net_vhost_check_net(void *opaque, QemuOpts *opts, Error **errp) > +{ > + const char *name = opaque; > + const char *driver, *netdev; > + > + driver = qemu_opt_get(opts, "driver"); > + netdev = qemu_opt_get(opts, "netdev"); > + > + if (!driver || !netdev) { > + return 0; > + } > + > + if (strcmp(netdev, name) == 0 && > + !g_str_has_prefix(driver, "virtio-net-")) { > + error_setg(errp, "vhost-vdpa requires frontend driver virtio-net-*"); > + return -1; > + } > So perhaps you can build the file only if CONFIG_VIRTIO_NET is set? Thanks, Laurent
On Tue, Apr 21, 2020 at 11:47 PM Laurent Vivier <lvivier@redhat.com> wrote: > > On 20/04/2020 11:32, Cindy Lu wrote: > > This patch set introduces a new net client type: vhost-vdpa. > > vhost-vdpa net client will set up a vDPA device which is svhostdevpecified > > by a "vhostdev" parameter. > > > > Author: Tiwei Bie > > Signed-off-by: Cindy Lu <lulu@redhat.com> > > --- > > include/net/vhost-vdpa.h | 18 ++++ > > include/net/vhost_net.h | 1 + > > net/Makefile.objs | 2 +- > > net/clients.h | 2 + > > net/net.c | 1 + > > net/vhost-vdpa.c | 211 +++++++++++++++++++++++++++++++++++++++ > > qapi/net.json | 21 +++- > > 7 files changed, 253 insertions(+), 3 deletions(-) > > create mode 100644 include/net/vhost-vdpa.h > > create mode 100644 net/vhost-vdpa.c > > > > diff --git a/include/net/vhost-vdpa.h b/include/net/vhost-vdpa.h > > new file mode 100644 > > index 0000000000..9ddd538dad > > --- /dev/null > > +++ b/include/net/vhost-vdpa.h > > @@ -0,0 +1,18 @@ > > +/* > > + * vhost-vdpa.h > > + * > > + * Copyright(c) 2017 Intel Corporation. All rights reserved. > > + * > > + * This work is licensed under the terms of the GNU GPL, version 2 or later. > > + * See the COPYING file in the top-level directory. > > + * > > + */ > > + > > +#ifndef VHOST_VDPA_H > > +#define VHOST_VDPA_H > > + > > +struct vhost_net; > > +struct vhost_net *vhost_vdpa_get_vhost_net(NetClientState *nc); > > +uint64_t vhost_vdpa_get_acked_features(NetClientState *nc); > > + > > +#endif /* VHOST_VDPA_H */ > > diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h > > index 77e47398c4..6f3a624cf7 100644 > > --- a/include/net/vhost_net.h > > +++ b/include/net/vhost_net.h > > @@ -39,5 +39,6 @@ int vhost_set_vring_enable(NetClientState * nc, int enable); > > uint64_t vhost_net_get_acked_features(VHostNetState *net); > > > > int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu); > > +int vhost_set_state(NetClientState *nc, int state); > > > > #endif > > diff --git a/net/Makefile.objs b/net/Makefile.objs > > index c5d076d19c..da459cfc19 100644 > > --- a/net/Makefile.objs > > +++ b/net/Makefile.objs > > @@ -26,7 +26,7 @@ tap-obj-$(CONFIG_SOLARIS) = tap-solaris.o > > tap-obj-y ?= tap-stub.o > > common-obj-$(CONFIG_POSIX) += tap.o $(tap-obj-y) > > common-obj-$(CONFIG_WIN32) += tap-win32.o > > - > > +common-obj-$(CONFIG_VHOST_KERNEL) += vhost-vdpa.o > > should it be CONFIG_VHOST_NET_USER as you use net_init_vhost_vdpa() > below inside a "#ifdef CONFIG_VHOST_NET_USER"? > > Why don't you define a CONFIG_VHOST_VDPA? > Thanks Laurent for point it out, There is no dependence between CONFIG_VHOST_NET_USER and vDPA, So I will implement a new macro specific for vDPA > > vde.o-libs = $(VDE_LIBS) > > > > common-obj-$(CONFIG_CAN_BUS) += can/ > > diff --git a/net/clients.h b/net/clients.h > > index a6ef267e19..92f9b59aed 100644 > > --- a/net/clients.h > > +++ b/net/clients.h > > @@ -61,4 +61,6 @@ int net_init_netmap(const Netdev *netdev, const char *name, > > int net_init_vhost_user(const Netdev *netdev, const char *name, > > NetClientState *peer, Error **errp); > > > > +int net_init_vhost_vdpa(const Netdev *netdev, const char *name, > > + NetClientState *peer, Error **errp); > > #endif /* QEMU_NET_CLIENTS_H */ > > diff --git a/net/net.c b/net/net.c > > index ac5080dda1..2beb95388a 100644 > > --- a/net/net.c > > +++ b/net/net.c > > @@ -964,6 +964,7 @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])( > > [NET_CLIENT_DRIVER_HUBPORT] = net_init_hubport, > > #ifdef CONFIG_VHOST_NET_USER ^^^^^^^^^^^^^^^^^^^^^ > here > > > [NET_CLIENT_DRIVER_VHOST_USER] = net_init_vhost_user, > > + [NET_CLIENT_DRIVER_VHOST_VDPA] = net_init_vhost_vdpa, > > #endif > > #ifdef CONFIG_L2TPV3 > > [NET_CLIENT_DRIVER_L2TPV3] = net_init_l2tpv3, > > diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c > > new file mode 100644 > > index 0000000000..5daeba0b76 > > --- /dev/null > > +++ b/net/vhost-vdpa.c > ... > > +static int net_vhost_check_net(void *opaque, QemuOpts *opts, Error **errp) > > +{ > > + const char *name = opaque; > > + const char *driver, *netdev; > > + > > + driver = qemu_opt_get(opts, "driver"); > > + netdev = qemu_opt_get(opts, "netdev"); > > + > > + if (!driver || !netdev) { > > + return 0; > > + } > > + > > + if (strcmp(netdev, name) == 0 && > > + !g_str_has_prefix(driver, "virtio-net-")) { > > + error_setg(errp, "vhost-vdpa requires frontend driver virtio-net-*"); > > + return -1; > > + } > > > > So perhaps you can build the file only if CONFIG_VIRTIO_NET is set? > > Thanks, > Laurent > Thanks, There will be a new macro specific for vDPA
diff --git a/include/net/vhost-vdpa.h b/include/net/vhost-vdpa.h new file mode 100644 index 0000000000..9ddd538dad --- /dev/null +++ b/include/net/vhost-vdpa.h @@ -0,0 +1,18 @@ +/* + * vhost-vdpa.h + * + * Copyright(c) 2017 Intel Corporation. All rights reserved. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef VHOST_VDPA_H +#define VHOST_VDPA_H + +struct vhost_net; +struct vhost_net *vhost_vdpa_get_vhost_net(NetClientState *nc); +uint64_t vhost_vdpa_get_acked_features(NetClientState *nc); + +#endif /* VHOST_VDPA_H */ diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h index 77e47398c4..6f3a624cf7 100644 --- a/include/net/vhost_net.h +++ b/include/net/vhost_net.h @@ -39,5 +39,6 @@ int vhost_set_vring_enable(NetClientState * nc, int enable); uint64_t vhost_net_get_acked_features(VHostNetState *net); int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu); +int vhost_set_state(NetClientState *nc, int state); #endif diff --git a/net/Makefile.objs b/net/Makefile.objs index c5d076d19c..da459cfc19 100644 --- a/net/Makefile.objs +++ b/net/Makefile.objs @@ -26,7 +26,7 @@ tap-obj-$(CONFIG_SOLARIS) = tap-solaris.o tap-obj-y ?= tap-stub.o common-obj-$(CONFIG_POSIX) += tap.o $(tap-obj-y) common-obj-$(CONFIG_WIN32) += tap-win32.o - +common-obj-$(CONFIG_VHOST_KERNEL) += vhost-vdpa.o vde.o-libs = $(VDE_LIBS) common-obj-$(CONFIG_CAN_BUS) += can/ diff --git a/net/clients.h b/net/clients.h index a6ef267e19..92f9b59aed 100644 --- a/net/clients.h +++ b/net/clients.h @@ -61,4 +61,6 @@ int net_init_netmap(const Netdev *netdev, const char *name, int net_init_vhost_user(const Netdev *netdev, const char *name, NetClientState *peer, Error **errp); +int net_init_vhost_vdpa(const Netdev *netdev, const char *name, + NetClientState *peer, Error **errp); #endif /* QEMU_NET_CLIENTS_H */ diff --git a/net/net.c b/net/net.c index ac5080dda1..2beb95388a 100644 --- a/net/net.c +++ b/net/net.c @@ -964,6 +964,7 @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])( [NET_CLIENT_DRIVER_HUBPORT] = net_init_hubport, #ifdef CONFIG_VHOST_NET_USER [NET_CLIENT_DRIVER_VHOST_USER] = net_init_vhost_user, + [NET_CLIENT_DRIVER_VHOST_VDPA] = net_init_vhost_vdpa, #endif #ifdef CONFIG_L2TPV3 [NET_CLIENT_DRIVER_L2TPV3] = net_init_l2tpv3, diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c new file mode 100644 index 0000000000..5daeba0b76 --- /dev/null +++ b/net/vhost-vdpa.c @@ -0,0 +1,211 @@ +/* + * vhost-vdpa.c + * + * Copyright(c) 2017-2018 Intel Corporation. All rights reserved. + * Copyright(c) 2020 Red Hat, Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "clients.h" +#include "net/vhost_net.h" +#include "net/vhost-vdpa.h" +#include "hw/virtio/vhost-vdpa.h" +#include "chardev/char-fe.h" +#include "qemu/config-file.h" +#include "qemu/error-report.h" +#include "qemu/option.h" +#include "qapi/error.h" +#include "trace.h" +#include <linux/vfio.h> +#include <sys/ioctl.h> +#include <err.h> +#include <linux/virtio_net.h> + + +typedef struct VhostVDPAState { + NetClientState nc; + struct vhost_vdpa vhost_vdpa; + VHostNetState *vhost_net; + uint64_t acked_features; + bool started; +} VhostVDPAState; + +VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc) +{ + VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); + assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); + return s->vhost_net; +} + +uint64_t vhost_vdpa_get_acked_features(NetClientState *nc) +{ + VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); + assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); + return s->acked_features; +} + +static void vhost_vdpa_stop(NetClientState *ncs) +{ + VhostVDPAState *s; + + assert(ncs->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); + + s = DO_UPCAST(VhostVDPAState, nc, ncs); + + if (s->vhost_net) { + /* save acked features */ + uint64_t features = vhost_net_get_acked_features(s->vhost_net); + if (features) { + s->acked_features = features; + } + vhost_net_cleanup(s->vhost_net); + } +} + +static int vhost_vdpa_start(NetClientState *ncs, void *be) +{ + VhostNetOptions options; + struct vhost_net *net = NULL; + VhostVDPAState *s; + + options.backend_type = VHOST_BACKEND_TYPE_VDPA; + + assert(ncs->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); + + s = DO_UPCAST(VhostVDPAState, nc, ncs); + + options.net_backend = ncs; + options.opaque = be; + options.busyloop_timeout = 0; + net = vhost_net_init(&options); + if (!net) { + error_report("failed to init vhost_net for queue"); + goto err; + } + + if (s->vhost_net) { + vhost_net_cleanup(s->vhost_net); + g_free(s->vhost_net); + } + s->vhost_net = net; + + return 0; + +err: + if (net) { + vhost_net_cleanup(net); + } + vhost_vdpa_stop(ncs); + return -1; +} +static void vhost_vdpa_cleanup(NetClientState *nc) +{ + VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); + + if (s->vhost_net) { + vhost_net_cleanup(s->vhost_net); + g_free(s->vhost_net); + s->vhost_net = NULL; + } + + qemu_purge_queued_packets(nc); +} + +static bool vhost_vdpa_has_vnet_hdr(NetClientState *nc) +{ + assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); + + return true; +} + +static bool vhost_vdpa_has_ufo(NetClientState *nc) +{ + assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); + VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); + uint64_t features = 0; + + features |= (1ULL << VIRTIO_NET_F_HOST_UFO); + features = vhost_net_get_features(s->vhost_net, features); + return !!(features & (1ULL << VIRTIO_NET_F_HOST_UFO)); + +} + +static NetClientInfo net_vhost_vdpa_info = { + .type = NET_CLIENT_DRIVER_VHOST_VDPA, + .size = sizeof(VhostVDPAState), + .cleanup = vhost_vdpa_cleanup, + .has_vnet_hdr = vhost_vdpa_has_vnet_hdr, + .has_ufo = vhost_vdpa_has_ufo, +}; + +static int net_vhost_vdpa_init(NetClientState *peer, const char *device, + const char *name, const char *vhostdev) +{ + NetClientState *nc = NULL; + VhostVDPAState *s; + int vdpa_device_fd; + assert(name); + + nc = qemu_new_net_client(&net_vhost_vdpa_info, peer, device, name); + snprintf(nc->info_str, sizeof(nc->info_str), "vhost-vdpa"); + nc->queue_index = 0; + + s = DO_UPCAST(VhostVDPAState, nc, nc); + + vdpa_device_fd = open(vhostdev, O_RDWR); + if (vdpa_device_fd == -1) { + return -errno; + } + s->vhost_vdpa.device_fd = vdpa_device_fd; + vhost_vdpa_start(nc, (void *)&s->vhost_vdpa); + + assert(s->vhost_net); + + return 0; +} + +static int net_vhost_check_net(void *opaque, QemuOpts *opts, Error **errp) +{ + const char *name = opaque; + const char *driver, *netdev; + + driver = qemu_opt_get(opts, "driver"); + netdev = qemu_opt_get(opts, "netdev"); + + if (!driver || !netdev) { + return 0; + } + + if (strcmp(netdev, name) == 0 && + !g_str_has_prefix(driver, "virtio-net-")) { + error_setg(errp, "vhost-vdpa requires frontend driver virtio-net-*"); + return -1; + } + + return 0; +} + +int net_init_vhost_vdpa(const Netdev *netdev, const char *name, + NetClientState *peer, Error **errp) +{ + const NetdevVhostVDPAOptions *vhost_vdpa_opts; + + assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA); + vhost_vdpa_opts = &netdev->u.vhost_vdpa; + + /* verify net frontend */ + if (qemu_opts_foreach(qemu_find_opts("device"), net_vhost_check_net, + (char *)name, errp)) { + return -1; + } + + + return net_vhost_vdpa_init(peer, "vhost_vdpa", name, + vhost_vdpa_opts->vhostdev); + + return 0; +} diff --git a/qapi/net.json b/qapi/net.json index 335295be50..35a5ccee39 100644 --- a/qapi/net.json +++ b/qapi/net.json @@ -441,6 +441,22 @@ '*queues': 'int' } } ## +# @NetdevVhostVDPAOptions: +# +# Vhost-vdpa network backend +# +# @vhostdev: name of a mdev dev path in sysfs +# +# @queues: number of queues to be created for multiqueue vhost-vdpa +# (default: 1) (Since 2.11) +# +# Since: 2.11 +## +{ 'struct': 'NetdevVhostVDPAOptions', + 'data': { + '*vhostdev': 'str', + '*queues': 'int' } } +## # @NetClientDriver: # # Available netdev drivers. @@ -451,7 +467,7 @@ ## { 'enum': 'NetClientDriver', 'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde', - 'bridge', 'hubport', 'netmap', 'vhost-user' ] } + 'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa' ] } ## # @Netdev: @@ -479,7 +495,8 @@ 'bridge': 'NetdevBridgeOptions', 'hubport': 'NetdevHubPortOptions', 'netmap': 'NetdevNetmapOptions', - 'vhost-user': 'NetdevVhostUserOptions' } } + 'vhost-user': 'NetdevVhostUserOptions', + 'vhost-vdpa': 'NetdevVhostVDPAOptions' } } ## # @NetLegacy:
This patch set introduces a new net client type: vhost-vdpa. vhost-vdpa net client will set up a vDPA device which is svhostdevpecified by a "vhostdev" parameter. Author: Tiwei Bie Signed-off-by: Cindy Lu <lulu@redhat.com> --- include/net/vhost-vdpa.h | 18 ++++ include/net/vhost_net.h | 1 + net/Makefile.objs | 2 +- net/clients.h | 2 + net/net.c | 1 + net/vhost-vdpa.c | 211 +++++++++++++++++++++++++++++++++++++++ qapi/net.json | 21 +++- 7 files changed, 253 insertions(+), 3 deletions(-) create mode 100644 include/net/vhost-vdpa.h create mode 100644 net/vhost-vdpa.c