From 1f9c7a74bc7e76d9662c593b2f5a576c0a78d0ee Mon Sep 17 00:00:00 2001 From: Changpeng Liu Date: Mon, 8 Nov 2021 20:13:54 +0800 Subject: [PATCH] vhost: stop started session in session_shutdown DPDK vhost will call `new_device` when the VRINGs are queue paired(virtio-net) or all the VRINGs are started. However, for virtio-blk/scsi, SeaBIOS will only use one VRING queue, DPDK added a workaround patch to add `pre_msg_handle` and `post_msg_handle` callbacks to let devices other than virtio-net to process such scenarios. In SPDK, we will start the device when there is one valid VRING, so there is a case that SPDK and DPDK have different state for one device. For a virtio-scsi device, SeaBIOS will only start the request queue, and in the BIOS stage, SPDK will start the device but DPDK doesn't think so. If users killed SPDK vhost target at the moment, in `session_shutdown`, SPDK will expect DPDK to call `destroy_device` to do the cleanup, but DPDK won't do that as it thinks the device isn't started. Here in `session_shutdown`, SPDK will do this first, it's OK that DPDK will call another `destroy_device` for devices that have the same state both in SPDK and DPDK. Fix issue #2228. Change-Id: Ib76dd54c8fa302ffe6da9b13498312b7d344bbfe Signed-off-by: Changpeng Liu Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/10143 Community-CI: Broadcom CI Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- lib/vhost/vhost.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c index 211e211ee9..557a61b00c 100644 --- a/lib/vhost/vhost.c +++ b/lib/vhost/vhost.c @@ -1658,8 +1658,16 @@ static void * session_shutdown(void *arg) { struct spdk_vhost_dev *vdev = NULL; + struct spdk_vhost_session *vsession; TAILQ_FOREACH(vdev, &g_vhost_devices, tailq) { + pthread_mutex_lock(&g_vhost_mutex); + TAILQ_FOREACH(vsession, &vdev->vsessions, tailq) { + if (vsession->started) { + _stop_session(vsession); + } + } + pthread_mutex_unlock(&g_vhost_mutex); vhost_driver_unregister(vdev->path); vdev->registered = false; }