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 <dariuszx.stojaczyk@intel.com>
This commit is contained in:
Dariusz Stojaczyk 2017-05-08 09:42:55 -07:00 committed by Jim Harris
parent 8457b98cf2
commit 52b10970c4
2 changed files with 50 additions and 0 deletions

View File

@ -82,6 +82,9 @@ struct rte_vhost_vring {
int callfd; int callfd;
int kickfd; int kickfd;
uint16_t size; 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, int rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
struct rte_vhost_vring *vring); 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_ */ #endif /* _RTE_VHOST_H_ */

View File

@ -407,6 +407,9 @@ rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
vring->kickfd = vq->kickfd; vring->kickfd = vq->kickfd;
vring->size = vq->size; vring->size = vq->size;
vring->last_avail_idx = vq->last_avail_idx;
vring->last_used_idx = vq->last_used_idx;
return 0; 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); 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;
}