Commit f5187b7d authored by Quinn Tran's avatar Quinn Tran Committed by Martin K. Petersen
Browse files

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: default avatarQuinn Tran <qutran@marvell.com>
Signed-off-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent fd5564ba
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -2920,6 +2920,8 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
	struct qla_hw_data *ha = vha->hw;
	uint16_t id = vha->vp_idx;

	set_bit(VPORT_DELETE, &vha->dpc_flags);

	while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags) ||
	    test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags))
		msleep(1000);
+1 −0
Original line number Diff line number Diff line
@@ -4394,6 +4394,7 @@ typedef struct scsi_qla_host {
#define IOCB_WORK_ACTIVE	31
#define SET_ZIO_THRESHOLD_NEEDED 32
#define ISP_ABORT_TO_ROM	33
#define VPORT_DELETE		34

	unsigned long	pci_flags;
#define PFLG_DISCONNECTED	0	/* PCI device removed */
+2 −1
Original line number Diff line number Diff line
@@ -3102,7 +3102,8 @@ int qla24xx_post_gpnid_work(struct scsi_qla_host *vha, port_id_t *id)
{
	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;

	e = qla2x00_alloc_work(vha, QLA_EVT_GPNID);
+22 −10
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
	uint16_t vp_id;
	struct qla_hw_data *ha = vha->hw;
	unsigned long flags = 0;
	u8 i;

	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
	 * from the queue)
	 */
	wait_event_timeout(vha->vref_waitq, !atomic_read(&vha->vref_count),
	    10*HZ);
	for (i = 0; i < 10 && atomic_read(&vha->vref_count); i++)
		wait_event_timeout(vha->vref_waitq,
		    atomic_read(&vha->vref_count), HZ);

	spin_lock_irqsave(&ha->vport_slock, flags);
	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);
	list_for_each_entry(vha, &ha->vp_list, list) {
		if (vha->vp_idx) {
			if (test_bit(VPORT_DELETE, &vha->dpc_flags))
				continue;

			atomic_inc(&vha->vref_count);
			spin_unlock_irqrestore(&ha->vport_slock, flags);

@@ -300,6 +305,20 @@ qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb)
int
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
	 * 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);
	}

	/*
	 * 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,
	    "Scheduling enable of Vport %d.\n", vha->vp_idx);

	return qla24xx_enable_vp(vha);
}

+6 −1
Original line number Diff line number Diff line
@@ -1115,9 +1115,14 @@ static inline int test_fcport_count(scsi_qla_host_t *vha)
void
qla2x00_wait_for_sess_deletion(scsi_qla_host_t *vha)
{
	u8 i;

	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);
}

Loading