From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 3ABA8A04B5; Wed, 13 Jan 2021 14:57:39 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id AF89C140D29; Wed, 13 Jan 2021 14:57:38 +0100 (CET) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by mails.dpdk.org (Postfix) with ESMTP id 1D310140D28 for ; Wed, 13 Jan 2021 14:57:36 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1610546256; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wXZjZnWu2dErInXUfwd6HRoWbo7uRXqQaXLzj0srrkw=; b=fNoWQEWZrkWbIFFic2zII6BMyulH88hU2TtTS0VmYtAusj2FpLc0RcgqbJcsR6qjT++eIq pZSWD1ZysNWk8SM9nLSHnnFp9As+TWly/pn2xULohSMht+XrzD3yDyfMTEYdYw+t9+oyuj nsI5psD9PUbzQ5mqzo6KOSg3zSY8w3I= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-49-scrvRev1MnezJIkj6RF_bg-1; Wed, 13 Jan 2021 08:57:34 -0500 X-MC-Unique: scrvRev1MnezJIkj6RF_bg-1 Received: by mail-wr1-f70.google.com with SMTP id o12so988296wrq.13 for ; Wed, 13 Jan 2021 05:57:31 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=wXZjZnWu2dErInXUfwd6HRoWbo7uRXqQaXLzj0srrkw=; b=ilEIjAxIBaluB5cV4cwg1eyjtX7cn6nQ5mVLDEcyi0qWRqMWAqIAJtmfU4fYcBlWDS N6jrQK95/DmhpOMoxWoQNEK7IeQAPy4FjLWeMxZwmkXFXkkTQ/xAlU8nDaA9LoD4Q7wg g3OIYLRlAcWd7AC5zMP7i/Zq9ZzUmvqbYTiXPy+Pds/jQa47X4Erp4Ugo11bVGji4xDn R3Cjpc8cRjSA1bAE/L2yCc3qvuFFgMC4JT705tbH/0d2y5WpckyNxbpsb9g4iKHeD+Hi 4cR3fn9Bx0qp5ReU3P4Asj1o+mA17J6KyN5BcmnehbUq/9baeRoQyvmh4ycKDrS7c58t BieA== X-Gm-Message-State: AOAM531W8P2YA5uXcerv5Q2PwkE8eP6J+W04krta1NAOoBY+BRUb3G4y TgOe+El16r6rPrOqW4Te01/jvqS2Du/ZLmP805L4Gkv+ft3OVncSaymJPZ5NaZVENcXOvJd6liS tbo0= X-Received: by 2002:a7b:c4c7:: with SMTP id g7mr2370100wmk.29.1610546250550; Wed, 13 Jan 2021 05:57:30 -0800 (PST) X-Google-Smtp-Source: ABdhPJw+fv84CaeA5flGdqSGCAS65BPoC+hiRq2uEDbYnV2tYYkbCSy7pgwbbQnBYNVZIhIeAz2Ijw== X-Received: by 2002:a7b:c4c7:: with SMTP id g7mr2370067wmk.29.1610546250158; Wed, 13 Jan 2021 05:57:30 -0800 (PST) Received: from amorenoz.users.ipa.redhat.com ([94.73.56.18]) by smtp.gmail.com with ESMTPSA id i9sm3457895wrs.70.2021.01.13.05.57.29 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 13 Jan 2021 05:57:29 -0800 (PST) To: Maxime Coquelin , dev@dpdk.org, chenbo.xia@intel.com, olivier.matz@6wind.com, david.marchand@redhat.com References: <20201220211405.313012-1-maxime.coquelin@redhat.com> <20201220211405.313012-26-maxime.coquelin@redhat.com> From: Adrian Moreno Message-ID: <3dc4e2f1-b761-9a1b-1271-afdf43201095@redhat.com> Date: Wed, 13 Jan 2021 14:57:28 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.6.0 MIME-Version: 1.0 In-Reply-To: <20201220211405.313012-26-maxime.coquelin@redhat.com> Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=amorenoz@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit Subject: Re: [dpdk-dev] [PATCH 25/40] net/virtio: add Virtio-user features ops X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" On 12/20/20 10:13 PM, Maxime Coquelin wrote: > This patch introduce new callbacks for getting > and setting Virtio features, and implements them > for the different backend types. > > Signed-off-by: Maxime Coquelin > --- > drivers/net/virtio/virtio_user/vhost.h | 2 + > drivers/net/virtio/virtio_user/vhost_kernel.c | 150 +++++++++--------- > .../net/virtio/virtio_user/vhost_kernel_tap.c | 23 +++ > .../net/virtio/virtio_user/vhost_kernel_tap.h | 1 + > drivers/net/virtio/virtio_user/vhost_user.c | 63 +++++++- > drivers/net/virtio/virtio_user/vhost_vdpa.c | 38 +++-- > .../net/virtio/virtio_user/virtio_user_dev.c | 5 +- > drivers/net/virtio/virtio_user_ethdev.c | 3 +- > 8 files changed, 188 insertions(+), 97 deletions(-) > > diff --git a/drivers/net/virtio/virtio_user/vhost.h b/drivers/net/virtio/virtio_user/vhost.h > index 8e819ecfb8..16978e27ed 100644 > --- a/drivers/net/virtio/virtio_user/vhost.h > +++ b/drivers/net/virtio/virtio_user/vhost.h > @@ -102,6 +102,8 @@ struct virtio_user_dev; > struct virtio_user_backend_ops { > int (*setup)(struct virtio_user_dev *dev); > int (*set_owner)(struct virtio_user_dev *dev); > + int (*get_features)(struct virtio_user_dev *dev, uint64_t *features); > + int (*set_features)(struct virtio_user_dev *dev, uint64_t features); > int (*send_request)(struct virtio_user_dev *dev, > enum vhost_user_request req, > void *arg); > diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c b/drivers/net/virtio/virtio_user/vhost_kernel.c > index b79dcad179..f44df8ef1f 100644 > --- a/drivers/net/virtio/virtio_user/vhost_kernel.c > +++ b/drivers/net/virtio/virtio_user/vhost_kernel.c > @@ -38,6 +38,28 @@ struct vhost_memory_kernel { > #define VHOST_SET_VRING_ERR _IOW(VHOST_VIRTIO, 0x22, struct vhost_vring_file) > #define VHOST_NET_SET_BACKEND _IOW(VHOST_VIRTIO, 0x30, struct vhost_vring_file) > > +/* with below features, vhost kernel does not need to do the checksum and TSO, > + * these info will be passed to virtio_user through virtio net header. > + */ > +#define VHOST_KERNEL_GUEST_OFFLOADS_MASK \ > + ((1ULL << VIRTIO_NET_F_GUEST_CSUM) | \ > + (1ULL << VIRTIO_NET_F_GUEST_TSO4) | \ > + (1ULL << VIRTIO_NET_F_GUEST_TSO6) | \ > + (1ULL << VIRTIO_NET_F_GUEST_ECN) | \ > + (1ULL << VIRTIO_NET_F_GUEST_UFO)) > + > +/* with below features, when flows from virtio_user to vhost kernel > + * (1) if flows goes up through the kernel networking stack, it does not need > + * to verify checksum, which can save CPU cycles; > + * (2) if flows goes through a Linux bridge and outside from an interface > + * (kernel driver), checksum and TSO will be done by GSO in kernel or even > + * offloaded into real physical device. > + */ > +#define VHOST_KERNEL_HOST_OFFLOADS_MASK \ nit: backslash alignment > + ((1ULL << VIRTIO_NET_F_HOST_TSO4) | \ > + (1ULL << VIRTIO_NET_F_HOST_TSO6) | \ > + (1ULL << VIRTIO_NET_F_CSUM)) > + > static uint64_t max_regions = 64; > > static void > @@ -77,10 +99,57 @@ vhost_kernel_set_owner(struct virtio_user_dev *dev) > return vhost_kernel_ioctl(dev->vhostfds[0], VHOST_SET_OWNER, NULL); > } > > +static int > +vhost_kernel_get_features(struct virtio_user_dev *dev, uint64_t *features) > +{ > + int ret; > + unsigned int tap_features; > + > + ret = vhost_kernel_ioctl(dev->vhostfds[0], VHOST_GET_FEATURES, features); > + if (ret < 0) { > + PMD_DRV_LOG(ERR, "Failed to get features"); > + return -1; > + } > + > + ret = tap_support_features(&tap_features); > + if (ret < 0) { > + PMD_DRV_LOG(ERR, "Failed to get TAP features)"); > + return -1; > + } > + > + /* with tap as the backend, all these features are supported > + * but not claimed by vhost-net, so we add them back when > + * reporting to upper layer. > + */ > + if (tap_features & IFF_VNET_HDR) { > + *features |= VHOST_KERNEL_GUEST_OFFLOADS_MASK; > + *features |= VHOST_KERNEL_HOST_OFFLOADS_MASK; > + } > + > + /* vhost_kernel will not declare this feature, but it does > + * support multi-queue. > + */ > + if (tap_features & IFF_MULTI_QUEUE) > + *features |= (1ull << VIRTIO_NET_F_MQ); > + > + return 0; > +} > + > +static int > +vhost_kernel_set_features(struct virtio_user_dev *dev, uint64_t features) > +{ > + /* We don't need memory protection here */ > + features &= ~(1ULL << VIRTIO_F_IOMMU_PLATFORM); > + /* VHOST kernel does not know about below flags */ > + features &= ~VHOST_KERNEL_GUEST_OFFLOADS_MASK; > + features &= ~VHOST_KERNEL_HOST_OFFLOADS_MASK; > + features &= ~(1ULL << VIRTIO_NET_F_MQ); > + > + return vhost_kernel_ioctl(dev->vhostfds[0], VHOST_SET_FEATURES, &features); > +} > + > static uint64_t vhost_req_user_to_kernel[] = { > [VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER, > - [VHOST_USER_SET_FEATURES] = VHOST_SET_FEATURES, > - [VHOST_USER_GET_FEATURES] = VHOST_GET_FEATURES, > [VHOST_USER_SET_VRING_CALL] = VHOST_SET_VRING_CALL, > [VHOST_USER_SET_VRING_NUM] = VHOST_SET_VRING_NUM, > [VHOST_USER_SET_VRING_BASE] = VHOST_SET_VRING_BASE, > @@ -150,51 +219,6 @@ prepare_vhost_memory_kernel(void) > return vm; > } > > -/* with below features, vhost kernel does not need to do the checksum and TSO, > - * these info will be passed to virtio_user through virtio net header. > - */ > -#define VHOST_KERNEL_GUEST_OFFLOADS_MASK \ > - ((1ULL << VIRTIO_NET_F_GUEST_CSUM) | \ > - (1ULL << VIRTIO_NET_F_GUEST_TSO4) | \ > - (1ULL << VIRTIO_NET_F_GUEST_TSO6) | \ > - (1ULL << VIRTIO_NET_F_GUEST_ECN) | \ > - (1ULL << VIRTIO_NET_F_GUEST_UFO)) > - > -/* with below features, when flows from virtio_user to vhost kernel > - * (1) if flows goes up through the kernel networking stack, it does not need > - * to verify checksum, which can save CPU cycles; > - * (2) if flows goes through a Linux bridge and outside from an interface > - * (kernel driver), checksum and TSO will be done by GSO in kernel or even > - * offloaded into real physical device. > - */ > -#define VHOST_KERNEL_HOST_OFFLOADS_MASK \ > - ((1ULL << VIRTIO_NET_F_HOST_TSO4) | \ > - (1ULL << VIRTIO_NET_F_HOST_TSO6) | \ > - (1ULL << VIRTIO_NET_F_CSUM)) > - > -static unsigned int > -tap_support_features(void) > -{ > - int tapfd; > - unsigned int tap_features; > - > - tapfd = open(PATH_NET_TUN, O_RDWR); > - if (tapfd < 0) { > - PMD_DRV_LOG(ERR, "fail to open %s: %s", > - PATH_NET_TUN, strerror(errno)); > - return -1; > - } > - > - if (ioctl(tapfd, TUNGETFEATURES, &tap_features) == -1) { > - PMD_DRV_LOG(ERR, "TUNGETFEATURES failed: %s", strerror(errno)); > - close(tapfd); > - return -1; > - } > - > - close(tapfd); > - return tap_features; > -} > - > static int > vhost_kernel_send_request(struct virtio_user_dev *dev, > enum vhost_user_request req, > @@ -206,7 +230,6 @@ vhost_kernel_send_request(struct virtio_user_dev *dev, > struct vhost_memory_kernel *vm = NULL; > int vhostfd; > unsigned int queue_sel; > - unsigned int features; > > PMD_DRV_LOG(INFO, "%s", vhost_msg_strings[req]); > > @@ -219,17 +242,6 @@ vhost_kernel_send_request(struct virtio_user_dev *dev, > arg = (void *)vm; > } > > - if (req_kernel == VHOST_SET_FEATURES) { > - /* We don't need memory protection here */ > - *(uint64_t *)arg &= ~(1ULL << VIRTIO_F_IOMMU_PLATFORM); > - > - /* VHOST kernel does not know about below flags */ > - *(uint64_t *)arg &= ~VHOST_KERNEL_GUEST_OFFLOADS_MASK; > - *(uint64_t *)arg &= ~VHOST_KERNEL_HOST_OFFLOADS_MASK; > - > - *(uint64_t *)arg &= ~(1ULL << VIRTIO_NET_F_MQ); > - } > - > switch (req_kernel) { > case VHOST_SET_VRING_NUM: > case VHOST_SET_VRING_ADDR: > @@ -259,24 +271,6 @@ vhost_kernel_send_request(struct virtio_user_dev *dev, > ret = ioctl(vhostfd, req_kernel, arg); > } > > - if (!ret && req_kernel == VHOST_GET_FEATURES) { > - features = tap_support_features(); > - /* with tap as the backend, all these features are supported > - * but not claimed by vhost-net, so we add them back when > - * reporting to upper layer. > - */ > - if (features & IFF_VNET_HDR) { > - *((uint64_t *)arg) |= VHOST_KERNEL_GUEST_OFFLOADS_MASK; > - *((uint64_t *)arg) |= VHOST_KERNEL_HOST_OFFLOADS_MASK; > - } > - > - /* vhost_kernel will not declare this feature, but it does > - * support multi-queue. > - */ > - if (features & IFF_MULTI_QUEUE) > - *(uint64_t *)arg |= (1ull << VIRTIO_NET_F_MQ); > - } > - > if (vm) > free(vm); > > @@ -407,6 +401,8 @@ vhost_kernel_enable_queue_pair(struct virtio_user_dev *dev, > struct virtio_user_backend_ops virtio_ops_kernel = { > .setup = vhost_kernel_setup, > .set_owner = vhost_kernel_set_owner, > + .get_features = vhost_kernel_get_features, > + .set_features = vhost_kernel_set_features, > .send_request = vhost_kernel_send_request, > .enable_qp = vhost_kernel_enable_queue_pair > }; > diff --git a/drivers/net/virtio/virtio_user/vhost_kernel_tap.c b/drivers/net/virtio/virtio_user/vhost_kernel_tap.c > index eade702c5c..99096bdf39 100644 > --- a/drivers/net/virtio/virtio_user/vhost_kernel_tap.c > +++ b/drivers/net/virtio/virtio_user/vhost_kernel_tap.c > @@ -18,6 +18,29 @@ > #include "../virtio_logs.h" > #include "../virtio.h" > > + > +int > +tap_support_features(unsigned int *tap_features) > +{ > + int tapfd; > + > + tapfd = open(PATH_NET_TUN, O_RDWR); > + if (tapfd < 0) { > + PMD_DRV_LOG(ERR, "fail to open %s: %s", > + PATH_NET_TUN, strerror(errno)); > + return -1; > + } > + > + if (ioctl(tapfd, TUNGETFEATURES, tap_features) == -1) { > + PMD_DRV_LOG(ERR, "TUNGETFEATURES failed: %s", strerror(errno)); > + close(tapfd); > + return -1; > + } > + > + close(tapfd); > + return 0; > +} > + > int > vhost_kernel_tap_set_offload(int fd, uint64_t features) > { > diff --git a/drivers/net/virtio/virtio_user/vhost_kernel_tap.h b/drivers/net/virtio/virtio_user/vhost_kernel_tap.h > index 5c4447b296..ed03fce21e 100644 > --- a/drivers/net/virtio/virtio_user/vhost_kernel_tap.h > +++ b/drivers/net/virtio/virtio_user/vhost_kernel_tap.h > @@ -43,5 +43,6 @@ int vhost_kernel_open_tap(char **p_ifname, int hdr_size, int req_mq, > const char *mac, uint64_t features); > int vhost_kernel_tap_set_offload(int fd, uint64_t features); > int vhost_kernel_tap_set_queue(int fd, bool attach); > +int tap_support_features(unsigned int *tap_features); > > #endif > diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c > index 5ab15318ac..d204fa1eb0 100644 > --- a/drivers/net/virtio/virtio_user/vhost_user.c > +++ b/drivers/net/virtio/virtio_user/vhost_user.c > @@ -143,6 +143,62 @@ vhost_user_set_owner(struct virtio_user_dev *dev) > return 0; > } > > +static int > +vhost_user_get_features(struct virtio_user_dev *dev, uint64_t *features) > +{ > + int ret; > + struct vhost_user_msg msg = { > + .request = VHOST_USER_GET_FEATURES, > + .flags = VHOST_USER_VERSION, > + }; > + > + ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0); > + if (ret < 0) > + goto err; > + > + ret = vhost_user_read(dev->vhostfd, &msg); > + if (ret < 0) > + goto err; > + > + if (msg.request != VHOST_USER_GET_FEATURES) { > + PMD_DRV_LOG(ERR, "Unexpected request type (%d)", msg.request); > + goto err; > + } > + > + if (msg.size != sizeof(*features)) { > + PMD_DRV_LOG(ERR, "Unexpected payload size (%d)", msg.size); > + goto err; > + } > + > + *features = msg.payload.u64; > + > + return 0; > +err: > + PMD_DRV_LOG(ERR, "Failed to get backend features"); > + On possibly socket-related errors, it's sometimes useful to print sterror(errno). WDYT? > + return -1; > +} > + > +static int > +vhost_user_set_features(struct virtio_user_dev *dev, uint64_t features) > +{ > + int ret; > + struct vhost_user_msg msg = { > + .request = VHOST_USER_SET_FEATURES, > + .flags = VHOST_USER_VERSION, > + .size = sizeof(features), > + .payload.u64 = features, > + }; > + > + ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0); > + if (ret < 0) { > + PMD_DRV_LOG(ERR, "Failed to set features"); > + return -1; > + } > + > + return 0; > +} > + > struct walk_arg { > struct vhost_memory *vm; > int *fds; > @@ -249,8 +305,6 @@ static struct vhost_user_msg m; > > const char * const vhost_msg_strings[] = { > [VHOST_USER_RESET_OWNER] = "VHOST_RESET_OWNER", > - [VHOST_USER_SET_FEATURES] = "VHOST_SET_FEATURES", > - [VHOST_USER_GET_FEATURES] = "VHOST_GET_FEATURES", > [VHOST_USER_SET_VRING_CALL] = "VHOST_SET_VRING_CALL", > [VHOST_USER_SET_VRING_NUM] = "VHOST_SET_VRING_NUM", > [VHOST_USER_SET_VRING_BASE] = "VHOST_SET_VRING_BASE", > @@ -299,7 +353,6 @@ vhost_user_sock(struct virtio_user_dev *dev, > (1ULL << VHOST_USER_PROTOCOL_F_STATUS)))) > return -ENOTSUP; > /* Fallthrough */ > - case VHOST_USER_GET_FEATURES: > case VHOST_USER_GET_PROTOCOL_FEATURES: > need_reply = 1; > break; > @@ -313,7 +366,6 @@ vhost_user_sock(struct virtio_user_dev *dev, > if (has_reply_ack) > msg.flags |= VHOST_USER_NEED_REPLY_MASK; > /* Fallthrough */ > - case VHOST_USER_SET_FEATURES: > case VHOST_USER_SET_PROTOCOL_FEATURES: > case VHOST_USER_SET_LOG_BASE: > msg.payload.u64 = *((__u64 *)arg); > @@ -393,7 +445,6 @@ vhost_user_sock(struct virtio_user_dev *dev, > } > > switch (req) { > - case VHOST_USER_GET_FEATURES: > case VHOST_USER_GET_STATUS: > case VHOST_USER_GET_PROTOCOL_FEATURES: > if (msg.size != sizeof(m.payload.u64)) { > @@ -531,6 +582,8 @@ vhost_user_enable_queue_pair(struct virtio_user_dev *dev, > struct virtio_user_backend_ops virtio_ops_user = { > .setup = vhost_user_setup, > .set_owner = vhost_user_set_owner, > + .get_features = vhost_user_get_features, > + .set_features = vhost_user_set_features, > .send_request = vhost_user_sock, > .enable_qp = vhost_user_enable_queue_pair > }; > diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c b/drivers/net/virtio/virtio_user/vhost_vdpa.c > index f405b6b86a..c0a9b5b767 100644 > --- a/drivers/net/virtio/virtio_user/vhost_vdpa.c > +++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c > @@ -38,8 +38,6 @@ > > static uint64_t vhost_req_user_to_vdpa[] = { > [VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER, > - [VHOST_USER_SET_FEATURES] = VHOST_SET_FEATURES, > - [VHOST_USER_GET_FEATURES] = VHOST_GET_FEATURES, > [VHOST_USER_SET_VRING_CALL] = VHOST_SET_VRING_CALL, > [VHOST_USER_SET_VRING_NUM] = VHOST_SET_VRING_NUM, > [VHOST_USER_SET_VRING_BASE] = VHOST_SET_VRING_BASE, > @@ -101,6 +99,32 @@ vhost_vdpa_set_owner(struct virtio_user_dev *dev) > return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_OWNER, NULL); > } > > +static int > +vhost_vdpa_get_features(struct virtio_user_dev *dev, uint64_t *features) > +{ > + int ret; > + > + ret = vhost_vdpa_ioctl(dev->vhostfd, VHOST_GET_FEATURES, features); > + if (ret) { > + PMD_DRV_LOG(ERR, "Failed to get features"); > + return -1; > + } > + > + /* Multiqueue not supported for now */ > + *features &= ~(1ULL << VIRTIO_NET_F_MQ); > + > + return 0; > +} > + > +static int > +vhost_vdpa_set_features(struct virtio_user_dev *dev, uint64_t features) > +{ > + /* WORKAROUND */ > + features |= 1ULL << VIRTIO_F_IOMMU_PLATFORM; > + > + return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_FEATURES, &features); > +} > + > static int > vhost_vdpa_dma_map(struct virtio_user_dev *dev, void *addr, > uint64_t iova, size_t len) > @@ -227,14 +251,6 @@ vhost_vdpa_send_request(struct virtio_user_dev *dev, > if (req_vdpa == VHOST_SET_MEM_TABLE) > return vhost_vdpa_dma_map_all(dev); > > - if (req_vdpa == VHOST_SET_FEATURES) { > - /* WORKAROUND */ > - *(uint64_t *)arg |= 1ULL << VIRTIO_F_IOMMU_PLATFORM; > - > - /* Multiqueue not supported for now */ > - *(uint64_t *)arg &= ~(1ULL << VIRTIO_NET_F_MQ); > - } > - > switch (req_vdpa) { > case VHOST_SET_VRING_NUM: > case VHOST_SET_VRING_ADDR: > @@ -313,6 +329,8 @@ vhost_vdpa_enable_queue_pair(struct virtio_user_dev *dev, > struct virtio_user_backend_ops virtio_ops_vdpa = { > .setup = vhost_vdpa_setup, > .set_owner = vhost_vdpa_set_owner, > + .get_features = vhost_vdpa_get_features, > + .set_features = vhost_vdpa_set_features, > .send_request = vhost_vdpa_send_request, > .enable_qp = vhost_vdpa_enable_queue_pair, > .dma_map = vhost_vdpa_dma_map, > diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c > index f8e4581951..0a85d058a8 100644 > --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c > +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c > @@ -141,7 +141,7 @@ virtio_user_dev_set_features(struct virtio_user_dev *dev) > /* Strip VIRTIO_NET_F_CTRL_VQ, as devices do not really need to know */ > features &= ~(1ull << VIRTIO_NET_F_CTRL_VQ); > features &= ~(1ull << VIRTIO_NET_F_STATUS); > - ret = dev->ops->send_request(dev, VHOST_USER_SET_FEATURES, &features); > + ret = dev->ops->set_features(dev, features); > if (ret < 0) > goto error; > PMD_DRV_LOG(INFO, "set features: %" PRIx64, features); > @@ -488,8 +488,7 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues, > return -1; > } > > - if (dev->ops->send_request(dev, VHOST_USER_GET_FEATURES, > - &dev->device_features) < 0) { > + if (dev->ops->get_features(dev, &dev->device_features) < 0) { > PMD_INIT_LOG(ERR, "get_features failed: %s", > strerror(errno)); > return -1; > diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c > index 283f5c7a36..4d2635c8aa 100644 > --- a/drivers/net/virtio/virtio_user_ethdev.c > +++ b/drivers/net/virtio/virtio_user_ethdev.c > @@ -85,8 +85,7 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev) > > virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER); > > - if (dev->ops->send_request(dev, VHOST_USER_GET_FEATURES, > - &dev->device_features) < 0) { > + if (dev->ops->get_features(dev, &dev->device_features) < 0) { > PMD_INIT_LOG(ERR, "get_features failed: %s", > strerror(errno)); > return -1; > -- Adrián Moreno