From 002cfe9d3fde7f8e026a303499169e294be50573 Mon Sep 17 00:00:00 2001 From: Li Feng Date: Wed, 18 Nov 2020 17:11:17 +0800 Subject: [PATCH] vhost-scsi: fix hang when removing target If the virtio-scsi controller doesn't support the 'eventq' and 'controlq' queue, the operation(vhost_scsi_controller_remove_target) of removing target from this controller will always hang. We can reproduce this by starting a qemu without a bootable guest os. Change-Id: Ia53b48ae1a18cfb9dc919352fc3cce6ade84c9d8 Signed-off-by: Li Feng Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5151 Tested-by: SPDK CI Jenkins Reviewed-by: Changpeng Liu Reviewed-by: Shuhei Matsumoto Community-CI: Mellanox Build Bot --- lib/vhost/vhost_scsi.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/vhost/vhost_scsi.c b/lib/vhost/vhost_scsi.c index 632e096ea..cba4b2490 100644 --- a/lib/vhost/vhost_scsi.c +++ b/lib/vhost/vhost_scsi.c @@ -807,10 +807,15 @@ vdev_mgmt_worker(void *arg) struct spdk_vhost_session *vsession = &svsession->vsession; process_removed_devs(svsession); - vhost_vq_used_signal(vsession, &vsession->virtqueue[VIRTIO_SCSI_EVENTQ]); - process_vq(svsession, &vsession->virtqueue[VIRTIO_SCSI_CONTROLQ]); - vhost_vq_used_signal(vsession, &vsession->virtqueue[VIRTIO_SCSI_CONTROLQ]); + if (vsession->virtqueue[VIRTIO_SCSI_EVENTQ].vring.desc) { + vhost_vq_used_signal(vsession, &vsession->virtqueue[VIRTIO_SCSI_EVENTQ]); + } + + if (vsession->virtqueue[VIRTIO_SCSI_CONTROLQ].vring.desc) { + process_vq(svsession, &vsession->virtqueue[VIRTIO_SCSI_CONTROLQ]); + vhost_vq_used_signal(vsession, &vsession->virtqueue[VIRTIO_SCSI_CONTROLQ]); + } return SPDK_POLLER_BUSY; } @@ -1408,11 +1413,8 @@ vhost_scsi_start_cb(struct spdk_vhost_dev *vdev, vsession->name, spdk_env_get_current_core()); svsession->requestq_poller = SPDK_POLLER_REGISTER(vdev_worker, svsession, 0); - if (vsession->virtqueue[VIRTIO_SCSI_CONTROLQ].vring.desc && - vsession->virtqueue[VIRTIO_SCSI_EVENTQ].vring.desc) { - svsession->mgmt_poller = SPDK_POLLER_REGISTER(vdev_mgmt_worker, svsession, - MGMT_POLL_PERIOD_US); - } + svsession->mgmt_poller = SPDK_POLLER_REGISTER(vdev_mgmt_worker, svsession, + MGMT_POLL_PERIOD_US); out: vhost_session_start_done(vsession, rc); return rc;