Commit d8630bb9 authored by Quinn Tran's avatar Quinn Tran Committed by Martin K. Petersen

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: default avatarQuinn Tran <quinn.tran@cavium.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 94cff6e1
...@@ -888,7 +888,6 @@ void qlt_plogi_ack_link(struct scsi_qla_host *, struct qlt_plogi_ack_t *, ...@@ -888,7 +888,6 @@ void qlt_plogi_ack_link(struct scsi_qla_host *, struct qlt_plogi_ack_t *,
struct fc_port *, enum qlt_plogi_link_t); struct fc_port *, enum qlt_plogi_link_t);
void qlt_plogi_ack_unref(struct scsi_qla_host *, struct qlt_plogi_ack_t *); void qlt_plogi_ack_unref(struct scsi_qla_host *, struct qlt_plogi_ack_t *);
extern void qlt_schedule_sess_for_deletion(struct fc_port *); extern void qlt_schedule_sess_for_deletion(struct fc_port *);
extern void qlt_schedule_sess_for_deletion_lock(struct fc_port *);
extern struct fc_port *qlt_find_sess_invalidate_other(scsi_qla_host_t *, extern struct fc_port *qlt_find_sess_invalidate_other(scsi_qla_host_t *,
uint64_t wwn, port_id_t port_id, uint16_t loop_id, struct fc_port **); uint64_t wwn, port_id_t port_id, uint16_t loop_id, struct fc_port **);
void qla24xx_delete_sess_fn(struct work_struct *); void qla24xx_delete_sess_fn(struct work_struct *);
......
...@@ -3047,7 +3047,7 @@ void qla24xx_handle_gidpn_event(scsi_qla_host_t *vha, struct event_arg *ea) ...@@ -3047,7 +3047,7 @@ void qla24xx_handle_gidpn_event(scsi_qla_host_t *vha, struct event_arg *ea)
ql_dbg(ql_dbg_disc, vha, 0x2021, ql_dbg(ql_dbg_disc, vha, 0x2021,
"%s %d %8phC post del sess\n", "%s %d %8phC post del sess\n",
__func__, __LINE__, fcport->port_name); __func__, __LINE__, fcport->port_name);
qlt_schedule_sess_for_deletion_lock(fcport); qlt_schedule_sess_for_deletion(fcport);
} }
} }
} else { /* ea->sp->gen1 != fcport->rscn_gen */ } else { /* ea->sp->gen1 != fcport->rscn_gen */
...@@ -3064,7 +3064,7 @@ void qla24xx_handle_gidpn_event(scsi_qla_host_t *vha, struct event_arg *ea) ...@@ -3064,7 +3064,7 @@ void qla24xx_handle_gidpn_event(scsi_qla_host_t *vha, struct event_arg *ea)
ql_dbg(ql_dbg_disc, vha, 0x2042, ql_dbg(ql_dbg_disc, vha, 0x2042,
"%s %d %8phC post del sess\n", __func__, "%s %d %8phC post del sess\n", __func__,
__LINE__, fcport->port_name); __LINE__, fcport->port_name);
qlt_schedule_sess_for_deletion_lock(fcport); qlt_schedule_sess_for_deletion(fcport);
} else { } else {
ql_dbg(ql_dbg_disc, vha, 0x2045, ql_dbg(ql_dbg_disc, vha, 0x2045,
"%s %d %8phC login\n", __func__, __LINE__, "%s %d %8phC login\n", __func__, __LINE__,
...@@ -3436,8 +3436,7 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea) ...@@ -3436,8 +3436,7 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
"%s %d %8phC post del sess\n", "%s %d %8phC post del sess\n",
__func__, __LINE__, __func__, __LINE__,
fcport->port_name); fcport->port_name);
qlt_schedule_sess_for_deletion_lock qlt_schedule_sess_for_deletion(fcport);
(fcport);
break; break;
} }
} }
...@@ -3470,7 +3469,7 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea) ...@@ -3470,7 +3469,7 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
"%s %d %8phC post del sess\n", "%s %d %8phC post del sess\n",
__func__, __LINE__, __func__, __LINE__,
conflict->port_name); conflict->port_name);
qlt_schedule_sess_for_deletion_lock qlt_schedule_sess_for_deletion
(conflict); (conflict);
break; break;
} }
...@@ -3528,7 +3527,7 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea) ...@@ -3528,7 +3527,7 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
"%s %d %8phC post del sess\n", "%s %d %8phC post del sess\n",
__func__, __LINE__, __func__, __LINE__,
conflict->port_name); conflict->port_name);
qlt_schedule_sess_for_deletion_lock qlt_schedule_sess_for_deletion
(conflict); (conflict);
break; break;
} }
...@@ -3959,8 +3958,7 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) ...@@ -3959,8 +3958,7 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
__func__, __LINE__, __func__, __LINE__,
fcport->port_name); fcport->port_name);
qlt_schedule_sess_for_deletion_lock qlt_schedule_sess_for_deletion(fcport);
(fcport);
continue; continue;
} }
} }
......
...@@ -1091,7 +1091,7 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea) ...@@ -1091,7 +1091,7 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
default: default:
ql_dbg(ql_dbg_disc, vha, 0x20d5, "%s %d %8phC post del sess\n", ql_dbg(ql_dbg_disc, vha, 0x20d5, "%s %d %8phC post del sess\n",
__func__, __LINE__, fcport->port_name); __func__, __LINE__, fcport->port_name);
qlt_schedule_sess_for_deletion_lock(fcport); qlt_schedule_sess_for_deletion(fcport);
return; return;
} }
__qla24xx_handle_gpdb_event(vha, ea); __qla24xx_handle_gpdb_event(vha, ea);
...@@ -4964,8 +4964,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha) ...@@ -4964,8 +4964,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
__func__, __LINE__, __func__, __LINE__,
fcport->port_name); fcport->port_name);
qlt_schedule_sess_for_deletion_lock qlt_schedule_sess_for_deletion(fcport);
(fcport);
continue; continue;
} }
} }
...@@ -5552,9 +5551,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) ...@@ -5552,9 +5551,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
"%s %d %8phC post del sess\n", "%s %d %8phC post del sess\n",
__func__, __LINE__, __func__, __LINE__,
fcport->port_name); fcport->port_name);
qlt_schedule_sess_for_deletion(fcport);
qlt_schedule_sess_for_deletion_lock
(fcport);
continue; continue;
} }
} }
......
...@@ -1009,7 +1009,7 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) ...@@ -1009,7 +1009,7 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
if (qla_ini_mode_enabled(vha)) { if (qla_ini_mode_enabled(vha)) {
qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1); qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1);
fcport->logout_on_delete = 0; fcport->logout_on_delete = 0;
qlt_schedule_sess_for_deletion_lock(fcport); qlt_schedule_sess_for_deletion(fcport);
} }
break; break;
...@@ -2701,7 +2701,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) ...@@ -2701,7 +2701,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
comp_status); comp_status);
qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1); qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1);
qlt_schedule_sess_for_deletion_lock(fcport); qlt_schedule_sess_for_deletion(fcport);
} }
break; break;
......
...@@ -3896,7 +3896,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, ...@@ -3896,7 +3896,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
case DSC_DELETE_PEND: case DSC_DELETE_PEND:
break; break;
default: default:
qlt_schedule_sess_for_deletion_lock(fcport); qlt_schedule_sess_for_deletion(fcport);
break; break;
} }
} else { } else {
......
...@@ -3869,7 +3869,7 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer) ...@@ -3869,7 +3869,7 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer)
list_for_each_entry(fcport, &vha->vp_fcports, list) { list_for_each_entry(fcport, &vha->vp_fcports, list) {
fcport->scan_state = 0; fcport->scan_state = 0;
qlt_schedule_sess_for_deletion_lock(fcport); qlt_schedule_sess_for_deletion(fcport);
if (vha->vp_idx != 0 && vha->vp_idx != fcport->vha->vp_idx) if (vha->vp_idx != 0 && vha->vp_idx != fcport->vha->vp_idx)
continue; continue;
...@@ -4897,8 +4897,7 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e) ...@@ -4897,8 +4897,7 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
default: default:
fcport->login_pause = 1; fcport->login_pause = 1;
tfcp->conflict = fcport; tfcp->conflict = fcport;
qlt_schedule_sess_for_deletion_lock qlt_schedule_sess_for_deletion(tfcp);
(tfcp);
break; break;
} }
} }
......
...@@ -1214,6 +1214,7 @@ static void qla24xx_chk_fcp_state(struct fc_port *sess) ...@@ -1214,6 +1214,7 @@ static void qla24xx_chk_fcp_state(struct fc_port *sess)
void qlt_schedule_sess_for_deletion(struct fc_port *sess) void qlt_schedule_sess_for_deletion(struct fc_port *sess)
{ {
struct qla_tgt *tgt = sess->tgt; struct qla_tgt *tgt = sess->tgt;
unsigned long flags;
if (sess->disc_state == DSC_DELETE_PEND) if (sess->disc_state == DSC_DELETE_PEND)
return; return;
...@@ -1229,12 +1230,19 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess) ...@@ -1229,12 +1230,19 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess)
return; return;
} }
sess->disc_state = DSC_DELETE_PEND;
if (sess->deleted == QLA_SESS_DELETED) if (sess->deleted == QLA_SESS_DELETED)
sess->logout_on_delete = 0; 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; 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); qla24xx_chk_fcp_state(sess);
ql_dbg(ql_dbg_tgt, sess->vha, 0xe001, ql_dbg(ql_dbg_tgt, sess->vha, 0xe001,
...@@ -1246,15 +1254,6 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess) ...@@ -1246,15 +1254,6 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess)
queue_work(sess->vha->hw->wq, &sess->del_work); 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 */ /* ha->tgt.sess_lock supposed to be held on entry */
static void qlt_clear_tgt_db(struct qla_tgt *tgt) 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) ...@@ -2210,7 +2209,7 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd)
"TM response logo %phC status %#x state %#x", "TM response logo %phC status %#x state %#x",
mcmd->sess->port_name, mcmd->fc_tm_rsp, mcmd->sess->port_name, mcmd->fc_tm_rsp,
mcmd->flags); mcmd->flags);
qlt_schedule_sess_for_deletion_lock(mcmd->sess); qlt_schedule_sess_for_deletion(mcmd->sess);
} else { } else {
qlt_send_notify_ack(vha->hw->base_qpair, qlt_send_notify_ack(vha->hw->base_qpair,
&mcmd->orig_iocb.imm_ntfy, 0, 0, 0, 0, 0, 0); &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, ...@@ -3905,7 +3904,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha,
"%s %d %8phC post del sess\n", "%s %d %8phC post del sess\n",
__func__, __LINE__, cmd->sess->port_name); __func__, __LINE__, cmd->sess->port_name);
qlt_schedule_sess_for_deletion_lock(cmd->sess); qlt_schedule_sess_for_deletion(cmd->sess);
} }
break; break;
} }
...@@ -4723,7 +4722,7 @@ static int qlt_handle_login(struct scsi_qla_host *vha, ...@@ -4723,7 +4722,7 @@ static int qlt_handle_login(struct scsi_qla_host *vha,
__func__, __LINE__, sess->port_name); __func__, __LINE__, sess->port_name);
qlt_schedule_sess_for_deletion_lock(sess); qlt_schedule_sess_for_deletion(sess);
break; break;
} }
out: out:
...@@ -4951,7 +4950,7 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha, ...@@ -4951,7 +4950,7 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
} else { } else {
/* cmd did not go to upper layer. */ /* cmd did not go to upper layer. */
if (sess) { if (sess) {
qlt_schedule_sess_for_deletion_lock(sess); qlt_schedule_sess_for_deletion(sess);
res = 0; res = 0;
} }
/* else logo will be ack */ /* else logo will be ack */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment