Daniel Wagner 50bad3
From: Ming Lei <ming.lei@redhat.com>
Daniel Wagner 50bad3
Date: Mon, 20 Jul 2020 10:54:35 +0800
Daniel Wagner 50bad3
Subject: scsi: core: Run queue in case of I/O resource contention failure
Daniel Wagner 50bad3
Patch-mainline: v5.8-rc7
Daniel Wagner 50bad3
Git-commit: 3f0dcfbcd2e162fc0a11c1f59b7acd42ee45f126
Daniel Wagner 50bad3
References: bsc#1186416
Daniel Wagner 50bad3
Daniel Wagner 50bad3
I/O requests may be held in scheduler queue because of resource contention.
Daniel Wagner 50bad3
The starvation scenario was handled properly in the regular completion
Daniel Wagner 50bad3
path but we failed to account for it during I/O submission. This lead to
Daniel Wagner 50bad3
the hang captured below. Make sure we run the queue when resource
Daniel Wagner 50bad3
contention is encountered in the submission path.
Daniel Wagner 50bad3
Daniel Wagner 50bad3
[   39.054963] scsi 13:0:0:0: rejecting I/O to dead device
Daniel Wagner 50bad3
[   39.058700] scsi 13:0:0:0: rejecting I/O to dead device
Daniel Wagner 50bad3
[   39.087855] sd 13:0:0:1: [sdd] Synchronizing SCSI cache
Daniel Wagner 50bad3
[   39.088909] scsi 13:0:0:1: rejecting I/O to dead device
Daniel Wagner 50bad3
[   39.095351] scsi 13:0:0:1: rejecting I/O to dead device
Daniel Wagner 50bad3
[   39.096962] scsi 13:0:0:1: rejecting I/O to dead device
Daniel Wagner 50bad3
[  247.021859] INFO: task scsi-stress-rem:813 blocked for more than 122 seconds.
Daniel Wagner 50bad3
[  247.023258]       Not tainted 5.8.0-rc2 #8
Daniel Wagner 50bad3
[  247.024069] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
Daniel Wagner 50bad3
[  247.025331] scsi-stress-rem D    0   813    802 0x00004000
Daniel Wagner 50bad3
[  247.025334] Call Trace:
Daniel Wagner 50bad3
[  247.025354]  __schedule+0x504/0x55f
Daniel Wagner 50bad3
[  247.027987]  schedule+0x72/0xa8
Daniel Wagner 50bad3
[  247.027991]  blk_mq_freeze_queue_wait+0x63/0x8c
Daniel Wagner 50bad3
[  247.027994]  ? do_wait_intr_irq+0x7a/0x7a
Daniel Wagner 50bad3
[  247.027996]  blk_cleanup_queue+0x4b/0xc9
Daniel Wagner 50bad3
[  247.028000]  __scsi_remove_device+0xf6/0x14e
Daniel Wagner 50bad3
[  247.028002]  scsi_remove_device+0x21/0x2b
Daniel Wagner 50bad3
[  247.029037]  sdev_store_delete+0x58/0x7c
Daniel Wagner 50bad3
[  247.029041]  kernfs_fop_write+0x10d/0x14f
Daniel Wagner 50bad3
[  247.031281]  vfs_write+0xa2/0xdf
Daniel Wagner 50bad3
[  247.032670]  ksys_write+0x6b/0xb3
Daniel Wagner 50bad3
[  247.032673]  do_syscall_64+0x56/0x82
Daniel Wagner 50bad3
[  247.034053]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
Daniel Wagner 50bad3
[  247.034059] RIP: 0033:0x7f69f39e9008
Daniel Wagner 50bad3
[  247.036330] Code: Bad RIP value.
Daniel Wagner 50bad3
[  247.036331] RSP: 002b:00007ffdd8116498 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
Daniel Wagner 50bad3
[  247.037613] RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007f69f39e9008
Daniel Wagner 50bad3
[  247.039714] RDX: 0000000000000002 RSI: 000055cde92a0ab0 RDI: 0000000000000001
Daniel Wagner 50bad3
[  247.039715] RBP: 000055cde92a0ab0 R08: 000000000000000a R09: 00007f69f3a79e80
Daniel Wagner 50bad3
[  247.039716] R10: 000000000000000a R11: 0000000000000246 R12: 00007f69f3abb780
Daniel Wagner 50bad3
[  247.039717] R13: 0000000000000002 R14: 00007f69f3ab6740 R15: 0000000000000002
Daniel Wagner 50bad3
Daniel Wagner 50bad3
Link: https://lore.kernel.org/r/20200720025435.812030-1-ming.lei@redhat.com
Daniel Wagner 50bad3
Cc: linux-block@vger.kernel.org
Daniel Wagner 50bad3
Cc: Christoph Hellwig <hch@lst.de>
Daniel Wagner 50bad3
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Daniel Wagner 50bad3
Reviewed-by: Christoph Hellwig <hch@lst.de>
Daniel Wagner 50bad3
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Daniel Wagner 50bad3
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Daniel Wagner 50bad3
Acked-by: Daniel Wagner <dwagner@suse.de>
Daniel Wagner 50bad3
---
Daniel Wagner 50bad3
 drivers/scsi/scsi_lib.c |   16 +++++++++++-----
