From patchwork Tue Jan 23 10:55:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srujana Challa X-Patchwork-Id: 136056 X-Patchwork-Delegate: maxime.coquelin@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 9165B439A6; Tue, 23 Jan 2024 11:55:31 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 260E9402B0; Tue, 23 Jan 2024 11:55:31 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 866F3400D7 for ; Tue, 23 Jan 2024 11:55:29 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 40N1Emoe008709; Tue, 23 Jan 2024 02:55:28 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= pfpt0220; bh=DoLLWGf/tyu5CbZ0P0ndrRdVJ70p9lUkBDf4Hzf0Wto=; b=Z// hq7RYrh65NXDSPrPDjrIoPa+4cpqZrDuyHxd0xsaCDC6YNg6bZjLr812A7IYLNsv 1eATCdD6B5N+jkyW0eD0XBE38xzOyhR1cBoUhX7oclz87E+rYzVI/eBQwDWfcKZp 1/LNN/QRqDyrP/+1eYM2oPLe5CWiwYXF/PRZ6LBKbsehkw2MhqA5MUapF3BrF+Ur oRAUnu31D8ZAv6nzdSmw5K7alyHhCBlu8Lq3czVDjG1lXCA5QFdJU/46ti4hTY2g cAldUV0OimmgY0Sn9pueZiRt0tApSUXfOuzWaWCJzT1YFbj+dw2OiznqTy8o+sPN bC5NZPSv30N//TJWfMg== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3vrejnh5dm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Tue, 23 Jan 2024 02:55:28 -0800 (PST) Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.48; Tue, 23 Jan 2024 02:55:26 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.48 via Frontend Transport; Tue, 23 Jan 2024 02:55:26 -0800 Received: from localhost.localdomain (unknown [10.28.36.175]) by maili.marvell.com (Postfix) with ESMTP id 47D315B6941; Tue, 23 Jan 2024 02:55:24 -0800 (PST) From: Srujana Challa To: , , CC: , Subject: [PATCH v2 1/2] net/virtio-user: improve kick performance with notification area mapping Date: Tue, 23 Jan 2024 16:25:22 +0530 Message-ID: <20240123105523.751151-1-schalla@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231208053121.152929-1-schalla@marvell.com> References: <20231208053121.152929-1-schalla@marvell.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: hZQyc_TNJh6M9EsVL2VenRkUmDjhS5iT X-Proofpoint-GUID: hZQyc_TNJh6M9EsVL2VenRkUmDjhS5iT X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-01-23_05,2024-01-23_01,2023-05-22_02 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 This patch introduces new virtio-user callbacks to map the vq notification area and implements it for the vhost-vDPA backend. This is simply done by using mmap()/munmap() for the vhost-vDPA fd. And also adds code to write to queue notify address in notify callback. This will help in increasing the kick performance. Signed-off-by: Srujana Challa Reviewed-by: Maxime Coquelin --- drivers/net/virtio/virtio_user/vhost.h | 2 + drivers/net/virtio/virtio_user/vhost_vdpa.c | 68 +++++++++++++++++++ .../net/virtio/virtio_user/virtio_user_dev.c | 43 ++++++++++-- .../net/virtio/virtio_user/virtio_user_dev.h | 2 + drivers/net/virtio/virtio_user_ethdev.c | 37 ++++++++-- 5 files changed, 143 insertions(+), 9 deletions(-) diff --git a/drivers/net/virtio/virtio_user/vhost.h b/drivers/net/virtio/virtio_user/vhost.h index f817cab77a..eee3a4bc47 100644 --- a/drivers/net/virtio/virtio_user/vhost.h +++ b/drivers/net/virtio/virtio_user/vhost.h @@ -90,6 +90,8 @@ struct virtio_user_backend_ops { int (*server_disconnect)(struct virtio_user_dev *dev); int (*server_reconnect)(struct virtio_user_dev *dev); int (*get_intr_fd)(struct virtio_user_dev *dev); + int (*map_notification_area)(struct virtio_user_dev *dev); + int (*unmap_notification_area)(struct virtio_user_dev *dev); }; extern struct virtio_user_backend_ops virtio_ops_user; diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c b/drivers/net/virtio/virtio_user/vhost_vdpa.c index 2c36b26224..3246b74e13 100644 --- a/drivers/net/virtio/virtio_user/vhost_vdpa.c +++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -622,6 +623,71 @@ vhost_vdpa_get_intr_fd(struct virtio_user_dev *dev __rte_unused) return -1; } +static int +vhost_vdpa_get_nr_vrings(struct virtio_user_dev *dev) +{ + int nr_vrings = dev->max_queue_pairs * 2; + + if (dev->device_features & (1ull << VIRTIO_NET_F_CTRL_VQ)) + nr_vrings += 1; + + return nr_vrings; +} + +static int +vhost_vdpa_unmap_notification_area(struct virtio_user_dev *dev) +{ + int i, nr_vrings; + + nr_vrings = vhost_vdpa_get_nr_vrings(dev); + + for (i = 0; i < nr_vrings; i++) { + if (dev->notify_area[i]) + munmap(dev->notify_area[i], getpagesize()); + } + free(dev->notify_area); + dev->notify_area = NULL; + + return 0; +} + +static int +vhost_vdpa_map_notification_area(struct virtio_user_dev *dev) +{ + struct vhost_vdpa_data *data = dev->backend_data; + int nr_vrings, i, page_size = getpagesize(); + uint16_t **notify_area; + + nr_vrings = vhost_vdpa_get_nr_vrings(dev); + + notify_area = malloc(nr_vrings * sizeof(*notify_area)); + if (!notify_area) { + PMD_DRV_LOG(ERR, "(%s) Failed to allocate notify area array", dev->path); + return -1; + } + + for (i = 0; i < nr_vrings; i++) { + notify_area[i] = mmap(NULL, page_size, PROT_WRITE, MAP_SHARED | MAP_FILE, + data->vhostfd, i * page_size); + if (notify_area[i] == MAP_FAILED) { + PMD_DRV_LOG(ERR, "(%s) Map failed for notify address of queue %d\n", + dev->path, i); + i--; + goto map_err; + } + } + dev->notify_area = notify_area; + + return 0; + +map_err: + for (; i >= 0; i--) + munmap(notify_area[i], page_size); + free(notify_area); + + return -1; +} + struct virtio_user_backend_ops virtio_ops_vdpa = { .setup = vhost_vdpa_setup, .destroy = vhost_vdpa_destroy, @@ -646,4 +712,6 @@ struct virtio_user_backend_ops virtio_ops_vdpa = { .dma_unmap = vhost_vdpa_dma_unmap_batch, .update_link_state = vhost_vdpa_update_link_state, .get_intr_fd = vhost_vdpa_get_intr_fd, + .map_notification_area = vhost_vdpa_map_notification_area, + .unmap_notification_area = vhost_vdpa_unmap_notification_area, }; diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c index af1f8c8237..15b75dd802 100644 --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "vhost.h" #include "virtio_user_dev.h" @@ -414,6 +415,10 @@ virtio_user_dev_init_notify(struct virtio_user_dev *dev) dev->kickfds[i] = kickfd; } + if (dev->ops->map_notification_area) + if (dev->ops->map_notification_area(dev)) + goto err; + return 0; err: for (j = 0; j < i; j++) { @@ -445,6 +450,8 @@ virtio_user_dev_uninit_notify(struct virtio_user_dev *dev) dev->callfds[i] = -1; } } + if (dev->ops->unmap_notification_area && dev->notify_area) + dev->ops->unmap_notification_area(dev); } static int @@ -674,7 +681,8 @@ virtio_user_free_vrings(struct virtio_user_dev *dev) 1ULL << VIRTIO_NET_F_GUEST_TSO6 | \ 1ULL << VIRTIO_F_IN_ORDER | \ 1ULL << VIRTIO_F_VERSION_1 | \ - 1ULL << VIRTIO_F_RING_PACKED) + 1ULL << VIRTIO_F_RING_PACKED | \ + 1ULL << VIRTIO_F_NOTIFICATION_DATA) int virtio_user_dev_init(struct virtio_user_dev *dev, char *path, uint16_t queues, @@ -1039,11 +1047,35 @@ static void virtio_user_control_queue_notify(struct virtqueue *vq, void *cookie) { struct virtio_user_dev *dev = cookie; - uint64_t buf = 1; + uint64_t notify_data = 1; + + if (!dev->notify_area) { + if (write(dev->kickfds[vq->vq_queue_index], ¬ify_data, sizeof(notify_data)) < 0) + PMD_DRV_LOG(ERR, "failed to kick backend: %s", + strerror(errno)); + return; + } else if (!virtio_with_feature(&dev->hw, VIRTIO_F_NOTIFICATION_DATA)) { + rte_write16(vq->vq_queue_index, vq->notify_addr); + return; + } - if (write(dev->kickfds[vq->vq_queue_index], &buf, sizeof(buf)) < 0) - PMD_DRV_LOG(ERR, "failed to kick backend: %s", - strerror(errno)); + if (virtio_with_packed_queue(&dev->hw)) { + /* Bit[0:15]: vq queue index + * Bit[16:30]: avail index + * Bit[31]: avail wrap counter + */ + notify_data = ((uint32_t)(!!(vq->vq_packed.cached_flags & + VRING_PACKED_DESC_F_AVAIL)) << 31) | + ((uint32_t)vq->vq_avail_idx << 16) | + vq->vq_queue_index; + } else { + /* Bit[0:15]: vq queue index + * Bit[16:31]: avail index + */ + notify_data = ((uint32_t)vq->vq_avail_idx << 16) | + vq->vq_queue_index; + } + rte_write32(notify_data, vq->notify_addr); } int @@ -1062,6 +1094,7 @@ virtio_user_dev_create_shadow_cvq(struct virtio_user_dev *dev, struct virtqueue scvq->cq.notify_queue = &virtio_user_control_queue_notify; scvq->cq.notify_cookie = dev; + scvq->notify_addr = vq->notify_addr; dev->scvq = scvq; return 0; diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h b/drivers/net/virtio/virtio_user/virtio_user_dev.h index 7323d88302..671ba50c03 100644 --- a/drivers/net/virtio/virtio_user/virtio_user_dev.h +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h @@ -64,6 +64,8 @@ struct virtio_user_dev { struct virtqueue *scvq; void *backend_data; + + uint16_t **notify_area; }; int virtio_user_dev_set_features(struct virtio_user_dev *dev); diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c index 3a31642899..aae4c53f32 100644 --- a/drivers/net/virtio/virtio_user_ethdev.c +++ b/drivers/net/virtio/virtio_user_ethdev.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "virtio_ethdev.h" #include "virtio_logs.h" @@ -232,6 +233,9 @@ virtio_user_setup_queue(struct virtio_hw *hw, struct virtqueue *vq) else virtio_user_setup_queue_split(vq, dev); + if (dev->notify_area) + vq->notify_addr = dev->notify_area[vq->vq_queue_index]; + if (dev->hw_cvq && hw->cvq && (virtnet_cq_to_vq(hw->cvq) == vq)) return virtio_user_dev_create_shadow_cvq(dev, vq); @@ -262,8 +266,8 @@ virtio_user_del_queue(struct virtio_hw *hw, struct virtqueue *vq) static void virtio_user_notify_queue(struct virtio_hw *hw, struct virtqueue *vq) { - uint64_t buf = 1; struct virtio_user_dev *dev = virtio_user_get_dev(hw); + uint64_t notify_data = 1; if (hw->cvq && (virtnet_cq_to_vq(hw->cvq) == vq)) { virtio_user_handle_cq(dev, vq->vq_queue_index); @@ -271,9 +275,34 @@ virtio_user_notify_queue(struct virtio_hw *hw, struct virtqueue *vq) return; } - if (write(dev->kickfds[vq->vq_queue_index], &buf, sizeof(buf)) < 0) - PMD_DRV_LOG(ERR, "failed to kick backend: %s", - strerror(errno)); + if (!dev->notify_area) { + if (write(dev->kickfds[vq->vq_queue_index], ¬ify_data, + sizeof(notify_data)) < 0) + PMD_DRV_LOG(ERR, "failed to kick backend: %s", + strerror(errno)); + return; + } else if (!virtio_with_feature(hw, VIRTIO_F_NOTIFICATION_DATA)) { + rte_write16(vq->vq_queue_index, vq->notify_addr); + return; + } + + if (virtio_with_packed_queue(hw)) { + /* Bit[0:15]: vq queue index + * Bit[16:30]: avail index + * Bit[31]: avail wrap counter + */ + notify_data = ((uint32_t)(!!(vq->vq_packed.cached_flags & + VRING_PACKED_DESC_F_AVAIL)) << 31) | + ((uint32_t)vq->vq_avail_idx << 16) | + vq->vq_queue_index; + } else { + /* Bit[0:15]: vq queue index + * Bit[16:31]: avail index + */ + notify_data = ((uint32_t)vq->vq_avail_idx << 16) | + vq->vq_queue_index; + } + rte_write32(notify_data, vq->notify_addr); } static int