diff options
author | Quinn Tran <quinn.tran@cavium.com> | 2017-12-28 12:33:44 -0800 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2018-01-03 23:41:08 -0500 |
commit | 1ae634eb28533b82f9777a47c1ade44cb8c0182b (patch) | |
tree | 28806934989911aac971e0a95bbb18f387711348 /drivers/scsi | |
parent | d8630bb95f46ea118dede63bd75533faa64f9612 (diff) |
scsi: qla2xxx: Serialize session free in qlt_free_session_done
Add free_pending flag to serialize queueing of
free_work element onto the work queue
Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.c | 13 |
2 files changed, 14 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index ac2f340bc1c6..f7396a2e28ba 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2334,6 +2334,7 @@ typedef struct fc_port { unsigned int conf_compl_supported:1; unsigned int deleted:2; + unsigned int free_pending:1; unsigned int local:1; unsigned int logout_on_delete:1; unsigned int logo_ack_needed:1; diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 72b452db26da..0d3c3f647f91 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -1105,6 +1105,7 @@ static void qlt_free_session_done(struct work_struct *work) sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN] = NULL; } } + spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); ql_dbg(ql_dbg_tgt_mgt, vha, 0xf001, @@ -1118,6 +1119,9 @@ static void qlt_free_session_done(struct work_struct *work) 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; @@ -1140,11 +1144,20 @@ static void qlt_free_session_done(struct work_struct *work) void qlt_unreg_sess(struct fc_port *sess) { struct scsi_qla_host *vha = sess->vha; + unsigned long flags; ql_dbg(ql_dbg_disc, sess->vha, 0x210a, "%s sess %p for deletion %8phC\n", __func__, sess, sess->port_name); + spin_lock_irqsave(&sess->vha->work_lock, flags); + if (sess->free_pending) { + spin_unlock_irqrestore(&sess->vha->work_lock, flags); + return; + } + sess->free_pending = 1; + spin_unlock_irqrestore(&sess->vha->work_lock, flags); + if (sess->se_sess) vha->hw->tgt.tgt_ops->clear_nacl_from_fcport_map(sess); |