Skip to content

Commit fd5564b

Browse files
Quinn Tranmartinkpetersen
authored andcommitted
scsi: qla2xxx: Fix stale mem access on driver unload
On driver unload, 'remove_one' thread was allowed to advance, while session cleanup still lag behind. This patch ensures session deletion will finish before remove_one can advance. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Quinn Tran <[email protected]> Signed-off-by: Himanshu Madhani <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent c3b6a1d commit fd5564b

File tree

2 files changed

+9
-13
lines changed

2 files changed

+9
-13
lines changed

drivers/scsi/qla2xxx/qla_os.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,7 @@ qla2x00_wait_for_sess_deletion(scsi_qla_host_t *vha)
11181118
qla2x00_mark_all_devices_lost(vha, 0);
11191119

11201120
wait_event_timeout(vha->fcport_waitQ, test_fcport_count(vha), 10*HZ);
1121+
flush_workqueue(vha->hw->wq);
11211122
}
11221123

11231124
/*

drivers/scsi/qla2xxx/qla_target.c

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,7 @@ void qlt_free_session_done(struct work_struct *work)
953953
struct qla_hw_data *ha = vha->hw;
954954
unsigned long flags;
955955
bool logout_started = false;
956-
scsi_qla_host_t *base_vha;
956+
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
957957
struct qlt_plogi_ack_t *own =
958958
sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN];
959959

@@ -1105,6 +1105,7 @@ void qlt_free_session_done(struct work_struct *work)
11051105
}
11061106

11071107
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
1108+
sess->free_pending = 0;
11081109

11091110
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf001,
11101111
"Unregistration of sess %p %8phC finished fcp_cnt %d\n",
@@ -1113,17 +1114,8 @@ void qlt_free_session_done(struct work_struct *work)
11131114
if (tgt && (tgt->sess_count == 0))
11141115
wake_up_all(&tgt->waitQ);
11151116

1116-
if (vha->fcport_count == 0)
1117-
wake_up_all(&vha->fcport_waitQ);
1118-
1119-
base_vha = pci_get_drvdata(ha->pdev);
1120-
1121-
sess->free_pending = 0;
1122-
1123-
if (test_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags))
1124-
return;
1125-
1126-
if ((!tgt || !tgt->tgt_stop) && !LOOP_TRANSITION(vha)) {
1117+
if (!test_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags) &&
1118+
(!tgt || !tgt->tgt_stop) && !LOOP_TRANSITION(vha)) {
11271119
switch (vha->host->active_mode) {
11281120
case MODE_INITIATOR:
11291121
case MODE_DUAL:
@@ -1136,6 +1128,9 @@ void qlt_free_session_done(struct work_struct *work)
11361128
break;
11371129
}
11381130
}
1131+
1132+
if (vha->fcport_count == 0)
1133+
wake_up_all(&vha->fcport_waitQ);
11391134
}
11401135

11411136
/* ha->tgt.sess_lock supposed to be held on entry */
@@ -1165,7 +1160,7 @@ void qlt_unreg_sess(struct fc_port *sess)
11651160
sess->last_login_gen = sess->login_gen;
11661161

11671162
INIT_WORK(&sess->free_work, qlt_free_session_done);
1168-
schedule_work(&sess->free_work);
1163+
queue_work(sess->vha->hw->wq, &sess->free_work);
11691164
}
11701165
EXPORT_SYMBOL(qlt_unreg_sess);
11711166

0 commit comments

Comments
 (0)