summaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp
diff options
context:
space:
mode:
authorBart Van Assche <bvanassche@acm.org>2019-06-17 11:18:20 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2019-06-20 15:37:02 -0400
commitfd56141244066a6a21ef458670071c58b6402035 (patch)
treedcb3ca3cbb75073084c3074c4530517d64227dac /drivers/infiniband/ulp
parentbbe9fb0d04b96dda1fd7bd973e094004978b2166 (diff)
scsi: RDMA/srp: Fix a sleep-in-invalid-context bug
The previous patch guarantees that srp_queuecommand() does not get invoked while reconnecting occurs. Hence remove the code from srp_queuecommand() that prevents command queueing while reconnecting. This patch avoids that the following can appear in the kernel log: BUG: sleeping function called from invalid context at kernel/locking/mutex.c:747 in_atomic(): 1, irqs_disabled(): 0, pid: 5600, name: scsi_eh_9 1 lock held by scsi_eh_9/5600: #0: (rcu_read_lock){....}, at: [<00000000cbb798c7>] __blk_mq_run_hw_queue+0xf1/0x1e0 Preemption disabled at: [<00000000139badf2>] __blk_mq_delay_run_hw_queue+0x78/0xf0 CPU: 9 PID: 5600 Comm: scsi_eh_9 Tainted: G W 4.15.0-rc4-dbg+ #1 Hardware name: Dell Inc. PowerEdge R720/0VWT90, BIOS 2.5.4 01/22/2016 Call Trace: dump_stack+0x67/0x99 ___might_sleep+0x16a/0x250 [ib_srp] __mutex_lock+0x46/0x9d0 srp_queuecommand+0x356/0x420 [ib_srp] scsi_dispatch_cmd+0xf6/0x3f0 scsi_queue_rq+0x4a8/0x5f0 blk_mq_dispatch_rq_list+0x73/0x440 blk_mq_sched_dispatch_requests+0x109/0x1a0 __blk_mq_run_hw_queue+0x131/0x1e0 __blk_mq_delay_run_hw_queue+0x9a/0xf0 blk_mq_run_hw_queue+0xc0/0x1e0 blk_mq_start_hw_queues+0x2c/0x40 scsi_run_queue+0x18e/0x2d0 scsi_run_host_queues+0x22/0x40 scsi_error_handler+0x18d/0x5f0 kthread+0x11c/0x140 ret_from_fork+0x24/0x30 Reviewed-by: Hannes Reinecke <hare@suse.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Laurence Oberman <loberman@redhat.com> Cc: Jason Gunthorpe <jgg@mellanox.com> Cc: Leon Romanovsky <leonro@mellanox.com> Cc: Doug Ledford <dledford@redhat.com> Signed-off-by: Bart Van Assche <bvanassche@acm.org> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/infiniband/ulp')
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c21
1 files changed, 2 insertions, 19 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index be9ddcad8f28..b7c5a35f7daa 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -2338,7 +2338,6 @@ static void srp_handle_qp_err(struct ib_cq *cq, struct ib_wc *wc,
2338static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd) 2338static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd)
2339{ 2339{
2340 struct srp_target_port *target = host_to_target(shost); 2340 struct srp_target_port *target = host_to_target(shost);
2341 struct srp_rport *rport = target->rport;
2342 struct srp_rdma_ch *ch; 2341 struct srp_rdma_ch *ch;
2343 struct srp_request *req; 2342 struct srp_request *req;
2344 struct srp_iu *iu; 2343 struct srp_iu *iu;
@@ -2348,16 +2347,6 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd)
2348 u32 tag; 2347 u32 tag;
2349 u16 idx; 2348 u16 idx;
2350 int len, ret; 2349 int len, ret;
2351 const bool in_scsi_eh = !in_interrupt() && current == shost->ehandler;
2352
2353 /*
2354 * The SCSI EH thread is the only context from which srp_queuecommand()
2355 * can get invoked for blocked devices (SDEV_BLOCK /
2356 * SDEV_CREATED_BLOCK). Avoid racing with srp_reconnect_rport() by
2357 * locking the rport mutex if invoked from inside the SCSI EH.
2358 */
2359 if (in_scsi_eh)
2360 mutex_lock(&rport->mutex);
2361 2350
2362 scmnd->result = srp_chkready(target->rport); 2351 scmnd->result = srp_chkready(target->rport);
2363 if (unlikely(scmnd->result)) 2352 if (unlikely(scmnd->result))
@@ -2426,13 +2415,7 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd)
2426 goto err_unmap; 2415 goto err_unmap;
2427 } 2416 }
2428 2417
2429 ret = 0; 2418 return 0;
2430
2431unlock_rport:
2432 if (in_scsi_eh)
2433 mutex_unlock(&rport->mutex);
2434
2435 return ret;
2436 2419
2437err_unmap: 2420err_unmap:
2438 srp_unmap_data(scmnd, ch, req); 2421 srp_unmap_data(scmnd, ch, req);
@@ -2454,7 +2437,7 @@ err:
2454 ret = SCSI_MLQUEUE_HOST_BUSY; 2437 ret = SCSI_MLQUEUE_HOST_BUSY;
2455 } 2438 }
2456 2439
2457 goto unlock_rport; 2440 return ret;
2458} 2441}
2459 2442
2460/* 2443/*