From: Himanshu Madhani <himanshu.madhani@qlogic.com> To: target-devel@vger.kernel.org, nab@linux-iscsi.org Cc: giridhar.malavali@qlogic.com, linux-scsi@vger.kernel.org, himanshu.madhani@qlogic.com Subject: [PATCH 06/20] qla2xxx: Delete session if initiator is gone from FW Date: Mon, 7 Dec 2015 19:48:53 -0500 [thread overview] Message-ID: <1449535747-2850-7-git-send-email-himanshu.madhani@qlogic.com> (raw) In-Reply-To: <1449535747-2850-1-git-send-email-himanshu.madhani@qlogic.com> From: Alexei Potashnik <alexei@purestorage.com> 1. Initiator A is logged in with fc_id(1)/loop_id(1) 2. Initiator A re-logs in with fc_id(2)/loop_id(2) 3. Part of old session deletion async logoout for 1/1 is queued 4. Initiator B logs in with fc_id(1)/loop_id(1), starts passing data and creates session. 5. Async logo from 3 is processed by DPC and sent to FW Now initiator B has the session but is logged out from FW. This condition is detected first with CTIO error 29 at which point we should delete current session. During session deletion we will send LOGO to initiator to force re-login. Under rare circumstances initiator might be logged out of FW, not have driver session, but still think it's logged in. E.g. the above sequence plus session deletion due to re-config. Incoming commands will fail to create local session because initiator is not found in FW. In this case we also issue LOGO to initiator to force him re-login. Finally this patch fixes exchange leak when commands where received in logged out state. In this case loop_id must be set to FFFF when corresponding exchange is terminated. The patch modifies exchange termination to always use FFFF, since in certain scenarios it's impossible to tell whether command was received in logged in or logged out state. 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> --- drivers/scsi/qla2xxx/qla_def.h | 2 + drivers/scsi/qla2xxx/qla_os.c | 1 + drivers/scsi/qla2xxx/qla_target.c | 108 +++++++++++++++++++++++++++++++------ drivers/scsi/qla2xxx/qla_target.h | 9 +++ 4 files changed, 104 insertions(+), 16 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 366f65b..1050fc2 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -3652,6 +3652,8 @@ typedef struct scsi_qla_host { atomic_t generation_tick; /* Time when global fcport update has been scheduled */ int total_fcport_update_gen; + /* List of pending LOGOs, protected by tgt_mutex */ + struct list_head logo_list; uint32_t vp_abort_cnt; diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index a63ce6e..c02cbc6 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -3918,6 +3918,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, INIT_LIST_HEAD(&vha->list); INIT_LIST_HEAD(&vha->qla_cmd_list); INIT_LIST_HEAD(&vha->qla_sess_op_cmd_list); + INIT_LIST_HEAD(&vha->logo_list); spin_lock_init(&vha->work_lock); spin_lock_init(&vha->cmd_list_lock); diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 661124a..5ef9d4c 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -389,6 +389,52 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt) } +typedef struct { + /* These fields must be initialized by the caller */ + port_id_t id; + /* + * number of cmds dropped while we were waiting for + * initiator to ack LOGO initialize to 1 if LOGO is + * triggered by a command, otherwise, to 0 + */ + int cmd_count; + + /* These fields are used by callee */ + struct list_head list; +} qlt_port_logo_t; + +static void +qlt_send_first_logo(struct scsi_qla_host *vha, qlt_port_logo_t *logo) +{ + qlt_port_logo_t *tmp; + int res; + + mutex_lock(&vha->vha_tgt.tgt_mutex); + + list_for_each_entry(tmp, &vha->logo_list, list) { + if (tmp->id.b24 == logo->id.b24) { + tmp->cmd_count += logo->cmd_count; + mutex_unlock(&vha->vha_tgt.tgt_mutex); + return; + } + } + + list_add_tail(&logo->list, &vha->logo_list); + + mutex_unlock(&vha->vha_tgt.tgt_mutex); + + res = qla24xx_els_dcmd_iocb(vha, ELS_DCMD_LOGO, logo->id); + + mutex_lock(&vha->vha_tgt.tgt_mutex); + list_del(&logo->list); + mutex_unlock(&vha->vha_tgt.tgt_mutex); + + dev_info(&vha->hw->pdev->dev, + "Finished LOGO to %02x:%02x:%02x, dropped %d cmds, res = %#x\n", + logo->id.b.domain, logo->id.b.area, logo->id.b.al_pa, + logo->cmd_count, res); +} + static void qlt_free_session_done(struct work_struct *work) { struct qla_tgt_sess *sess = container_of(work, struct qla_tgt_sess, @@ -402,14 +448,21 @@ static void qlt_free_session_done(struct work_struct *work) ql_dbg(ql_dbg_tgt_mgt, vha, 0xf084, "%s: se_sess %p / sess %p from port %8phC loop_id %#04x" - " s_id %02x:%02x:%02x logout %d keep %d plogi %d\n", + " s_id %02x:%02x:%02x logout %d keep %d plogi %d els_logo %d\n", __func__, sess->se_sess, sess, sess->port_name, sess->loop_id, sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa, sess->logout_on_delete, sess->keep_nport_handle, - sess->plogi_ack_needed); + sess->plogi_ack_needed, sess->send_els_logo); BUG_ON(!tgt); + if (sess->send_els_logo) { + qlt_port_logo_t logo; + logo.id = sess->s_id; + logo.cmd_count = 0; + qlt_send_first_logo(vha, &logo); + } + if (sess->logout_on_delete) { int rc; @@ -636,12 +689,12 @@ static int qla24xx_get_loop_id(struct scsi_qla_host *vha, const uint8_t *s_id, ql_dbg(ql_dbg_tgt_mgt, vha, 0xf045, "qla_target(%d): get_id_list() failed: %x\n", vha->vp_idx, rc); - res = -1; + res = -EBUSY; goto out_free_id_list; } id_iter = (char *)gid_list; - res = -1; + res = -ENOENT; for (i = 0; i < entries; i++) { struct gid_list_info *gid = (struct gid_list_info *)id_iter; if ((gid->al_pa == s_id[2]) && @@ -2968,7 +3021,7 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha, ctio24 = (struct ctio7_to_24xx *)pkt; ctio24->entry_type = CTIO_TYPE7; - ctio24->nport_handle = cmd ? cmd->loop_id : CTIO7_NHANDLE_UNRECOGNIZED; + ctio24->nport_handle = CTIO7_NHANDLE_UNRECOGNIZED; ctio24->timeout = cpu_to_le16(QLA_TGT_TIMEOUT); ctio24->vp_index = vha->vp_idx; ctio24->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; @@ -3404,13 +3457,26 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle, case CTIO_PORT_LOGGED_OUT: case CTIO_PORT_UNAVAILABLE: + { + bool logged_out = (status & 0xFFFF); ql_dbg(ql_dbg_tgt_mgt, vha, 0xf059, - "qla_target(%d): CTIO with PORT LOGGED " - "OUT (29) or PORT UNAVAILABLE (28) status %x " + "qla_target(%d): CTIO with %s status %x " "received (state %x, se_cmd %p)\n", vha->vp_idx, + (logged_out == CTIO_PORT_LOGGED_OUT) ? + "PORT LOGGED OUT" : "PORT UNAVAILABLE", status, cmd->state, se_cmd); - break; + if (logged_out && cmd->sess) { + /* + * Session is already logged out, but we need + * to notify initiator, who's not aware of this + */ + cmd->sess->logout_on_delete = 0; + cmd->sess->send_els_logo = 1; + qlt_schedule_sess_for_deletion(cmd->sess, true); + } + break; + } case CTIO_SRR_RECEIVED: ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05a, "qla_target(%d): CTIO with SRR_RECEIVED" @@ -3698,10 +3764,8 @@ static void qlt_create_sess_from_atio(struct work_struct *work) goto out_term; } - mutex_lock(&vha->vha_tgt.tgt_mutex); sess = qlt_make_local_sess(vha, s_id); /* sess has an extra creation ref. */ - mutex_unlock(&vha->vha_tgt.tgt_mutex); if (!sess) goto out_term; @@ -5541,12 +5605,16 @@ static struct qla_tgt_sess *qlt_make_local_sess(struct scsi_qla_host *vha, int rc, global_resets; uint16_t loop_id = 0; + mutex_lock(&vha->vha_tgt.tgt_mutex); + retry: global_resets = atomic_read(&vha->vha_tgt.qla_tgt->tgt_global_resets_count); rc = qla24xx_get_loop_id(vha, s_id, &loop_id); if (rc != 0) { + mutex_unlock(&vha->vha_tgt.tgt_mutex); + if ((s_id[0] == 0xFF) && (s_id[1] == 0xFC)) { /* @@ -5557,17 +5625,27 @@ retry: "Unable to find initiator with S_ID %x:%x:%x", s_id[0], s_id[1], s_id[2]); } else - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf071, + ql_log(ql_log_info, vha, 0xf071, "qla_target(%d): Unable to find " "initiator with S_ID %x:%x:%x", vha->vp_idx, s_id[0], s_id[1], s_id[2]); + + if (rc == -ENOENT) { + qlt_port_logo_t logo; + sid_to_portid(s_id, &logo.id); + logo.cmd_count = 1; + qlt_send_first_logo(vha, &logo); + } + return NULL; } fcport = qlt_get_port_database(vha, loop_id); - if (!fcport) + if (!fcport) { + mutex_unlock(&vha->vha_tgt.tgt_mutex); return NULL; + } if (global_resets != atomic_read(&vha->vha_tgt.qla_tgt->tgt_global_resets_count)) { @@ -5582,6 +5660,8 @@ retry: sess = qlt_create_sess(vha, fcport, true); + mutex_unlock(&vha->vha_tgt.tgt_mutex); + kfree(fcport); return sess; } @@ -5611,10 +5691,8 @@ static void qlt_abort_work(struct qla_tgt *tgt, if (!sess) { spin_unlock_irqrestore(&ha->hardware_lock, flags); - mutex_lock(&vha->vha_tgt.tgt_mutex); sess = qlt_make_local_sess(vha, s_id); /* sess has got an extra creation ref */ - mutex_unlock(&vha->vha_tgt.tgt_mutex); spin_lock_irqsave(&ha->hardware_lock, flags); if (!sess) @@ -5670,10 +5748,8 @@ static void qlt_tmr_work(struct qla_tgt *tgt, if (!sess) { spin_unlock_irqrestore(&ha->hardware_lock, flags); - mutex_lock(&vha->vha_tgt.tgt_mutex); sess = qlt_make_local_sess(vha, s_id); /* sess has got an extra creation ref */ - mutex_unlock(&vha->vha_tgt.tgt_mutex); spin_lock_irqsave(&ha->hardware_lock, flags); if (!sess) diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index bca584a..e316d42 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h @@ -909,6 +909,7 @@ struct qla_tgt_sess { unsigned int logout_on_delete:1; unsigned int plogi_ack_needed:1; unsigned int keep_nport_handle:1; + unsigned int send_els_logo:1; unsigned char logout_completed; @@ -1120,6 +1121,14 @@ static inline uint32_t sid_to_key(const uint8_t *s_id) return key; } +static inline void sid_to_portid(const uint8_t *s_id, port_id_t *p) +{ + memset(p, 0, sizeof(*p)); + p->b.domain = s_id[0]; + p->b.area = s_id[1]; + p->b.al_pa = s_id[2]; +} + /* * Exported symbols from qla_target.c LLD logic used by qla2xxx code.. */ -- 1.7.7
next prev parent reply other threads:[~2015-12-08 1:29 UTC|newest] Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top 2015-12-08 0:48 [PATCH 00/20] qla2xxx: Patches for target-pending branch Himanshu Madhani 2015-12-08 0:48 ` [PATCH 01/20] qla2xxx: Enable Extended Login support Himanshu Madhani 2015-12-08 15:51 ` Hannes Reinecke 2015-12-08 19:35 ` Himanshu Madhani 2015-12-08 0:48 ` [PATCH 02/20] qla2xxx: Enable Exchange offload support Himanshu Madhani 2015-12-08 15:52 ` Hannes Reinecke 2015-12-08 0:48 ` [PATCH 03/20] qla2xxx: Enable Target counters in DebugFS Himanshu Madhani 2015-12-08 15:52 ` Hannes Reinecke 2015-12-08 0:48 ` [PATCH 04/20] qla2xxx: Add FW resource count " Himanshu Madhani 2015-12-08 15:53 ` Hannes Reinecke 2015-12-08 0:48 ` [PATCH 05/20] qla2xxx: Added interface to send ELS commands from driver Himanshu Madhani 2015-12-08 2:10 ` kbuild test robot 2015-12-08 2:10 ` [PATCH] qla2xxx: fix ifnullfree.cocci warnings kbuild test robot 2015-12-08 15:54 ` [PATCH 05/20] qla2xxx: Added interface to send ELS commands from driver Hannes Reinecke 2015-12-08 0:48 ` Himanshu Madhani [this message] 2015-12-08 1:41 ` [PATCH 06/20] qla2xxx: Delete session if initiator is gone from FW kbuild test robot 2015-12-08 15:58 ` Hannes Reinecke 2015-12-08 0:48 ` [PATCH 07/20] qla2xxx: Wait for all conflicts before ack'ing PLOGI Himanshu Madhani 2015-12-08 16:00 ` Hannes Reinecke 2015-12-08 0:48 ` [PATCH 08/20] qla2xxx: Replace QLA_TGT_STATE_ABORTED with a bit Himanshu Madhani 2015-12-08 16:01 ` Hannes Reinecke 2015-12-08 0:48 ` [PATCH 09/20] qla2xxx: Change check_stop_free to always return 1 Himanshu Madhani 2015-12-08 2:33 ` Christoph Hellwig 2015-12-09 6:56 ` Hannes Reinecke 2015-12-10 1:06 ` Quinn Tran 2015-12-08 0:48 ` [PATCH 10/20] qla2xxx: Fix interaction issue between qla2xxx and Target Core Module Himanshu Madhani 2015-12-08 2:37 ` Christoph Hellwig 2015-12-09 22:07 ` Quinn Tran 2015-12-14 10:34 ` Christoph Hellwig 2015-12-14 21:59 ` Quinn Tran 2015-12-09 7:01 ` Hannes Reinecke 2015-12-09 22:41 ` Quinn Tran 2015-12-08 0:48 ` [PATCH 11/20] qla2xxx: Add TAS detection for kernel 3.15 n newer Himanshu Madhani 2015-12-08 2:48 ` Christoph Hellwig 2015-12-09 20:24 ` Quinn Tran 2015-12-14 10:37 ` Christoph Hellwig 2015-12-14 22:00 ` Quinn Tran 2015-12-09 7:02 ` Hannes Reinecke 2015-12-08 0:48 ` [PATCH 12/20] target/tmr: LUN reset cause cmd premature free Himanshu Madhani 2015-12-08 2:48 ` Christoph Hellwig 2015-12-09 20:11 ` Quinn Tran 2016-01-04 7:44 ` Bart Van Assche 2015-12-09 7:03 ` Hannes Reinecke 2015-12-08 0:49 ` [PATCH 13/20] qla2xxx: Remove dependency on hardware_lock to reduce lock contention Himanshu Madhani 2015-12-08 0:49 ` [PATCH 14/20] qla2xxx: Add irq affinity notification Himanshu Madhani 2015-12-08 0:49 ` [PATCH 15/20] qla2xxx: Add selective command queuing Himanshu Madhani 2015-12-08 0:49 ` [PATCH 16/20] qla2xxx: Move atioq to a different lock to reduce lock contention Himanshu Madhani 2015-12-08 0:49 ` [PATCH 17/20] qla2xxx: Disable ZIO at start time Himanshu Madhani 2015-12-08 0:49 ` [PATCH 18/20] qla2xxx: Set all queues to 4k Himanshu Madhani 2015-12-08 0:49 ` [PATCH 19/20] qla2xxx: Add bulk send for atio & ctio completion paths Himanshu Madhani 2015-12-08 0:49 ` [PATCH 20/20] qla2xxx: Check for online flag instead of active reset when transmitting responses Himanshu Madhani
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1449535747-2850-7-git-send-email-himanshu.madhani@qlogic.com \ --to=himanshu.madhani@qlogic.com \ --cc=giridhar.malavali@qlogic.com \ --cc=linux-scsi@vger.kernel.org \ --cc=nab@linux-iscsi.org \ --cc=target-devel@vger.kernel.org \ --subject='Re: [PATCH 06/20] qla2xxx: Delete session if initiator is gone from FW' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.