scsi: qla2xxx: Fix stuck session in GNL
Fix race condition between GNL completion processing and GNL request. Late submission of GNL request was not seen by the GNL completion thread. This patch will re-submit the GNL request for late submission fcport. Link: https://lore.kernel.org/r/20191217220617.28084-13-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>
This commit is contained in:
parent
118f01e7d9
commit
e1217dc3ed
|
@ -990,7 +990,7 @@ static void qla24xx_async_gnl_sp_done(srb_t *sp, int res)
|
|||
set_bit(loop_id, vha->hw->loop_id_map);
|
||||
wwn = wwn_to_u64(e->port_name);
|
||||
|
||||
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x20e8,
|
||||
ql_dbg(ql_dbg_disc, vha, 0x20e8,
|
||||
"%s %8phC %02x:%02x:%02x CLS %x/%x lid %x \n",
|
||||
__func__, (void *)&wwn, e->port_id[2], e->port_id[1],
|
||||
e->port_id[0], e->current_login_state, e->last_login_state,
|
||||
|
@ -1049,6 +1049,16 @@ static void qla24xx_async_gnl_sp_done(srb_t *sp, int res)
|
|||
|
||||
spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
|
||||
vha->gnl.sent = 0;
|
||||
if (!list_empty(&vha->gnl.fcports)) {
|
||||
/* retrigger gnl */
|
||||
list_for_each_entry_safe(fcport, tf, &vha->gnl.fcports,
|
||||
gnl_entry) {
|
||||
list_del_init(&fcport->gnl_entry);
|
||||
fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
|
||||
if (qla24xx_post_gnl_work(vha, fcport) == QLA_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
|
||||
|
||||
sp->free(sp);
|
||||
|
@ -2000,7 +2010,7 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
|
|||
qla24xx_post_prli_work(vha, ea->fcport);
|
||||
} else {
|
||||
ql_dbg(ql_dbg_disc, vha, 0x20ea,
|
||||
"%s %d %8phC LoopID 0x%x in use with %06x. post gnl\n",
|
||||
"%s %d %8phC LoopID 0x%x in use with %06x. post gpdb\n",
|
||||
__func__, __LINE__, ea->fcport->port_name,
|
||||
ea->fcport->loop_id, ea->fcport->d_id.b24);
|
||||
|
||||
|
@ -2071,6 +2081,7 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
|
|||
set_bit(lid, vha->hw->loop_id_map);
|
||||
ea->fcport->loop_id = lid;
|
||||
ea->fcport->keep_nport_handle = 0;
|
||||
ea->fcport->logout_on_delete = 1;
|
||||
qlt_schedule_sess_for_deletion(ea->fcport);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -958,7 +958,7 @@ void qlt_free_session_done(struct work_struct *work)
|
|||
struct qlt_plogi_ack_t *own =
|
||||
sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN];
|
||||
|
||||
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf084,
|
||||
ql_dbg(ql_dbg_disc, vha, 0xf084,
|
||||
"%s: se_sess %p / sess %p from port %8phC loop_id %#04x"
|
||||
" s_id %02x:%02x:%02x logout %d keep %d els_logo %d\n",
|
||||
__func__, sess->se_sess, sess, sess->port_name, sess->loop_id,
|
||||
|
@ -1025,7 +1025,7 @@ void qlt_free_session_done(struct work_struct *work)
|
|||
|
||||
while (!READ_ONCE(sess->logout_completed)) {
|
||||
if (!traced) {
|
||||
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf086,
|
||||
ql_dbg(ql_dbg_disc, vha, 0xf086,
|
||||
"%s: waiting for sess %p logout\n",
|
||||
__func__, sess);
|
||||
traced = true;
|
||||
|
@ -1046,6 +1046,10 @@ void qlt_free_session_done(struct work_struct *work)
|
|||
(struct imm_ntfy_from_isp *)sess->iocb, SRB_NACK_LOGO);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&vha->work_lock, flags);
|
||||
sess->flags &= ~FCF_ASYNC_SENT;
|
||||
spin_unlock_irqrestore(&vha->work_lock, flags);
|
||||
|
||||
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
|
||||
if (sess->se_sess) {
|
||||
sess->se_sess = NULL;
|
||||
|
@ -1109,7 +1113,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,
|
||||
ql_dbg(ql_dbg_disc, vha, 0xf001,
|
||||
"Unregistration of sess %p %8phC finished fcp_cnt %d\n",
|
||||
sess, sess->port_name, vha->fcport_count);
|
||||
|
||||
|
@ -1152,6 +1156,11 @@ void qlt_unreg_sess(struct fc_port *sess)
|
|||
return;
|
||||
}
|
||||
sess->free_pending = 1;
|
||||
/*
|
||||
* Use FCF_ASYNC_SENT flag to block other cmds used in sess
|
||||
* management from being sent.
|
||||
*/
|
||||
sess->flags |= FCF_ASYNC_SENT;
|
||||
spin_unlock_irqrestore(&sess->vha->work_lock, flags);
|
||||
|
||||
if (sess->se_sess)
|
||||
|
@ -4581,7 +4590,7 @@ qlt_find_sess_invalidate_other(scsi_qla_host_t *vha, uint64_t wwn,
|
|||
/* find other sess with nport_id collision */
|
||||
if (port_id.b24 == other_sess->d_id.b24) {
|
||||
if (loop_id != other_sess->loop_id) {
|
||||
ql_dbg(ql_dbg_tgt_tmr, vha, 0x1000c,
|
||||
ql_dbg(ql_dbg_disc, vha, 0x1000c,
|
||||
"Invalidating sess %p loop_id %d wwn %llx.\n",
|
||||
other_sess, other_sess->loop_id, other_wwn);
|
||||
|
||||
|
@ -4597,7 +4606,7 @@ qlt_find_sess_invalidate_other(scsi_qla_host_t *vha, uint64_t wwn,
|
|||
* Another wwn used to have our s_id/loop_id
|
||||
* kill the session, but don't free the loop_id
|
||||
*/
|
||||
ql_dbg(ql_dbg_tgt_tmr, vha, 0xf01b,
|
||||
ql_dbg(ql_dbg_disc, vha, 0xf01b,
|
||||
"Invalidating sess %p loop_id %d wwn %llx.\n",
|
||||
other_sess, other_sess->loop_id, other_wwn);
|
||||
|
||||
|
@ -4612,7 +4621,7 @@ qlt_find_sess_invalidate_other(scsi_qla_host_t *vha, uint64_t wwn,
|
|||
/* find other sess with nport handle collision */
|
||||
if ((loop_id == other_sess->loop_id) &&
|
||||
(loop_id != FC_NO_LOOP_ID)) {
|
||||
ql_dbg(ql_dbg_tgt_tmr, vha, 0x1000d,
|
||||
ql_dbg(ql_dbg_disc, vha, 0x1000d,
|
||||
"Invalidating sess %p loop_id %d wwn %llx.\n",
|
||||
other_sess, other_sess->loop_id, other_wwn);
|
||||
|
||||
|
|
Loading…
Reference in New Issue