From 6c299bb7322fc7c506389a951a2500a92ba9253e Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Tue, 2 Jan 2018 09:31:36 +0000 Subject: [PATCH] vhost: introduce vring call API 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 Reviewed-by: Maxime Coquelin Acked-by: Yuanhan Liu --- examples/vhost/virtio_net.c | 11 ++--------- examples/vhost_scsi/vhost_scsi.c | 6 +++--- lib/librte_vhost/rte_vhost.h | 15 +++++++++++++++ lib/librte_vhost/rte_vhost_version.map | 7 +++++++ lib/librte_vhost/vhost.c | 21 +++++++++++++++++++++ 5 files changed, 48 insertions(+), 12 deletions(-) diff --git a/examples/vhost/virtio_net.c b/examples/vhost/virtio_net.c index 496763dd5c..f6e00674d9 100644 --- a/examples/vhost/virtio_net.c +++ b/examples/vhost/virtio_net.c @@ -178,13 +178,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; } @@ -367,9 +362,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 38f5d8201c..da01ad378e 100644 --- a/examples/vhost_scsi/vhost_scsi.c +++ b/examples/vhost_scsi/vhost_scsi.c @@ -81,7 +81,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; @@ -102,7 +102,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 @@ -234,7 +234,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/rte_vhost.h b/lib/librte_vhost/rte_vhost.h index 1a84ddf98c..d332069974 100644 --- a/lib/librte_vhost/rte_vhost.h +++ b/lib/librte_vhost/rte_vhost.h @@ -57,7 +57,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; }; @@ -407,6 +409,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/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map index 1e7049535e..df01031292 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; + +DPDK_18.02 { + global: + + rte_vhost_vring_call; + +} DPDK_17.08; diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c index a93c70dfc0..4eb450cf17 100644 --- a/lib/librte_vhost/vhost.c +++ b/lib/librte_vhost/vhost.c @@ -490,6 +490,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) { -- 2.20.1