diff options
author | Quinn Tran <quinn.tran@cavium.com> | 2017-12-28 23:33:43 +0300 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2018-01-04 07:41:08 +0300 |
commit | d8630bb95f46ea118dede63bd75533faa64f9612 (patch) | |
tree | 845f81a334b1d0b06d24e3e539c60d06e0738914 /drivers/scsi/qla2xxx/qla_target.c | |
parent | 94cff6e114df56d0df74cdabe3481df38d9b0c1e (diff) | |
download | linux-d8630bb95f46ea118dede63bd75533faa64f9612.tar.xz |
scsi: qla2xxx: Serialize session deletion by using work_lock
for session deletion, replace sess_lock with work_lock.
Under certain case sess_lock is not feasiable to acquire.
The lock is needed temporarily to make sure a single
call to schedule of the work element.
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/qla2xxx/qla_target.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.c | 29 |
1 files changed, 14 insertions, 15 deletions
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 867d089c3ebe..72b452db26da 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -1214,6 +1214,7 @@ static void qla24xx_chk_fcp_state(struct fc_port *sess) void qlt_schedule_sess_for_deletion(struct fc_port *sess) { struct qla_tgt *tgt = sess->tgt; + unsigned long flags; if (sess->disc_state == DSC_DELETE_PEND) return; @@ -1229,12 +1230,19 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess) return; } - sess->disc_state = DSC_DELETE_PEND; - if (sess->deleted == QLA_SESS_DELETED) sess->logout_on_delete = 0; + spin_lock_irqsave(&sess->vha->work_lock, flags); + if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) { + spin_unlock_irqrestore(&sess->vha->work_lock, flags); + return; + } sess->deleted = QLA_SESS_DELETION_IN_PROGRESS; + spin_unlock_irqrestore(&sess->vha->work_lock, flags); + + sess->disc_state = DSC_DELETE_PEND; + qla24xx_chk_fcp_state(sess); ql_dbg(ql_dbg_tgt, sess->vha, 0xe001, @@ -1246,15 +1254,6 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess) queue_work(sess->vha->hw->wq, &sess->del_work); } -void qlt_schedule_sess_for_deletion_lock(struct fc_port *sess) -{ - unsigned long flags; - struct qla_hw_data *ha = sess->vha->hw; - spin_lock_irqsave(&ha->tgt.sess_lock, flags); - qlt_schedule_sess_for_deletion(sess); - spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); -} - /* ha->tgt.sess_lock supposed to be held on entry */ static void qlt_clear_tgt_db(struct qla_tgt *tgt) { @@ -2210,7 +2209,7 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd) "TM response logo %phC status %#x state %#x", mcmd->sess->port_name, mcmd->fc_tm_rsp, mcmd->flags); - qlt_schedule_sess_for_deletion_lock(mcmd->sess); + qlt_schedule_sess_for_deletion(mcmd->sess); } else { qlt_send_notify_ack(vha->hw->base_qpair, &mcmd->orig_iocb.imm_ntfy, 0, 0, 0, 0, 0, 0); @@ -3905,7 +3904,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, "%s %d %8phC post del sess\n", __func__, __LINE__, cmd->sess->port_name); - qlt_schedule_sess_for_deletion_lock(cmd->sess); + qlt_schedule_sess_for_deletion(cmd->sess); } break; } @@ -4723,7 +4722,7 @@ static int qlt_handle_login(struct scsi_qla_host *vha, __func__, __LINE__, sess->port_name); - qlt_schedule_sess_for_deletion_lock(sess); + qlt_schedule_sess_for_deletion(sess); break; } out: @@ -4951,7 +4950,7 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha, } else { /* cmd did not go to upper layer. */ if (sess) { - qlt_schedule_sess_for_deletion_lock(sess); + qlt_schedule_sess_for_deletion(sess); res = 0; } /* else logo will be ack */ |