vhost: abstract vring call mechanism as it is transport-specific
vring notification mechanism is transport-specific. At present, vhost dataplane code in `lib/vhost/vhost.c` triggers guest notifications with `eventfd_write()` system call. But this is an AF_UNIX specific notification mechanism. This patch replaces `eventfd_write()` with the existing generic `rte_vhost_vring_call()` function that is part of DPDK's librte_vhost public API. `rte_vhost_vring_call()` takes a vring_idx as an argument to associate the `struct spdk_vhost_virtqueue` instance with the relevant `struct vhost_virtqueue` instance. We introduce a new `vring_idx` field in `struct spdk_vhost_virtqueue` to enable this association. This field is initialized in `start_device()`. In addition, a stub for `rte_vhost_vring_call()` is added in the vhost unit test file. SPDK's internal `rte_vhost` copy will not be updated in order to support the virtio-vhost-user transport. However, an `rte_vhost_vring_call()` function is introduced in SPDK's `rte_vhost` in order to have a solid API. This function is just a wrapper of `eventfd_write()`. Change-Id: Ic93e25cd3f06e92f04766521bc850f1ee80b8ec8 Signed-off-by: Nikos Dragazis <ndragazis@arrikto.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/454373 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
This commit is contained in:
parent
0bfc614300
commit
5f4e42b80b
@ -472,4 +472,16 @@ int rte_vhost_set_vring_base(int vid, uint16_t queue_id,
|
|||||||
int rte_vhost_get_vring_base(int vid, uint16_t queue_id,
|
int rte_vhost_get_vring_base(int vid, uint16_t queue_id,
|
||||||
uint16_t *last_avail_idx, uint16_t *last_used_idx);
|
uint16_t *last_avail_idx, uint16_t *last_used_idx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the guest that used descriptors have been added to the vring.
|
||||||
|
*
|
||||||
|
* @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);
|
||||||
|
|
||||||
#endif /* _RTE_VHOST_H_ */
|
#endif /* _RTE_VHOST_H_ */
|
||||||
|
@ -503,3 +503,28 @@ rte_vhost_get_vring_base(int vid, uint16_t vring_idx,
|
|||||||
|
|
||||||
return 0;
|
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;
|
||||||
|
|
||||||
|
if (vq->callfd != -1) {
|
||||||
|
eventfd_write(vq->callfd, (eventfd_t)1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
@ -278,8 +278,13 @@ spdk_vhost_vq_used_signal(struct spdk_vhost_session *vsession,
|
|||||||
"Queue %td - USED RING: sending IRQ: last used %"PRIu16"\n",
|
"Queue %td - USED RING: sending IRQ: last used %"PRIu16"\n",
|
||||||
virtqueue - vsession->virtqueue, virtqueue->last_used_idx);
|
virtqueue - vsession->virtqueue, virtqueue->last_used_idx);
|
||||||
|
|
||||||
eventfd_write(virtqueue->vring.callfd, (eventfd_t)1);
|
if (rte_vhost_vring_call(vsession->vid, virtqueue->vring_idx) == 0) {
|
||||||
|
/* interrupt signalled */
|
||||||
return 1;
|
return 1;
|
||||||
|
} else {
|
||||||
|
/* interrupt not signalled */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1118,9 +1123,11 @@ start_device(int vid)
|
|||||||
for (i = 0; i < SPDK_VHOST_MAX_VQUEUES; i++) {
|
for (i = 0; i < SPDK_VHOST_MAX_VQUEUES; i++) {
|
||||||
struct spdk_vhost_virtqueue *q = &vsession->virtqueue[i];
|
struct spdk_vhost_virtqueue *q = &vsession->virtqueue[i];
|
||||||
|
|
||||||
|
q->vring_idx = -1;
|
||||||
if (rte_vhost_get_vhost_vring(vid, i, &q->vring)) {
|
if (rte_vhost_get_vhost_vring(vid, i, &q->vring)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
q->vring_idx = i;
|
||||||
|
|
||||||
if (q->vring.desc == NULL || q->vring.size == 0) {
|
if (q->vring.desc == NULL || q->vring.size == 0) {
|
||||||
continue;
|
continue;
|
||||||
@ -1160,9 +1167,7 @@ start_device(int vid)
|
|||||||
* Tested on QEMU 2.10.91 and 2.11.50.
|
* Tested on QEMU 2.10.91 and 2.11.50.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < vsession->max_queues; i++) {
|
for (i = 0; i < vsession->max_queues; i++) {
|
||||||
if (vsession->virtqueue[i].vring.callfd != -1) {
|
rte_vhost_vring_call(vsession->vid, vsession->virtqueue[i].vring_idx);
|
||||||
eventfd_write(vsession->virtqueue[i].vring.callfd, (eventfd_t)1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spdk_vhost_session_set_coalescing(vdev, vsession, NULL);
|
spdk_vhost_session_set_coalescing(vdev, vsession, NULL);
|
||||||
|
@ -113,6 +113,8 @@ struct spdk_vhost_virtqueue {
|
|||||||
/* Next time when we need to send event */
|
/* Next time when we need to send event */
|
||||||
uint64_t next_event_time;
|
uint64_t next_event_time;
|
||||||
|
|
||||||
|
/* Associated vhost_virtqueue in the virtio device's virtqueue list */
|
||||||
|
uint32_t vring_idx;
|
||||||
} __attribute((aligned(SPDK_CACHE_LINE_SIZE)));
|
} __attribute((aligned(SPDK_CACHE_LINE_SIZE)));
|
||||||
|
|
||||||
struct spdk_vhost_session {
|
struct spdk_vhost_session {
|
||||||
|
@ -55,6 +55,7 @@ DEFINE_STUB(spdk_event_allocate, struct spdk_event *,
|
|||||||
(uint32_t lcore, spdk_event_fn fn, void *arg1, void *arg2), NULL);
|
(uint32_t lcore, spdk_event_fn fn, void *arg1, void *arg2), NULL);
|
||||||
DEFINE_STUB(spdk_mem_register, int, (void *vaddr, size_t len), 0);
|
DEFINE_STUB(spdk_mem_register, int, (void *vaddr, size_t len), 0);
|
||||||
DEFINE_STUB(spdk_mem_unregister, int, (void *vaddr, size_t len), 0);
|
DEFINE_STUB(spdk_mem_unregister, int, (void *vaddr, size_t len), 0);
|
||||||
|
DEFINE_STUB(rte_vhost_vring_call, int, (int vid, uint16_t vring_idx), 0);
|
||||||
|
|
||||||
static struct spdk_cpuset *g_app_core_mask;
|
static struct spdk_cpuset *g_app_core_mask;
|
||||||
struct spdk_cpuset *spdk_app_get_core_mask(void)
|
struct spdk_cpuset *spdk_app_get_core_mask(void)
|
||||||
|
Loading…
Reference in New Issue
Block a user