From patchwork Thu Jun 18 16:28:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 71736 X-Patchwork-Delegate: maxime.coquelin@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 17A0CA04F1; Thu, 18 Jun 2020 18:28:17 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 9D2D51BFA5; Thu, 18 Jun 2020 18:28:15 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id B0EA71BFA5 for ; Thu, 18 Jun 2020 18:28:13 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from matan@mellanox.com) with SMTP; 18 Jun 2020 19:28:09 +0300 Received: from pegasus25.mtr.labs.mlnx. (pegasus25.mtr.labs.mlnx [10.210.16.10]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 05IGS9EO008363; Thu, 18 Jun 2020 19:28:09 +0300 From: Matan Azrad To: Maxime Coquelin , Xiao Wang Cc: dev@dpdk.org Date: Thu, 18 Jun 2020 16:28:03 +0000 Message-Id: <1592497686-433697-2-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1592497686-433697-1-git-send-email-matan@mellanox.com> References: <1592497686-433697-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v1 1/4] vhost: support host notifier queue configuration X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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" As an arrangement to per queue operations in the vDPA device it is needed to change the next experimental API: The API ``rte_vhost_host_notifier_ctrl`` was changed to be per queue instead of per device. A `qid` parameter was added to the API arguments list. Setting the parameter to the value VHOST_QUEUE_ALL will configure the host notifier to all the device queues as done before this patch. Signed-off-by: Matan Azrad --- doc/guides/rel_notes/release_20_08.rst | 2 ++ drivers/vdpa/ifc/ifcvf_vdpa.c | 6 +++--- drivers/vdpa/mlx5/mlx5_vdpa.c | 5 +++-- lib/librte_vhost/rte_vdpa.h | 8 ++++++-- lib/librte_vhost/rte_vhost.h | 2 ++ lib/librte_vhost/vhost.h | 3 --- lib/librte_vhost/vhost_user.c | 18 ++++++++++++++---- 7 files changed, 30 insertions(+), 14 deletions(-) diff --git a/doc/guides/rel_notes/release_20_08.rst b/doc/guides/rel_notes/release_20_08.rst index ba16d3b..9732959 100644 --- a/doc/guides/rel_notes/release_20_08.rst +++ b/doc/guides/rel_notes/release_20_08.rst @@ -111,6 +111,8 @@ API Changes Also, make sure to start the actual text at the margin. ========================================================= +* vhost: The API of ``rte_vhost_host_notifier_ctrl`` was changed to be per + queue and not per device, a qid parameter was added to the arguments list. ABI Changes ----------- diff --git a/drivers/vdpa/ifc/ifcvf_vdpa.c b/drivers/vdpa/ifc/ifcvf_vdpa.c index ec97178..336837a 100644 --- a/drivers/vdpa/ifc/ifcvf_vdpa.c +++ b/drivers/vdpa/ifc/ifcvf_vdpa.c @@ -839,7 +839,7 @@ struct internal_list { vdpa_ifcvf_stop(internal); vdpa_disable_vfio_intr(internal); - ret = rte_vhost_host_notifier_ctrl(vid, false); + ret = rte_vhost_host_notifier_ctrl(vid, VHOST_QUEUE_ALL, false); if (ret && ret != -ENOTSUP) goto error; @@ -858,7 +858,7 @@ struct internal_list { if (ret) goto stop_vf; - rte_vhost_host_notifier_ctrl(vid, true); + rte_vhost_host_notifier_ctrl(vid, VHOST_QUEUE_ALL, true); internal->sw_fallback_running = true; @@ -893,7 +893,7 @@ struct internal_list { rte_atomic32_set(&internal->dev_attached, 1); update_datapath(internal); - if (rte_vhost_host_notifier_ctrl(vid, true) != 0) + if (rte_vhost_host_notifier_ctrl(vid, VHOST_QUEUE_ALL, true) != 0) DRV_LOG(NOTICE, "vDPA (%d): software relay is used.", did); return 0; diff --git a/drivers/vdpa/mlx5/mlx5_vdpa.c b/drivers/vdpa/mlx5/mlx5_vdpa.c index 9e758b6..8ea1300 100644 --- a/drivers/vdpa/mlx5/mlx5_vdpa.c +++ b/drivers/vdpa/mlx5/mlx5_vdpa.c @@ -147,7 +147,8 @@ int ret; if (priv->direct_notifier) { - ret = rte_vhost_host_notifier_ctrl(priv->vid, false); + ret = rte_vhost_host_notifier_ctrl(priv->vid, VHOST_QUEUE_ALL, + false); if (ret != 0) { DRV_LOG(INFO, "Direct HW notifier FD cannot be " "destroyed for device %d: %d.", priv->vid, ret); @@ -155,7 +156,7 @@ } priv->direct_notifier = 0; } - ret = rte_vhost_host_notifier_ctrl(priv->vid, true); + ret = rte_vhost_host_notifier_ctrl(priv->vid, VHOST_QUEUE_ALL, true); if (ret != 0) DRV_LOG(INFO, "Direct HW notifier FD cannot be configured for" " device %d: %d.", priv->vid, ret); diff --git a/lib/librte_vhost/rte_vdpa.h b/lib/librte_vhost/rte_vdpa.h index ecb3d91..2db536c 100644 --- a/lib/librte_vhost/rte_vdpa.h +++ b/lib/librte_vhost/rte_vdpa.h @@ -202,22 +202,26 @@ struct rte_vdpa_device * int rte_vdpa_get_device_num(void); +#define VHOST_QUEUE_ALL VHOST_MAX_VRING + /** * @warning * @b EXPERIMENTAL: this API may change without prior notice * - * Enable/Disable host notifier mapping for a vdpa port. + * Enable/Disable host notifier mapping for a vdpa queue. * * @param vid * vhost device id * @param enable * true for host notifier map, false for host notifier unmap + * @param qid + * vhost queue id, VHOST_QUEUE_ALL to configure all the device queues * @return * 0 on success, -1 on failure */ __rte_experimental int -rte_vhost_host_notifier_ctrl(int vid, bool enable); +rte_vhost_host_notifier_ctrl(int vid, uint16_t qid, bool enable); /** * @warning diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h index 329ed8a..14bf7c2 100644 --- a/lib/librte_vhost/rte_vhost.h +++ b/lib/librte_vhost/rte_vhost.h @@ -107,6 +107,8 @@ #define VHOST_USER_F_PROTOCOL_FEATURES 30 #endif +#define VHOST_MAX_VRING 0x100 +#define VHOST_MAX_QUEUE_PAIRS 0x80 /** * Information relating to memory regions including offsets to diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h index 17f1e9a..28b991d 100644 --- a/lib/librte_vhost/vhost.h +++ b/lib/librte_vhost/vhost.h @@ -202,9 +202,6 @@ struct vhost_virtqueue { TAILQ_HEAD(, vhost_iotlb_entry) iotlb_pending_list; } __rte_cache_aligned; -#define VHOST_MAX_VRING 0x100 -#define VHOST_MAX_QUEUE_PAIRS 0x80 - /* Declare IOMMU related bits for older kernels */ #ifndef VIRTIO_F_IOMMU_PLATFORM diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c index 84bebad..cddfa4b 100644 --- a/lib/librte_vhost/vhost_user.c +++ b/lib/librte_vhost/vhost_user.c @@ -2960,13 +2960,13 @@ static int vhost_user_slave_set_vring_host_notifier(struct virtio_net *dev, return process_slave_message_reply(dev, &msg); } -int rte_vhost_host_notifier_ctrl(int vid, bool enable) +int rte_vhost_host_notifier_ctrl(int vid, uint16_t qid, bool enable) { struct virtio_net *dev; struct rte_vdpa_device *vdpa_dev; int vfio_device_fd, did, ret = 0; uint64_t offset, size; - unsigned int i; + unsigned int i, q_start, q_last; dev = get_device(vid); if (!dev) @@ -2990,6 +2990,16 @@ int rte_vhost_host_notifier_ctrl(int vid, bool enable) if (!vdpa_dev) return -ENODEV; + if (qid == VHOST_QUEUE_ALL) { + q_start = 0; + q_last = dev->nr_vring - 1; + } else { + if (qid >= dev->nr_vring) + return -EINVAL; + q_start = qid; + q_last = qid; + } + RTE_FUNC_PTR_OR_ERR_RET(vdpa_dev->ops->get_vfio_device_fd, -ENOTSUP); RTE_FUNC_PTR_OR_ERR_RET(vdpa_dev->ops->get_notify_area, -ENOTSUP); @@ -2998,7 +3008,7 @@ int rte_vhost_host_notifier_ctrl(int vid, bool enable) return -ENOTSUP; if (enable) { - for (i = 0; i < dev->nr_vring; i++) { + for (i = q_start; i <= q_last; i++) { if (vdpa_dev->ops->get_notify_area(vid, i, &offset, &size) < 0) { ret = -ENOTSUP; @@ -3013,7 +3023,7 @@ int rte_vhost_host_notifier_ctrl(int vid, bool enable) } } else { disable: - for (i = 0; i < dev->nr_vring; i++) { + for (i = q_start; i <= q_last; i++) { vhost_user_slave_set_vring_host_notifier(dev, i, -1, 0, 0); } From patchwork Thu Jun 18 16:28:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 71739 X-Patchwork-Delegate: maxime.coquelin@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 39CB7A04F1; Thu, 18 Jun 2020 18:28:43 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 11B2B1BFC3; Thu, 18 Jun 2020 18:28:20 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id B5FD71BFA7 for ; Thu, 18 Jun 2020 18:28:13 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from matan@mellanox.com) with SMTP; 18 Jun 2020 19:28:10 +0300 Received: from pegasus25.mtr.labs.mlnx. (pegasus25.mtr.labs.mlnx [10.210.16.10]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 05IGS9EP008363; Thu, 18 Jun 2020 19:28:09 +0300 From: Matan Azrad To: Maxime Coquelin , Xiao Wang Cc: dev@dpdk.org Date: Thu, 18 Jun 2020 16:28:04 +0000 Message-Id: <1592497686-433697-3-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1592497686-433697-1-git-send-email-matan@mellanox.com> References: <1592497686-433697-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v1 2/4] vhost: skip access lock when vDPA is configured X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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" No need to take access lock in the vhost-user massage handler when vDPA driver controls all the data-path of the vhost device. It allows the vDPA set_vring_state operation callback to configure guest notifications. Signed-off-by: Matan Azrad Reviewed-by: Maxime Coquelin --- lib/librte_vhost/vhost_user.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c index cddfa4b..b0849b9 100644 --- a/lib/librte_vhost/vhost_user.c +++ b/lib/librte_vhost/vhost_user.c @@ -2699,8 +2699,10 @@ typedef int (*vhost_message_handler_t)(struct virtio_net **pdev, case VHOST_USER_SEND_RARP: case VHOST_USER_NET_SET_MTU: case VHOST_USER_SET_SLAVE_REQ_FD: - vhost_user_lock_all_queue_pairs(dev); - unlock_required = 1; + if (!(dev->flags & VIRTIO_DEV_VDPA_CONFIGURED)) { + vhost_user_lock_all_queue_pairs(dev); + unlock_required = 1; + } break; default: break; From patchwork Thu Jun 18 16:28:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 71738 X-Patchwork-Delegate: maxime.coquelin@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 3669EA04F1; Thu, 18 Jun 2020 18:28:34 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id C09B21BFB9; Thu, 18 Jun 2020 18:28:18 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id C05791BFA9 for ; Thu, 18 Jun 2020 18:28:13 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from matan@mellanox.com) with SMTP; 18 Jun 2020 19:28:10 +0300 Received: from pegasus25.mtr.labs.mlnx. (pegasus25.mtr.labs.mlnx [10.210.16.10]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 05IGS9EQ008363; Thu, 18 Jun 2020 19:28:10 +0300 From: Matan Azrad To: Maxime Coquelin , Xiao Wang Cc: dev@dpdk.org Date: Thu, 18 Jun 2020 16:28:05 +0000 Message-Id: <1592497686-433697-4-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1592497686-433697-1-git-send-email-matan@mellanox.com> References: <1592497686-433697-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v1 3/4] vhost: improve device ready definition X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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" Some guest drivers may not configure disabled virtio queues. In this case, the vhost management never triggers the vDPA device configuration because it waits to the device to be ready. The current ready state means that all the virtio queues should be configured regardless the enablement status. In order to support this case, this patch changes the ready state: The device is ready when at least 1 queue pair is configured and enabled. So, now, the vDPA driver will be configured when the first queue pair is configured and enabled. Also the queue state operation is change to the next rules: 1. queue becomes ready (enabled and fully configured) - set_vring_state(enabled). 2. queue becomes not ready - set_vring_state(disabled). 3. queue stay ready and VHOST_USER_SET_VRING_ENABLE massage was handled - set_vring_state(enabled). The parallel operations for the application are adjusted too. Signed-off-by: Matan Azrad --- lib/librte_vhost/vhost_user.c | 51 ++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c index b0849b9..cfd5f27 100644 --- a/lib/librte_vhost/vhost_user.c +++ b/lib/librte_vhost/vhost_user.c @@ -1295,7 +1295,7 @@ { bool rings_ok; - if (!vq) + if (!vq || !vq->enabled) return false; if (vq_is_packed(dev)) @@ -1309,24 +1309,27 @@ vq->callfd != VIRTIO_UNINITIALIZED_EVENTFD; } +#define VIRTIO_DEV_NUM_VQS_TO_BE_READY 2u + static int virtio_is_ready(struct virtio_net *dev) { struct vhost_virtqueue *vq; uint32_t i; - if (dev->nr_vring == 0) + if (dev->nr_vring < VIRTIO_DEV_NUM_VQS_TO_BE_READY) return 0; - for (i = 0; i < dev->nr_vring; i++) { + for (i = 0; i < VIRTIO_DEV_NUM_VQS_TO_BE_READY; i++) { vq = dev->virtqueue[i]; if (!vq_is_ready(dev, vq)) return 0; } - VHOST_LOG_CONFIG(INFO, - "virtio is now ready for processing.\n"); + if (!(dev->flags & VIRTIO_DEV_READY)) + VHOST_LOG_CONFIG(INFO, + "virtio is now ready for processing.\n"); return 1; } @@ -1970,8 +1973,6 @@ static int vhost_user_set_vring_err(struct virtio_net **pdev __rte_unused, struct virtio_net *dev = *pdev; int enable = (int)msg->payload.state.num; int index = (int)msg->payload.state.index; - struct rte_vdpa_device *vdpa_dev; - int did = -1; if (validate_msg_fds(msg, 0) != 0) return RTE_VHOST_MSG_RESULT_ERR; @@ -1980,15 +1981,6 @@ static int vhost_user_set_vring_err(struct virtio_net **pdev __rte_unused, "set queue enable: %d to qp idx: %d\n", enable, index); - did = dev->vdpa_dev_id; - vdpa_dev = rte_vdpa_get_device(did); - if (vdpa_dev && vdpa_dev->ops->set_vring_state) - vdpa_dev->ops->set_vring_state(dev->vid, index, enable); - - if (dev->notify_ops->vring_state_changed) - dev->notify_ops->vring_state_changed(dev->vid, - index, enable); - /* On disable, rings have to be stopped being processed. */ if (!enable && dev->dequeue_zero_copy) drain_zmbuf_list(dev->virtqueue[index]); @@ -2622,11 +2614,13 @@ typedef int (*vhost_message_handler_t)(struct virtio_net **pdev, struct virtio_net *dev; struct VhostUserMsg msg; struct rte_vdpa_device *vdpa_dev; + bool ready[VHOST_MAX_VRING]; int did = -1; int ret; int unlock_required = 0; bool handled; int request; + uint32_t i; dev = get_device(vid); if (dev == NULL) @@ -2668,6 +2662,10 @@ typedef int (*vhost_message_handler_t)(struct virtio_net **pdev, VHOST_LOG_CONFIG(DEBUG, "External request %d\n", request); } + /* Save ready status for all the VQs before message handle. */ + for (i = 0; i < VHOST_MAX_VRING; i++) + ready[i] = vq_is_ready(dev, dev->virtqueue[i]); + ret = vhost_user_check_and_alloc_queue_pair(dev, &msg); if (ret < 0) { VHOST_LOG_CONFIG(ERR, @@ -2802,6 +2800,25 @@ typedef int (*vhost_message_handler_t)(struct virtio_net **pdev, return -1; } + did = dev->vdpa_dev_id; + vdpa_dev = rte_vdpa_get_device(did); + /* Update ready status. */ + for (i = 0; i < VHOST_MAX_VRING; i++) { + bool cur_ready = vq_is_ready(dev, dev->virtqueue[i]); + + if ((cur_ready && request == VHOST_USER_SET_VRING_ENABLE && + i == msg.payload.state.index) || + cur_ready != ready[i]) { + if (vdpa_dev && vdpa_dev->ops->set_vring_state) + vdpa_dev->ops->set_vring_state(dev->vid, i, + (int)cur_ready); + + if (dev->notify_ops->vring_state_changed) + dev->notify_ops->vring_state_changed(dev->vid, + i, (int)cur_ready); + } + } + if (!(dev->flags & VIRTIO_DEV_RUNNING) && virtio_is_ready(dev)) { dev->flags |= VIRTIO_DEV_READY; @@ -2816,8 +2833,6 @@ typedef int (*vhost_message_handler_t)(struct virtio_net **pdev, } } - did = dev->vdpa_dev_id; - vdpa_dev = rte_vdpa_get_device(did); if (vdpa_dev && virtio_is_ready(dev) && !(dev->flags & VIRTIO_DEV_VDPA_CONFIGURED) && msg.request.master == VHOST_USER_SET_VRING_CALL) { From patchwork Thu Jun 18 16:28:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 71740 X-Patchwork-Delegate: maxime.coquelin@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id C52E2A04F1; Thu, 18 Jun 2020 18:28:51 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 6D5131BFD1; Thu, 18 Jun 2020 18:28:21 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id C30E41BFAA for ; Thu, 18 Jun 2020 18:28:13 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from matan@mellanox.com) with SMTP; 18 Jun 2020 19:28:10 +0300 Received: from pegasus25.mtr.labs.mlnx. (pegasus25.mtr.labs.mlnx [10.210.16.10]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 05IGS9ER008363; Thu, 18 Jun 2020 19:28:10 +0300 From: Matan Azrad To: Maxime Coquelin , Xiao Wang Cc: dev@dpdk.org Date: Thu, 18 Jun 2020 16:28:06 +0000 Message-Id: <1592497686-433697-5-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1592497686-433697-1-git-send-email-matan@mellanox.com> References: <1592497686-433697-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v1 4/4] vdpa/mlx5: support queue update X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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" Last changes in vDPA device management by vhost library may cause queue ready state update after the device configuration. So, there is chance that some queue configuration information will be known only after the device was configured. Add support to reconfigure a queue after the device configuration according to the queue state update and the configuration changes. Adjust the host notifier and the guest notification configuration to be per queue and to be applied in the enablement process. Signed-off-by: Matan Azrad --- drivers/vdpa/mlx5/mlx5_vdpa.c | 25 ---------------- drivers/vdpa/mlx5/mlx5_vdpa.h | 8 ++++- drivers/vdpa/mlx5/mlx5_vdpa_virtq.c | 58 ++++++++++++++++++++++++++++++------- 3 files changed, 54 insertions(+), 37 deletions(-) diff --git a/drivers/vdpa/mlx5/mlx5_vdpa.c b/drivers/vdpa/mlx5/mlx5_vdpa.c index 8ea1300..0ef9e85 100644 --- a/drivers/vdpa/mlx5/mlx5_vdpa.c +++ b/drivers/vdpa/mlx5/mlx5_vdpa.c @@ -142,30 +142,6 @@ } static int -mlx5_vdpa_direct_db_prepare(struct mlx5_vdpa_priv *priv) -{ - int ret; - - if (priv->direct_notifier) { - ret = rte_vhost_host_notifier_ctrl(priv->vid, VHOST_QUEUE_ALL, - false); - if (ret != 0) { - DRV_LOG(INFO, "Direct HW notifier FD cannot be " - "destroyed for device %d: %d.", priv->vid, ret); - return -1; - } - priv->direct_notifier = 0; - } - ret = rte_vhost_host_notifier_ctrl(priv->vid, VHOST_QUEUE_ALL, true); - if (ret != 0) - DRV_LOG(INFO, "Direct HW notifier FD cannot be configured for" - " device %d: %d.", priv->vid, ret); - else - priv->direct_notifier = 1; - return 0; -} - -static int mlx5_vdpa_features_set(int vid) { int did = rte_vhost_get_vdpa_device_id(vid); @@ -330,7 +306,6 @@ if (mlx5_vdpa_mtu_set(priv)) DRV_LOG(WARNING, "MTU cannot be set on device %d.", did); if (mlx5_vdpa_pd_create(priv) || mlx5_vdpa_mem_register(priv) || - mlx5_vdpa_direct_db_prepare(priv) || mlx5_vdpa_virtqs_prepare(priv) || mlx5_vdpa_steer_setup(priv) || mlx5_vdpa_cqe_event_setup(priv)) { mlx5_vdpa_dev_close(vid); diff --git a/drivers/vdpa/mlx5/mlx5_vdpa.h b/drivers/vdpa/mlx5/mlx5_vdpa.h index 28ec0be..0b90900 100644 --- a/drivers/vdpa/mlx5/mlx5_vdpa.h +++ b/drivers/vdpa/mlx5/mlx5_vdpa.h @@ -70,11 +70,18 @@ struct mlx5_vdpa_query_mr { int is_indirect; }; +enum { + MLX5_VDPA_NOTIFIER_STATE_DISABLED, + MLX5_VDPA_NOTIFIER_STATE_ENABLED, + MLX5_VDPA_NOTIFIER_STATE_ERR +}; + struct mlx5_vdpa_virtq { SLIST_ENTRY(mlx5_vdpa_virtq) next; uint8_t enable; uint16_t index; uint16_t vq_size; + uint8_t notifier_state; struct mlx5_vdpa_priv *priv; struct mlx5_devx_obj *virtq; struct mlx5_devx_obj *counters; @@ -103,7 +110,6 @@ struct mlx5_vdpa_steer { struct mlx5_vdpa_priv { TAILQ_ENTRY(mlx5_vdpa_priv) next; uint8_t configured; - uint8_t direct_notifier; /* Whether direct notifier is on or off. */ uint64_t last_traffic_tic; pthread_t timer_tid; pthread_mutex_t timer_lock; diff --git a/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c b/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c index 4b4d019..30d45d4 100644 --- a/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c +++ b/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c @@ -36,6 +36,17 @@ break; } while (1); rte_write32(virtq->index, priv->virtq_db_addr); + if (virtq->notifier_state == MLX5_VDPA_NOTIFIER_STATE_DISABLED) { + if (rte_vhost_host_notifier_ctrl(priv->vid, virtq->index, true)) + virtq->notifier_state = MLX5_VDPA_NOTIFIER_STATE_ERR; + else + virtq->notifier_state = + MLX5_VDPA_NOTIFIER_STATE_ENABLED; + DRV_LOG(INFO, "Virtq %u notifier state is %s.", virtq->index, + virtq->notifier_state == + MLX5_VDPA_NOTIFIER_STATE_ENABLED ? "enabled" : + "disabled"); + } DRV_LOG(DEBUG, "Ring virtq %u doorbell.", virtq->index); } @@ -79,6 +90,7 @@ memset(&virtq->reset, 0, sizeof(virtq->reset)); if (virtq->eqp.fw_qp) mlx5_vdpa_event_qp_destroy(&virtq->eqp); + virtq->notifier_state = MLX5_VDPA_NOTIFIER_STATE_DISABLED; return 0; } @@ -289,6 +301,7 @@ virtq->priv = priv; if (!virtq->virtq) goto error; + claim_zero(rte_vhost_enable_guest_notification(priv->vid, index, 1)); if (mlx5_vdpa_virtq_modify(virtq, 1)) goto error; virtq->priv = priv; @@ -297,10 +310,6 @@ virtq->intr_handle.fd = vq.kickfd; if (virtq->intr_handle.fd == -1) { DRV_LOG(WARNING, "Virtq %d kickfd is invalid.", index); - if (!priv->direct_notifier) { - DRV_LOG(ERR, "Virtq %d cannot be notified.", index); - goto error; - } } else { virtq->intr_handle.type = RTE_INTR_HANDLE_EXT; if (rte_intr_callback_register(&virtq->intr_handle, @@ -418,18 +427,35 @@ goto error; } priv->nr_virtqs = nr_vring; - for (i = 0; i < nr_vring; i++) { - claim_zero(rte_vhost_enable_guest_notification(priv->vid, i, - 1)); - if (mlx5_vdpa_virtq_setup(priv, i)) + for (i = 0; i < nr_vring; i++) + if (priv->virtqs[i].enable && mlx5_vdpa_virtq_setup(priv, i)) goto error; - } return 0; error: mlx5_vdpa_virtqs_release(priv); return -1; } +static int +mlx5_vdpa_virtq_is_modified(struct mlx5_vdpa_priv *priv, + struct mlx5_vdpa_virtq *virtq) +{ + struct rte_vhost_vring vq; + int ret = rte_vhost_get_vhost_vring(priv->vid, virtq->index, &vq); + + if (ret) + return -1; + if (vq.size != virtq->vq_size || vq.kickfd != virtq->intr_handle.fd) + return 1; + if (virtq->eqp.cq.cq) { + if (vq.callfd != virtq->eqp.cq.callfd) + return 1; + } else if (vq.callfd != -1) { + return 1; + } + return 0; +} + int mlx5_vdpa_virtq_enable(struct mlx5_vdpa_priv *priv, int index, int enable) { @@ -438,12 +464,22 @@ DRV_LOG(INFO, "Update virtq %d status %sable -> %sable.", index, virtq->enable ? "en" : "dis", enable ? "en" : "dis"); - if (virtq->enable == !!enable) - return 0; if (!priv->configured) { virtq->enable = !!enable; return 0; } + if (virtq->enable == !!enable) { + if (!enable) + return 0; + ret = mlx5_vdpa_virtq_is_modified(priv, virtq); + if (ret < 0) { + DRV_LOG(ERR, "Virtq %d modify check failed.", index); + return -1; + } + if (ret == 0) + return 0; + DRV_LOG(INFO, "Virtq %d was modified, recreate it.", index); + } if (enable) { /* Configuration might have been updated - reconfigure virtq. */ if (virtq->virtq) {