mirror of
https://github.com/SCST-project/scst.git
synced 2026-08-18 05:06:31 +00:00
qla2x00t-32gbit: 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/20190912180918.6436-4-hmadhani@marvell.com Signed-off-by: Quinn Tran <qutran@marvell.com> Signed-off-by: Himanshu Madhani <hmadhani@marvell.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> [ commit fd5564ba54e0d8a9e3e823d311b764232e09eb5f upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8641 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -1155,6 +1155,7 @@ qla2x00_wait_for_sess_deletion(scsi_qla_host_t *vha)
|
||||
qla2x00_mark_all_devices_lost(vha, 0);
|
||||
|
||||
wait_event_timeout(vha->fcport_waitQ, test_fcport_count(vha), 10*HZ);
|
||||
flush_workqueue(vha->hw->wq);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -966,7 +966,7 @@ void qlt_free_session_done(struct work_struct *work)
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
unsigned long flags;
|
||||
bool logout_started = false;
|
||||
scsi_qla_host_t *base_vha;
|
||||
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
|
||||
struct qlt_plogi_ack_t *own =
|
||||
sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN];
|
||||
|
||||
@@ -1118,6 +1118,7 @@ void qlt_free_session_done(struct work_struct *work)
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
|
||||
sess->free_pending = 0;
|
||||
|
||||
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf001,
|
||||
"Unregistration of sess %p %8phC finished fcp_cnt %d\n",
|
||||
@@ -1126,17 +1127,8 @@ void qlt_free_session_done(struct work_struct *work)
|
||||
if (tgt && (tgt->sess_count == 0))
|
||||
wake_up_all(&tgt->waitQ);
|
||||
|
||||
if (vha->fcport_count == 0)
|
||||
wake_up_all(&vha->fcport_waitQ);
|
||||
|
||||
base_vha = pci_get_drvdata(ha->pdev);
|
||||
|
||||
sess->free_pending = 0;
|
||||
|
||||
if (test_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags))
|
||||
return;
|
||||
|
||||
if ((!tgt || !tgt->tgt_stop) && !LOOP_TRANSITION(vha)) {
|
||||
if (!test_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags) &&
|
||||
(!tgt || !tgt->tgt_stop) && !LOOP_TRANSITION(vha)) {
|
||||
switch (vha->host->active_mode) {
|
||||
case MODE_INITIATOR:
|
||||
case MODE_DUAL:
|
||||
@@ -1149,6 +1141,9 @@ void qlt_free_session_done(struct work_struct *work)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (vha->fcport_count == 0)
|
||||
wake_up_all(&vha->fcport_waitQ);
|
||||
}
|
||||
|
||||
/* ha->tgt.sess_lock supposed to be held on entry */
|
||||
@@ -1177,7 +1172,7 @@ void qlt_unreg_sess(struct fc_port *sess)
|
||||
sess->last_rscn_gen = sess->rscn_gen;
|
||||
sess->last_login_gen = sess->login_gen;
|
||||
|
||||
schedule_work(&sess->free_work);
|
||||
queue_work(sess->vha->hw->wq, &sess->free_work);
|
||||
}
|
||||
EXPORT_SYMBOL(qlt_unreg_sess);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user