Skip to content

Commit

Permalink
qla2xxx: delay plogi/prli ack until existing sessions are deleted
Browse files Browse the repository at this point in the history
- keep qla_tgt_sess object on the session list until it's freed

- modify use of sess->deleted flag to differentiate delayed
  session deletion that can be cancelled from irreversible one:
  QLA_SESS_DELETION_PENDING vs QLA_SESS_DELETION_IN_PROGRESS

- during IN_PROGRESS deletion all newly arrived commands and TMRs will
  be rejected, existing commands and TMRs will be terminated when
  given by the core to the fabric or simply dropped if session logout
  has already happened (logout terminates all existing exchanges)

- new PLOGI will initiate deletion of the following sessions
  (unless deletion is already IN_PROGRESS):
  - with the same port_name (with logout)
  - different port_name, different loop_id but the same port_id
    (with logout)
  - different port_name, different port_id, but the same loop_id
    (without logout)

- additionally each new PLOGI will store imm notify iocb in the
  same port_name session being deleted. When deletion process
  completes this iocb will be acked. Only the most recent PLOGI
  iocb is stored. The older ones will be terminated when replaced.

- new PRLI will initiate deletion of the following sessions
  (unless deletion is already IN_PROGRESS):
  - different port_name, different port_id, but the same loop_id
   (without logout)

Cc: <stable@vger.kernel.org> # v3.18+
Signed-off-by: Alexei Potashnik <alexei@purestorage.com>
Acked-by: Quinn Tran <quinn.tran@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
  • Loading branch information
Alexei Potashnik authored and Nicholas Bellinger committed Jul 24, 2015
1 parent 8b2f5ff commit a6ca887
Show file tree
Hide file tree
Showing 7 changed files with 481 additions and 22 deletions.
6 changes: 3 additions & 3 deletions drivers/scsi/qla2xxx/qla_dbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@
* | | | 0xd031-0xd0ff |
* | | | 0xd101-0xd1fe |
* | | | 0xd214-0xd2fe |
* | Target Mode | 0xe079 | |
* | Target Mode Management | 0xf083 | 0xf002 |
* | Target Mode | 0xe080 | |
* | Target Mode Management | 0xf091 | 0xf002 |
* | | | 0xf046-0xf049 |
* | Target Mode Task Management | 0x1000b | |
* | Target Mode Task Management | 0x1000d | |
* ----------------------------------------------------------------------
*/

Expand Down
2 changes: 2 additions & 0 deletions drivers/scsi/qla2xxx/qla_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@
#define RESPONSE_ENTRY_CNT_FX00 256 /* Number of response entries.*/

struct req_que;
struct qla_tgt_sess;

/*
* (sd.h is not exported, hence local inclusion)
Expand Down Expand Up @@ -2026,6 +2027,7 @@ typedef struct fc_port {
uint16_t port_id;

unsigned long retry_delay_timestamp;
struct qla_tgt_sess *tgt_session;
} fc_port_t;

#include "qla_mr.h"
Expand Down
7 changes: 6 additions & 1 deletion drivers/scsi/qla2xxx/qla_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ qla2x00_async_iocb_timeout(void *data)
QLA_LOGIO_LOGIN_RETRIED : 0;
qla2x00_post_async_login_done_work(fcport->vha, fcport,
lio->u.logio.data);
} else if (sp->type == SRB_LOGOUT_CMD) {
qlt_logo_completion_handler(fcport, QLA_FUNCTION_TIMEOUT);
}
}

Expand Down Expand Up @@ -497,7 +499,10 @@ void
qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport,
uint16_t *data)
{
qla2x00_mark_device_lost(vha, fcport, 1, 0);
/* Don't re-login in target mode */
if (!fcport->tgt_session)
qla2x00_mark_device_lost(vha, fcport, 1, 0);
qlt_logo_completion_handler(fcport, data[0]);
return;
}

Expand Down
3 changes: 3 additions & 0 deletions drivers/scsi/qla2xxx/qla_iocb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1943,6 +1943,9 @@ qla24xx_logout_iocb(srb_t *sp, struct logio_entry_24xx *logio)
logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
logio->control_flags =
cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO);
if (!sp->fcport->tgt_session ||
!sp->fcport->tgt_session->keep_nport_handle)
logio->control_flags |= cpu_to_le16(LCF_FREE_NPORT);
logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
logio->port_id[0] = sp->fcport->d_id.b.al_pa;
logio->port_id[1] = sp->fcport->d_id.b.area;
Expand Down
Loading

0 comments on commit a6ca887

Please sign in to comment.