From 40f556ca38442936549fd53cb05827e5e70db432 Mon Sep 17 00:00:00 2001 From: Changpeng Liu Date: Wed, 7 Sep 2022 13:44:14 +0800 Subject: [PATCH] vhost: don't kick VM when there are outstanding vhost-user messages For all the vhost-user messages processed in SPDK except VHOST_USER_GET_VRING_BASE, DPDK rte_vhost "vhost-events" thread already holds all VQ's access lock, before return response to "vhost-events" thread, SPDK should not call `rte_vhost_vring_call`, here we set a flag to TRUE for these vhost-user messages, and avoid to kick VM. The deferred IRQs will be posted in next round poll or after restarting the device. Fix issue #2518. Change-Id: I82f14b97d0b0ce602a93fd66d5fdeef64f07d179 Signed-off-by: Changpeng Liu Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14402 Tested-by: SPDK CI Jenkins Reviewed-by: Dong Yi Reviewed-by: Tomasz Zawadzki Reviewed-by: Jim Harris --- lib/vhost/rte_vhost_user.c | 17 +++++++++++++++++ lib/vhost/vhost_internal.h | 1 + 2 files changed, 18 insertions(+) diff --git a/lib/vhost/rte_vhost_user.c b/lib/vhost/rte_vhost_user.c index eae22895c..be3f711f8 100644 --- a/lib/vhost/rte_vhost_user.c +++ b/lib/vhost/rte_vhost_user.c @@ -351,6 +351,14 @@ int vhost_vq_used_signal(struct spdk_vhost_session *vsession, struct spdk_vhost_virtqueue *virtqueue) { + /* The flag is true when DPDK "vhost-events" thread is holding all + * VQ's access lock, we will skip to post IRQs this round poll, and + * try to post IRQs in next poll or after starting the device again. + */ + if (spdk_unlikely(vsession->skip_used_signal)) { + return 0; + } + if (virtqueue->used_req_cnt == 0) { return 0; } @@ -1408,6 +1416,13 @@ extern_vhost_pre_msg_handler(int vid, void *_msg) case VHOST_USER_SET_VRING_BASE: case VHOST_USER_SET_VRING_ADDR: case VHOST_USER_SET_VRING_NUM: + /* For vhost-user socket messages except VHOST_USER_GET_VRING_BASE, + * rte_vhost holds all VQ's access lock, then after DPDK 22.07 release, + * `rte_vhost_vring_call` also needs to hold VQ's access lock, so we + * can't call this function in DPDK "vhost-events" thread context, here + * SPDK vring poller will avoid executing this function when it's TRUE. + */ + vsession->skip_used_signal = true; if (vsession->forced_polling && vsession->started) { /* Additional queues are being initialized, so we either processed * enough I/Os and are switching from SeaBIOS to the OS now, or @@ -1435,6 +1450,7 @@ extern_vhost_pre_msg_handler(int vid, void *_msg) * rte_vhost. */ case VHOST_USER_SET_MEM_TABLE: + vsession->skip_used_signal = true; /* rte_vhost will unmap previous memory that SPDK may still * have pending DMA operations on. We can't let that happen, * so stop the device before letting rte_vhost unmap anything. @@ -1479,6 +1495,7 @@ extern_vhost_pre_msg_handler(int vid, void *_msg) break; } + vsession->skip_used_signal = false; return RTE_VHOST_MSG_RESULT_NOT_HANDLED; } diff --git a/lib/vhost/vhost_internal.h b/lib/vhost/vhost_internal.h index f0aa0b198..8a1f1ea61 100644 --- a/lib/vhost/vhost_internal.h +++ b/lib/vhost/vhost_internal.h @@ -119,6 +119,7 @@ struct spdk_vhost_session { bool needs_restart; bool forced_polling; bool interrupt_mode; + bool skip_used_signal; struct rte_vhost_memory *mem;