From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by dpdk.org (Postfix) with ESMTP id 1868C7D30 for ; Tue, 2 Jan 2018 10:31:59 +0100 (CET) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 712B13680C; Tue, 2 Jan 2018 09:31:58 +0000 (UTC) Received: from localhost (ovpn-117-44.ams2.redhat.com [10.36.117.44]) by smtp.corp.redhat.com (Postfix) with ESMTP id 17051600CA; Tue, 2 Jan 2018 09:31:52 +0000 (UTC) From: Stefan Hajnoczi To: dev@dpdk.org Cc: Yuanhan Liu , Tetsuya Mukawa , Maxime Coquelin , Stefan Hajnoczi Date: Tue, 2 Jan 2018 09:31:36 +0000 Message-Id: <20180102093136.28690-3-stefanha@redhat.com> In-Reply-To: <20180102093136.28690-1-stefanha@redhat.com> References: <20180102093136.28690-1-stefanha@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Tue, 02 Jan 2018 09:31:58 +0000 (UTC) Subject: [dpdk-dev] [PATCH v2 2/2] vhost: introduce rte_vhost_vring_call() 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: , X-List-Received-Date: Tue, 02 Jan 2018 09:31:59 -0000 Users of librte_vhost currently implement the vring call operation themselves. Each caller performs the operation slightly differently. This patch introduces a new librte_vhost API called rte_vhost_vring_call() that performs the operation so that vhost-user applications don't have to duplicate it. Signed-off-by: Stefan Hajnoczi --- lib/librte_vhost/rte_vhost.h | 15 +++++++++++++++ examples/vhost/virtio_net.c | 11 ++--------- examples/vhost_scsi/vhost_scsi.c | 6 +++--- lib/librte_vhost/vhost.c | 21 +++++++++++++++++++++ lib/librte_vhost/rte_vhost_version.map | 7 +++++++ 5 files changed, 48 insertions(+), 12 deletions(-) diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h index f65364495..890f8a831 100644 --- a/lib/librte_vhost/rte_vhost.h +++ b/lib/librte_vhost/rte_vhost.h @@ -86,7 +86,9 @@ struct rte_vhost_vring { struct vring_used *used; uint64_t log_guest_addr; + /** Deprecated, use rte_vhost_vring_call() instead. */ int callfd; + int kickfd; uint16_t size; }; @@ -436,6 +438,19 @@ int rte_vhost_get_mem_table(int vid, struct rte_vhost_memory **mem); int rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx, struct rte_vhost_vring *vring); +/** + * Notify the guest that used descriptors have been added to the vring. This + * function acts as a memory barrier. + * + * @param vid + * vhost device ID + * @param vring_idx + * vring index + * @return + * 0 on success, -1 on failure + */ +int rte_vhost_vring_call(int vid, uint16_t vring_idx); + /** * Get vhost RX queue avail count. * diff --git a/examples/vhost/virtio_net.c b/examples/vhost/virtio_net.c index 1ab57f526..252c5b8ce 100644 --- a/examples/vhost/virtio_net.c +++ b/examples/vhost/virtio_net.c @@ -207,13 +207,8 @@ vs_enqueue_pkts(struct vhost_dev *dev, uint16_t queue_id, *(volatile uint16_t *)&vr->used->idx += count; queue->last_used_idx += count; - /* flush used->idx update before we read avail->flags. */ - rte_mb(); + rte_vhost_vring_call(dev->vid, queue_id); - /* Kick the guest if necessary. */ - if (!(vr->avail->flags & VRING_AVAIL_F_NO_INTERRUPT) - && (vr->callfd >= 0)) - eventfd_write(vr->callfd, (eventfd_t)1); return count; } @@ -396,9 +391,7 @@ vs_dequeue_pkts(struct vhost_dev *dev, uint16_t queue_id, vr->used->idx += i; - if (!(vr->avail->flags & VRING_AVAIL_F_NO_INTERRUPT) - && (vr->callfd >= 0)) - eventfd_write(vr->callfd, (eventfd_t)1); + rte_vhost_vring_call(dev->vid, queue_id); return i; } diff --git a/examples/vhost_scsi/vhost_scsi.c b/examples/vhost_scsi/vhost_scsi.c index b4f1f8d27..e30e61f6d 100644 --- a/examples/vhost_scsi/vhost_scsi.c +++ b/examples/vhost_scsi/vhost_scsi.c @@ -110,7 +110,7 @@ descriptor_is_wr(struct vring_desc *cur_desc) } static void -submit_completion(struct vhost_scsi_task *task) +submit_completion(struct vhost_scsi_task *task, uint32_t q_idx) { struct rte_vhost_vring *vq; struct vring_used *used; @@ -131,7 +131,7 @@ submit_completion(struct vhost_scsi_task *task) /* Send an interrupt back to the guest VM so that it knows * a completion is ready to be processed. */ - eventfd_write(vq->callfd, (eventfd_t)1); + rte_vhost_vring_call(task->bdev->vid, q_idx); } static void @@ -263,7 +263,7 @@ process_requestq(struct vhost_scsi_ctrlr *ctrlr, uint32_t q_idx) task->resp->status = 0; task->resp->resid = 0; } - submit_completion(task); + submit_completion(task, q_idx); rte_free(task); } } diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c index 4f8b73a09..1244d76d4 100644 --- a/lib/librte_vhost/vhost.c +++ b/lib/librte_vhost/vhost.c @@ -519,6 +519,27 @@ rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx, return 0; } +int +rte_vhost_vring_call(int vid, uint16_t vring_idx) +{ + struct virtio_net *dev; + struct vhost_virtqueue *vq; + + dev = get_device(vid); + if (!dev) + return -1; + + if (vring_idx >= VHOST_MAX_VRING) + return -1; + + vq = dev->virtqueue[vring_idx]; + if (!vq) + return -1; + + vhost_vring_call(vq); + return 0; +} + uint16_t rte_vhost_avail_entries(int vid, uint16_t queue_id) { diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map index 1e7049535..b30187601 100644 --- a/lib/librte_vhost/rte_vhost_version.map +++ b/lib/librte_vhost/rte_vhost_version.map @@ -52,3 +52,10 @@ DPDK_17.08 { rte_vhost_rx_queue_count; } DPDK_17.05; + +EXPERIMENTAL { + global: + + rte_vhost_vring_call; + +} DPDK_17.08 -- 2.14.3