forked from Minki/linux
qla2xxx: Fix hardware lock/unlock issue causing kernel panic.
[ Upstream commitef86cb2059
] This patch fixes a kernel panic for qla2xxx Target core Module driver introduced by a fix in the qla2xxx initiator code. Commitef86cb2
("qla2xxx: Mark port lost when we receive an RSCN for it.") introduced the regression for qla2xxx Target driver. Stack trace will have following signature --- <NMI exception stack> --- [ffff88081faa3cc8] _raw_spin_lock_irqsave at ffffffff815b1f03 [ffff88081faa3cd0] qlt_fc_port_deleted at ffffffffa096ccd0 [qla2xxx] [ffff88081faa3d20] qla2x00_schedule_rport_del at ffffffffa0913831[qla2xxx] [ffff88081faa3d50] qla2x00_mark_device_lost at ffffffffa09159c5[qla2xxx] [ffff88081faa3db0] qla2x00_async_event at ffffffffa0938d59 [qla2xxx] [ffff88081faa3e30] qla24xx_msix_default at ffffffffa093a326 [qla2xxx] [ffff88081faa3e90] handle_irq_event_percpu at ffffffff810a7b8d [ffff88081faa3ee0] handle_irq_event at ffffffff810a7d32 [ffff88081faa3f10] handle_edge_irq at ffffffff810ab6b9 [ffff88081faa3f30] handle_irq at ffffffff8100619c [ffff88081faa3f70] do_IRQ at ffffffff815b4b1c --- <IRQ stack> --- Cc: <stable@vger.kernel.org> # v3.18+ Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com> Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com> Reviewed-by: Nicholas Bellinger <nab@linux-iscsi.org> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
c20910264c
commit
ba9f6f64a0
@ -2924,6 +2924,7 @@ qla2x00_rport_del(void *data)
|
|||||||
struct fc_rport *rport;
|
struct fc_rport *rport;
|
||||||
scsi_qla_host_t *vha = fcport->vha;
|
scsi_qla_host_t *vha = fcport->vha;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
unsigned long vha_flags;
|
||||||
|
|
||||||
spin_lock_irqsave(fcport->vha->host->host_lock, flags);
|
spin_lock_irqsave(fcport->vha->host->host_lock, flags);
|
||||||
rport = fcport->drport ? fcport->drport: fcport->rport;
|
rport = fcport->drport ? fcport->drport: fcport->rport;
|
||||||
@ -2935,7 +2936,9 @@ qla2x00_rport_del(void *data)
|
|||||||
* Release the target mode FC NEXUS in qla_target.c code
|
* Release the target mode FC NEXUS in qla_target.c code
|
||||||
* if target mod is enabled.
|
* if target mod is enabled.
|
||||||
*/
|
*/
|
||||||
|
spin_lock_irqsave(&vha->hw->hardware_lock, vha_flags);
|
||||||
qlt_fc_port_deleted(vha, fcport);
|
qlt_fc_port_deleted(vha, fcport);
|
||||||
|
spin_unlock_irqrestore(&vha->hw->hardware_lock, vha_flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3303,6 +3306,7 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport)
|
|||||||
* Create target mode FC NEXUS in qla_target.c if target mode is
|
* Create target mode FC NEXUS in qla_target.c if target mode is
|
||||||
* enabled..
|
* enabled..
|
||||||
*/
|
*/
|
||||||
|
|
||||||
qlt_fc_port_added(vha, fcport);
|
qlt_fc_port_added(vha, fcport);
|
||||||
|
|
||||||
spin_lock_irqsave(fcport->vha->host->host_lock, flags);
|
spin_lock_irqsave(fcport->vha->host->host_lock, flags);
|
||||||
|
@ -782,10 +782,8 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport)
|
|||||||
|
|
||||||
void qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport)
|
void qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport)
|
||||||
{
|
{
|
||||||
struct qla_hw_data *ha = vha->hw;
|
|
||||||
struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
|
struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
|
||||||
struct qla_tgt_sess *sess;
|
struct qla_tgt_sess *sess;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (!vha->hw->tgt.tgt_ops)
|
if (!vha->hw->tgt.tgt_ops)
|
||||||
return;
|
return;
|
||||||
@ -793,14 +791,11 @@ void qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport)
|
|||||||
if (!tgt || (fcport->port_type != FCT_INITIATOR))
|
if (!tgt || (fcport->port_type != FCT_INITIATOR))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
|
||||||
if (tgt->tgt_stop) {
|
if (tgt->tgt_stop) {
|
||||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sess = qlt_find_sess_by_port_name(tgt, fcport->port_name);
|
sess = qlt_find_sess_by_port_name(tgt, fcport->port_name);
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -808,7 +803,6 @@ void qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport)
|
|||||||
|
|
||||||
sess->local = 1;
|
sess->local = 1;
|
||||||
qlt_schedule_sess_for_deletion(sess, false);
|
qlt_schedule_sess_for_deletion(sess, false);
|
||||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int test_tgt_sess_count(struct qla_tgt *tgt)
|
static inline int test_tgt_sess_count(struct qla_tgt *tgt)
|
||||||
|
Loading…
Reference in New Issue
Block a user