Daniel Wagner 50bad3
 1 file changed, 11 insertions(+), 5 deletions(-)
Daniel Wagner 50bad3
Daniel Wagner 50bad3
--- a/drivers/scsi/scsi_lib.c
Daniel Wagner 50bad3
+++ b/drivers/scsi/scsi_lib.c
Daniel Wagner 50bad3
@@ -568,6 +568,15 @@ static void scsi_mq_uninit_cmd(struct sc
Daniel Wagner 50bad3
 	scsi_del_cmd_from_list(cmd);
Daniel Wagner 50bad3
 }
Daniel Wagner 50bad3
 
Daniel Wagner 50bad3
+static void scsi_run_queue_async(struct scsi_device *sdev)
Daniel Wagner 50bad3
+{
Daniel Wagner 50bad3
+	if (scsi_target(sdev)->single_lun ||
Daniel Wagner 50bad3
+	    !list_empty(&sdev->host->starved_list))
Daniel Wagner 50bad3
+		kblockd_schedule_work(&sdev->requeue_work);
Daniel Wagner 50bad3
+	else
Daniel Wagner 50bad3
+		blk_mq_run_hw_queues(sdev->request_queue, true);
Daniel Wagner 50bad3
+}
Daniel Wagner 50bad3
+
Daniel Wagner 50bad3
 /* Returns false when no more bytes to process, true if there are more */
Daniel Wagner 50bad3
 static bool scsi_end_request(struct request *req, blk_status_t error,
Daniel Wagner 50bad3
 		unsigned int bytes)
Daniel Wagner 50bad3
@@ -612,11 +621,7 @@ static bool scsi_end_request(struct requ
Daniel Wagner 50bad3
 
Daniel Wagner 50bad3
 	__blk_mq_end_request(req, error);
Daniel Wagner 50bad3
 
Daniel Wagner 50bad3
-	if (scsi_target(sdev)->single_lun ||
Daniel Wagner 50bad3
-	    !list_empty(&sdev->host->starved_list))
Daniel Wagner 50bad3
-		kblockd_schedule_work(&sdev->requeue_work);
Daniel Wagner 50bad3
-	else
Daniel Wagner 50bad3
-		blk_mq_run_hw_queues(q, true);
Daniel Wagner 50bad3
+	scsi_run_queue_async(sdev);
Daniel Wagner 50bad3
 
Daniel Wagner 50bad3
 	percpu_ref_put(&q->q_usage_counter);
Daniel Wagner 50bad3
 	return false;
Daniel Wagner 50bad3
@@ -1726,6 +1731,7 @@ static blk_status_t scsi_queue_rq(struct
Daniel Wagner 50bad3
 		 */
Daniel Wagner 50bad3
 		if (req->rq_flags & RQF_DONTPREP)
Daniel Wagner 50bad3
 			scsi_mq_uninit_cmd(cmd);
Daniel Wagner 50bad3
+		scsi_run_queue_async(sdev);
Daniel Wagner 50bad3
 		break;
Daniel Wagner 50bad3
 	}
Daniel Wagner 50bad3
 	return ret;