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 <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14402
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Dong Yi <yidong0635@126.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Changpeng Liu 2022-09-07 13:44:14 +08:00 committed by Jim Harris
parent 097691fc18
commit 40f556ca38
2 changed files with 18 additions and 0 deletions

View File

@ -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;
}

View File

@ -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;