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