From 52b10970c49bd1813d49786305797e58dd0b18f9 Mon Sep 17 00:00:00 2001 From: Dariusz Stojaczyk Date: Mon, 8 May 2017 09:42:55 -0700 Subject: [PATCH] vhost: added API for getting/setting last descriptor indices of vrings vhost-net devices might keep track of last descriptors indices by themselves, and assuming they initially start at 0, but that is not the case for vhost-scsi. Initial last descriptor indices are set via VHOST_USER_SET_VRING_BASE message, and we cannot possibly predict what will they be. Setting these to vqueue->used->idx is also not an option, because there might be some yet unprocessed requests between these and the actual last_idx. This patch adds API for getting/setting last descriptor indices of vrings, so that they can be synchronized between user-device and rte_vhost. The last_idx flow could be as following: * vhost start * received SET_VRING_BASE msg, last_idx is set on rte_vhost side * created user-device, last_idx pulled from rte_vhost * requests are being processed by user-device, last_idx changes * destroyed user-device, last_idx pushed to rte_vhost * *at this point, vrings could be recreated and another SET_VRING_BASE message could arrive, so last_idx would be set* * recreated user-device, last_idx pulled from rte_vhost Change-Id: I247ba4e461a2a2b524ccade364f5b7bf260f7538 Signed-off-by: Dariusz Stojaczyk --- lib/vhost/rte_vhost_17_05/rte_vhost.h | 24 ++++++++++++++++++++++++ lib/vhost/rte_vhost_17_05/vhost.c | 26 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/lib/vhost/rte_vhost_17_05/rte_vhost.h b/lib/vhost/rte_vhost_17_05/rte_vhost.h index 5fb9dfb88..b8419e3e9 100644 --- a/lib/vhost/rte_vhost_17_05/rte_vhost.h +++ b/lib/vhost/rte_vhost_17_05/rte_vhost.h @@ -82,6 +82,9 @@ struct rte_vhost_vring { int callfd; int kickfd; uint16_t size; + + uint16_t last_avail_idx; + uint16_t last_used_idx; }; /** @@ -424,4 +427,25 @@ 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); +/** + * Set id of the last descriptors in avail and used guest vrings. + * + * In case user application operates directly on buffers, it should use this + * function on device destruction to retrieve the same values later on in device + * creation via rte_vhost_get_vhost_vring(int, uint16_t, struct rte_vhost_vring *) + * + * @param vid + * vhost device ID + * @param vring_idx + * vring index + * @param last_avail_idx + * id of the last descriptor in avail ring to be set + * @param last_used_idx + * id of the last descriptor in used ring to be set + * @return + * 0 on success, -1 on failure + */ +int rte_vhost_set_vhost_vring_last_idx(int vid, uint16_t vring_idx, + uint16_t last_avail_idx, uint16_t last_used_idx); + #endif /* _RTE_VHOST_H_ */ diff --git a/lib/vhost/rte_vhost_17_05/vhost.c b/lib/vhost/rte_vhost_17_05/vhost.c index 0b19d2eb8..dc63208b0 100644 --- a/lib/vhost/rte_vhost_17_05/vhost.c +++ b/lib/vhost/rte_vhost_17_05/vhost.c @@ -407,6 +407,9 @@ rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx, vring->kickfd = vq->kickfd; vring->size = vq->size; + vring->last_avail_idx = vq->last_avail_idx; + vring->last_used_idx = vq->last_used_idx; + return 0; } @@ -475,3 +478,26 @@ rte_vhost_log_used_vring(int vid, uint16_t vring_idx, vhost_log_used_vring(dev, vq, offset, len); } + +int +rte_vhost_set_vhost_vring_last_idx(int vid, uint16_t vring_idx, + uint16_t last_avail_idx, uint16_t last_used_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; + + vq->last_avail_idx = last_avail_idx; + vq->last_used_idx = last_used_idx; + + return 0; +}