scsi: qla2xxx: Optimize NPIV tear down process
In the case of NPIV port is being torn down, this patch will set a flag to indicate VPORT_DELETE. This would prevent relogin to be triggered. Link: https://lore.kernel.org/r/20190912180918.6436-5-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
fd5564ba54
commit
f5187b7d1a
|
@ -2920,6 +2920,8 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
|
||||||
struct qla_hw_data *ha = vha->hw;
|
struct qla_hw_data *ha = vha->hw;
|
||||||
uint16_t id = vha->vp_idx;
|
uint16_t id = vha->vp_idx;
|
||||||
|
|
||||||
|
set_bit(VPORT_DELETE, &vha->dpc_flags);
|
||||||
|
|
||||||
while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags) ||
|
while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags) ||
|
||||||
test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags))
|
test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags))
|
||||||
msleep(1000);
|
msleep(1000);
|
||||||
|
|
|
@ -4394,6 +4394,7 @@ typedef struct scsi_qla_host {
|
||||||
#define IOCB_WORK_ACTIVE 31
|
#define IOCB_WORK_ACTIVE 31
|
||||||
#define SET_ZIO_THRESHOLD_NEEDED 32
|
#define SET_ZIO_THRESHOLD_NEEDED 32
|
||||||
#define ISP_ABORT_TO_ROM 33
|
#define ISP_ABORT_TO_ROM 33
|
||||||
|
#define VPORT_DELETE 34
|
||||||
|
|
||||||
unsigned long pci_flags;
|
unsigned long pci_flags;
|
||||||
#define PFLG_DISCONNECTED 0 /* PCI device removed */
|
#define PFLG_DISCONNECTED 0 /* PCI device removed */
|
||||||
|
|
|
@ -3102,7 +3102,8 @@ int qla24xx_post_gpnid_work(struct scsi_qla_host *vha, port_id_t *id)
|
||||||
{
|
{
|
||||||
struct qla_work_evt *e;
|
struct qla_work_evt *e;
|
||||||
|
|
||||||
if (test_bit(UNLOADING, &vha->dpc_flags))
|
if (test_bit(UNLOADING, &vha->dpc_flags) ||
|
||||||
|
(vha->vp_idx && test_bit(VPORT_DELETE, &vha->dpc_flags)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
e = qla2x00_alloc_work(vha, QLA_EVT_GPNID);
|
e = qla2x00_alloc_work(vha, QLA_EVT_GPNID);
|
||||||
|
|
|
@ -66,6 +66,7 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
|
||||||
uint16_t vp_id;
|
uint16_t vp_id;
|
||||||
struct qla_hw_data *ha = vha->hw;
|
struct qla_hw_data *ha = vha->hw;
|
||||||
unsigned long flags = 0;
|
unsigned long flags = 0;
|
||||||
|
u8 i;
|
||||||
|
|
||||||
mutex_lock(&ha->vport_lock);
|
mutex_lock(&ha->vport_lock);
|
||||||
/*
|
/*
|
||||||
|
@ -75,8 +76,9 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
|
||||||
* ensures no active vp_list traversal while the vport is removed
|
* ensures no active vp_list traversal while the vport is removed
|
||||||
* from the queue)
|
* from the queue)
|
||||||
*/
|
*/
|
||||||
wait_event_timeout(vha->vref_waitq, !atomic_read(&vha->vref_count),
|
for (i = 0; i < 10 && atomic_read(&vha->vref_count); i++)
|
||||||
10*HZ);
|
wait_event_timeout(vha->vref_waitq,
|
||||||
|
atomic_read(&vha->vref_count), HZ);
|
||||||
|
|
||||||
spin_lock_irqsave(&ha->vport_slock, flags);
|
spin_lock_irqsave(&ha->vport_slock, flags);
|
||||||
if (atomic_read(&vha->vref_count)) {
|
if (atomic_read(&vha->vref_count)) {
|
||||||
|
@ -262,6 +264,9 @@ qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb)
|
||||||
spin_lock_irqsave(&ha->vport_slock, flags);
|
spin_lock_irqsave(&ha->vport_slock, flags);
|
||||||
list_for_each_entry(vha, &ha->vp_list, list) {
|
list_for_each_entry(vha, &ha->vp_list, list) {
|
||||||
if (vha->vp_idx) {
|
if (vha->vp_idx) {
|
||||||
|
if (test_bit(VPORT_DELETE, &vha->dpc_flags))
|
||||||
|
continue;
|
||||||
|
|
||||||
atomic_inc(&vha->vref_count);
|
atomic_inc(&vha->vref_count);
|
||||||
spin_unlock_irqrestore(&ha->vport_slock, flags);
|
spin_unlock_irqrestore(&ha->vport_slock, flags);
|
||||||
|
|
||||||
|
@ -300,6 +305,20 @@ qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb)
|
||||||
int
|
int
|
||||||
qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
|
qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
|
||||||
{
|
{
|
||||||
|
fc_port_t *fcport;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To exclusively reset vport, we need to log it out first.
|
||||||
|
* Note: This control_vp can fail if ISP reset is already
|
||||||
|
* issued, this is expected, as the vp would be already
|
||||||
|
* logged out due to ISP reset.
|
||||||
|
*/
|
||||||
|
if (!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) {
|
||||||
|
qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL);
|
||||||
|
list_for_each_entry(fcport, &vha->vp_fcports, list)
|
||||||
|
fcport->logout_on_delete = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Physical port will do most of the abort and recovery work. We can
|
* Physical port will do most of the abort and recovery work. We can
|
||||||
* just treat it as a loop down
|
* just treat it as a loop down
|
||||||
|
@ -312,16 +331,9 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
|
||||||
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
|
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* To exclusively reset vport, we need to log it out first. Note: this
|
|
||||||
* control_vp can fail if ISP reset is already issued, this is
|
|
||||||
* expected, as the vp would be already logged out due to ISP reset.
|
|
||||||
*/
|
|
||||||
if (!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
|
|
||||||
qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL);
|
|
||||||
|
|
||||||
ql_dbg(ql_dbg_taskm, vha, 0x801d,
|
ql_dbg(ql_dbg_taskm, vha, 0x801d,
|
||||||
"Scheduling enable of Vport %d.\n", vha->vp_idx);
|
"Scheduling enable of Vport %d.\n", vha->vp_idx);
|
||||||
|
|
||||||
return qla24xx_enable_vp(vha);
|
return qla24xx_enable_vp(vha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1115,9 +1115,14 @@ static inline int test_fcport_count(scsi_qla_host_t *vha)
|
||||||
void
|
void
|
||||||
qla2x00_wait_for_sess_deletion(scsi_qla_host_t *vha)
|
qla2x00_wait_for_sess_deletion(scsi_qla_host_t *vha)
|
||||||
{
|
{
|
||||||
|
u8 i;
|
||||||
|
|
||||||
qla2x00_mark_all_devices_lost(vha, 0);
|
qla2x00_mark_all_devices_lost(vha, 0);
|
||||||
|
|
||||||
wait_event_timeout(vha->fcport_waitQ, test_fcport_count(vha), 10*HZ);
|
for (i = 0; i < 10; i++)
|
||||||
|
wait_event_timeout(vha->fcport_waitQ, test_fcport_count(vha),
|
||||||
|
HZ);
|
||||||
|
|
||||||
flush_workqueue(vha->hw->wq);
|
flush_workqueue(vha->hw->wq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1115,6 +1115,7 @@ void qlt_free_session_done(struct work_struct *work)
|
||||||
wake_up_all(&tgt->waitQ);
|
wake_up_all(&tgt->waitQ);
|
||||||
|
|
||||||
if (!test_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags) &&
|
if (!test_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags) &&
|
||||||
|
!(vha->vp_idx && test_bit(VPORT_DELETE, &vha->dpc_flags)) &&
|
||||||
(!tgt || !tgt->tgt_stop) && !LOOP_TRANSITION(vha)) {
|
(!tgt || !tgt->tgt_stop) && !LOOP_TRANSITION(vha)) {
|
||||||
switch (vha->host->active_mode) {
|
switch (vha->host->active_mode) {
|
||||||
case MODE_INITIATOR:
|
case MODE_INITIATOR:
|
||||||
|
|
Loading…
Reference in New Issue