summaryrefslogtreecommitdiff
path: root/drivers/scsi/lpfc/lpfc_nvme.c
diff options
context:
space:
mode:
authorJames Smart <jsmart2021@gmail.com>2018-05-24 21:08:59 -0700
committerMartin K. Petersen <martin.petersen@oracle.com>2018-05-28 22:40:33 -0400
commit7438273fa23bea6d1e647e66c451570b86e2758b (patch)
tree5d5ee28789dc9ea6c93fc403c50b708442a8a589 /drivers/scsi/lpfc/lpfc_nvme.c
parent4d5e789a2eb111d7f9e032d0ebaecb465a2eca8f (diff)
scsi: lpfc: Fix crash in blk_mq layer when executing modprobe -r lpfc
modprobe -r lpfc produces the following: Call Trace: __blk_mq_run_hw_queue+0xa2/0xb0 __blk_mq_delay_run_hw_queue+0x9d/0xb0 ? blk_mq_hctx_has_pending+0x32/0x80 blk_mq_run_hw_queue+0x50/0xd0 blk_mq_sched_insert_request+0x110/0x1b0 blk_execute_rq_nowait+0x76/0x180 nvme_keep_alive_work+0x8a/0xd0 [nvme_core] process_one_work+0x17f/0x440 worker_thread+0x126/0x3c0 ? manage_workers.isra.24+0x2a0/0x2a0 kthread+0xd1/0xe0 ? insert_kthread_work+0x40/0x40 ret_from_fork_nospec_begin+0x21/0x21 ? insert_kthread_work+0x40/0x40 However, rmmod lpfc would run correctly. When an nvme remoteport is unregistered with the host nvme transport, it needs to set the remoteport->dev_loss_tmo value 0 to indicate an immediate termination of device loss and prevent any further keep alives to that rport. The driver was never setting dev_loss_tmo causing the nvme transport to continue to send the keep alive. Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: James Smart <james.smart@broadcom.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_nvme.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_nvme.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 288dd3caff8a..76a5a99605aa 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -2862,6 +2862,15 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
* The transport will update it.
*/
ndlp->upcall_flags |= NLP_WAIT_FOR_UNREG;
+
+ /* Don't let the host nvme transport keep sending keep-alives
+ * on this remoteport. Vport is unloading, no recovery. The
+ * return values is ignored. The upcall is a courtesy to the
+ * transport.
+ */
+ if (vport->load_flag & FC_UNLOADING)
+ (void)nvme_fc_set_remoteport_devloss(remoteport, 0);
+
ret = nvme_fc_unregister_remoteport(remoteport);
if (ret != 0) {
lpfc_nlp_put(ndlp);