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 4CE101B282 for ; Thu, 21 Dec 2017 17:41:35 +0100 (CET) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A94E66A7D4; Thu, 21 Dec 2017 16:41:34 +0000 (UTC) Received: from localhost (ovpn-117-184.ams2.redhat.com [10.36.117.184]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1705960BEC; Thu, 21 Dec 2017 16:41:28 +0000 (UTC) From: Stefan Hajnoczi To: dev@dpdk.org Cc: Maxime Coquelin , Yuanhan Liu , Tetsuya Mukawa , Stefan Hajnoczi Date: Thu, 21 Dec 2017 16:41:28 +0000 Message-Id: <20171221164128.20001-1-stefanha@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Thu, 21 Dec 2017 16:41:34 +0000 (UTC) Subject: [dpdk-dev] [PATCH] 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: Thu, 21 Dec 2017 16:41:35 -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 | 27 +++++++++++++++++++++++++++ lib/librte_vhost/virtio_net.c | 29 ++++++----------------------- lib/librte_vhost/rte_vhost_version.map | 7 +++++++ 6 files changed, 60 insertions(+), 35 deletions(-) diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h index fe5c94c69..dde0eeb03 100644 --- a/lib/librte_vhost/rte_vhost.h +++ b/lib/librte_vhost/rte_vhost.h @@ -85,7 +85,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; }; @@ -435,6 +437,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..0d269f12a 100644 --- a/lib/librte_vhost/vhost.c +++ b/lib/librte_vhost/vhost.c @@ -519,6 +519,33 @@ 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; + + /* flush used->idx update before we read avail->flags. */ + rte_mb(); + + /* Kick the guest if necessary. */ + if (!(vq->avail->flags & VRING_AVAIL_F_NO_INTERRUPT) + && (vq->callfd >= 0)) + eventfd_write(vq->callfd, (eventfd_t)1); + return 0; +} + uint16_t rte_vhost_avail_entries(int vid, uint16_t queue_id) { diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c index 3c6f1a531..27efae788 100644 --- a/lib/librte_vhost/virtio_net.c +++ b/lib/librte_vhost/virtio_net.c @@ -408,13 +408,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id, offsetof(struct vring_used, idx), sizeof(vq->used->idx)); - /* flush used->idx update before we read avail->flags. */ - rte_mb(); - - /* Kick the guest if necessary. */ - if (!(vq->avail->flags & VRING_AVAIL_F_NO_INTERRUPT) - && (vq->callfd >= 0)) - eventfd_write(vq->callfd, (eventfd_t)1); + rte_vhost_vring_call(dev->vid, queue_id); out: if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)) vhost_user_iotlb_rd_unlock(vq); @@ -701,14 +695,7 @@ virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id, if (likely(vq->shadow_used_idx)) { flush_shadow_used_ring(dev, vq); - - /* flush used->idx update before we read avail->flags. */ - rte_mb(); - - /* Kick the guest if necessary. */ - if (!(vq->avail->flags & VRING_AVAIL_F_NO_INTERRUPT) - && (vq->callfd >= 0)) - eventfd_write(vq->callfd, (eventfd_t)1); + rte_vhost_vring_call(dev->vid, queue_id); } out: @@ -1095,7 +1082,7 @@ update_used_ring(struct virtio_net *dev, struct vhost_virtqueue *vq, static __rte_always_inline void update_used_idx(struct virtio_net *dev, struct vhost_virtqueue *vq, - uint32_t count) + uint16_t queue_id, uint32_t count) { if (unlikely(count == 0)) return; @@ -1106,11 +1093,7 @@ update_used_idx(struct virtio_net *dev, struct vhost_virtqueue *vq, vq->used->idx += count; vhost_log_used_vring(dev, vq, offsetof(struct vring_used, idx), sizeof(vq->used->idx)); - - /* Kick guest if required. */ - if (!(vq->avail->flags & VRING_AVAIL_F_NO_INTERRUPT) - && (vq->callfd >= 0)) - eventfd_write(vq->callfd, (eventfd_t)1); + rte_vhost_vring_call(dev->vid, queue_id); } static __rte_always_inline struct zcopy_mbuf * @@ -1213,7 +1196,7 @@ rte_vhost_dequeue_burst(int vid, uint16_t queue_id, } } - update_used_idx(dev, vq, nr_updated); + update_used_idx(dev, vq, queue_id, nr_updated); } /* @@ -1349,7 +1332,7 @@ rte_vhost_dequeue_burst(int vid, uint16_t queue_id, if (likely(dev->dequeue_zero_copy == 0)) { do_data_copy_dequeue(vq); vq->last_used_idx += i; - update_used_idx(dev, vq, i); + update_used_idx(dev, vq, queue_id, i); } out: 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