Commit dbe47004 authored by Yuhua's avatar Yuhua Committed by Tomasz Zawadzki
Browse files

lib/vhost: ensure a vring call interrupt when restart the device vq



It appears that the guest os may be frozen without a new vring call
interrupt after the virtqueue restarted. Currently, the handler of
message VHOST_USER_SET_VRING_CALL ensures the occurrence of an
interrupt. Furthermore, an additional interrupt is also required
following the `enable_device_vq` to ensure the continued
functionality of the virtqueue even after a runtime restart.

Fixes: 23baa676 ("lib/vhost: don't restart device multiple times").

Fix issue #3150.

Signed-off-by: default avatarYuhua <yuhua@smartx.com>
Change-Id: I405b8a090ea146d3227e6a7e91c8e8dbb1abc645
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/20245


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
parent ac3bfcda
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -1083,6 +1083,17 @@ enable_device_vq(struct spdk_vhost_session *vsession, uint16_t qid)
		return rc;
	}

	/*
	 * This shouldn't harm guest since spurious interrupts should be ignored by
	 * guest virtio driver.
	 *
	 * Make sure a successful call of `rte_vhost_vring_call` will happen after
	 * restarting the device.
	 */
	if (vsession->needs_restart) {
		q->used_req_cnt += 1;
	}

	if (packed_ring) {
		/* Since packed ring flag is already negociated between SPDK and VM, VM doesn't
		 * restore `last_avail_idx` and `last_used_idx` for packed ring, so use the
@@ -1572,12 +1583,12 @@ extern_vhost_post_msg_handler(int vid, void *_msg)
		vhost_register_memtable_if_required(vsession, vid);
		pthread_mutex_lock(&user_dev->lock);
		if (vsession->needs_restart) {
			vsession->needs_restart = false;
			pthread_mutex_unlock(&user_dev->lock);
			for (qid = 0; qid < vsession->original_max_queues; qid++) {
				enable_device_vq(vsession, qid);
			}
			vsession->original_max_queues = 0;
			vsession->needs_restart = false;
			g_spdk_vhost_ops.new_device(vid);
			break;
		}