Commit 40f556ca authored by Changpeng Liu's avatar Changpeng Liu Committed by Jim Harris
Browse files

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: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14402


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarDong Yi <yidong0635@126.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 097691fc
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -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;
}

+1 −0
Original line number Diff line number Diff line
@@ -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;