Commit 52b10970 authored by Dariusz Stojaczyk's avatar Dariusz Stojaczyk Committed by Jim Harris
Browse files

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: default avatarDariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
parent 8457b98c
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -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_ */
+26 −0
Original line number Diff line number Diff line
@@ -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;
}