From 448bb22e72eb56f492c9b15b28676147a3cda223 Mon Sep 17 00:00:00 2001 From: zhengbin Date: Thu, 21 Mar 2019 16:03:53 +0800 Subject: [PATCH] blk-mq: fix a hung issue when set device state to blocked and restore running euler inclusion category: bugfix bugzilla: 12808 CVE: NA --------------------------- When I use dd test a SCSI device which use blk-mq in the following steps: 1.echo "blocked" >/sys/block/sda/device/state 2.dd if=/dev/sda of=/mnt/t.log bs=1M count=10 3.echo "running" >/sys/block/sda/device/state dd should finish this work after step 3, unfortunately, still hung. After step2, the key code process is like this: blk_mq_dispatch_rq_list-->scsi_queue_rq-->prep_to_mq prep_to_mq will return BLK_STS_RESOURCE, and scsi_queue_rq will transter it to BLK_STS_DEV_RESOURCE, which means that driver can guarantee that IO dispatch will be triggered in future when the resource is available. Need to follow the rule if we set the device state to running. Signed-off-by: zhengbin Reviewed-by: Jason Yan Signed-off-by: Yang Yingliang --- drivers/scsi/scsi_sysfs.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 3aee9464a7bf..70b2e3a1abc7 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -765,9 +765,21 @@ store_state_field(struct device *dev, struct device_attribute *attr, mutex_lock(&sdev->state_mutex); ret = scsi_device_set_state(sdev, state); + /* If device use blk-mq, the device state changes to + * SDEV_RUNNING, we need to run hw queue to avoid io hung. + */ + if ((ret == 0) && (state == SDEV_RUNNING) && + (sdev->request_queue->mq_ops != NULL)) + goto out_run_hw_queue; mutex_unlock(&sdev->state_mutex); return ret == 0 ? count : -EINVAL; + +out_run_hw_queue: + mutex_unlock(&sdev->state_mutex); + blk_mq_run_hw_queues(sdev->request_queue, true); + + return count; } static ssize_t -- GitLab