[PATCH] qla_target/tcm_qla2xxx: Make qla_tgt_mgmt_cmd use TARGET_SCF_ACK_KREF

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>

This patch addresses an bug in recent qla_target/tcm_qla2xxx code where
transport_generic_free_cmd() is not being called for TMR ops and associated
qla_tgt_mgmt_cmd->se_cmd.  This results in core_tmr_release_req() not being
called and tmr->tmr_list being leaked after TMR response completion.

To address this issue, this patch changes tcm_qla2xxx_handle_tmr() ->
target_submit_tmr() to use TARGET_SCF_ACK_KREF flags, and adds a new
qla_tgt_ops->free_mcmd() callback to invoke the extra ACK ->cmd_kref put
from process context in the TFO->queue_tm_rsp() -> tcm_qla2xxx_queue_tm_rsp()
-> qla_tgt_xmit_tm_rsp() codepath.

Cc: Andrew Vasquez <andrew.vasquez@xxxxxxxxxx>
Cc: Arun Easi <arun.easi@xxxxxxxxxx>
Cc: Giridhar Malavali <giridhar.malavali@xxxxxxxxxx>
Cc: Roland Dreier <roland@xxxxxxxxxxxxxxx>
Cc: Christoph Hellwig <hch@xxxxxx>
Cc: Joern Engel <joern@xxxxxxxxx>
Cc: Andy Grover <agrover@xxxxxxxxxx>
Signed-off-by: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>
---
 drivers/scsi/qla2xxx/qla_target.c  |    9 +++++++++
 drivers/scsi/qla2xxx/qla_target.h  |    2 ++
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |   22 +++++++++++++++++++++-
 3 files changed, 32 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index b6db377..b03393a 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1409,6 +1409,15 @@ void qla_tgt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd)
 		else
 			qla_tgt_24xx_send_task_mgmt_ctio(vha, mcmd, mcmd->fc_tm_rsp);
 	}
+	/*
+	 * Make the callback for ->free_mcmd() to queue_work() and invoke
+	 * target_put_sess_cmd() to drop cmd_kref to 1.  The final
+	 * target_put_sess_cmd() call will be made from TFO->check_stop_free()
+	 * -> tcm_qla2xxx_check_stop_free() to release the TMR associated se_cmd
+	 * descriptor after TFO->queue_tm_rsp() -> tcm_qla2xxx_queue_tm_rsp() ->
+	 * qla_tgt_xmit_tm_rsp() returns here..
+	 */
+	ha->tgt_ops->free_mcmd(mcmd);
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 }
 EXPORT_SYMBOL(qla_tgt_xmit_tm_rsp);
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
index 6930d58..d643f27 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -636,6 +636,7 @@ struct qla_tgt_func_tmpl {
 	int (*handle_data)(struct qla_tgt_cmd *);
 	int (*handle_tmr)(struct qla_tgt_mgmt_cmd *, uint32_t, uint8_t, uint32_t);
 	void (*free_cmd)(struct qla_tgt_cmd *);
+	void (*free_mcmd)(struct qla_tgt_mgmt_cmd *);
 	void (*free_session)(struct qla_tgt_sess *);
 
 	int (*check_initiator_node_acl)(struct scsi_qla_host *, unsigned char *,
@@ -870,6 +871,7 @@ struct qla_tgt_mgmt_cmd {
 	uint8_t fc_tm_rsp;
 	struct qla_tgt_sess *sess;
 	struct se_cmd se_cmd;
+	struct work_struct free_work;
 	unsigned int flags;
 #define QLA24XX_MGMT_SEND_NACK	1
 	union {
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 85eec3e..c6acb80 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -387,6 +387,25 @@ u32 tcm_qla2xxx_tpg_get_inst_index(struct se_portal_group *se_tpg)
 	return tpg->lport_tpgt;
 }
 
+static void tcm_qla2xxx_complete_mcmd(struct work_struct *work)
+{
+	struct qla_tgt_mgmt_cmd *mcmd = container_of(work,
+			struct qla_tgt_mgmt_cmd, free_work);
+
+	transport_generic_free_cmd(&mcmd->se_cmd, 0);
+}
+
+/*
+ * Called from qla_target_template->free_mcmd(), and will call
+ * tcm_qla2xxx_release_cmd() via normal struct target_core_fabric_ops
+ * release callback.  qla_hw_data->hardware_lock is expected to be held
+ */
+static void tcm_qla2xxx_free_mcmd(struct qla_tgt_mgmt_cmd *mcmd)
+{
+	INIT_WORK(&mcmd->free_work, tcm_qla2xxx_complete_mcmd);
+	queue_work(tcm_qla2xxx_free_wq, &mcmd->free_work);
+}
+
 static void tcm_qla2xxx_complete_free(struct work_struct *work)
 {
 	struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
@@ -637,7 +656,7 @@ int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd *mcmd, uint32_t lun,
 	struct se_cmd *se_cmd = &mcmd->se_cmd;
 
 	return target_submit_tmr(se_cmd, sess->se_sess, NULL, lun, mcmd,
-			tmr_func, GFP_ATOMIC, tag, 0);
+			tmr_func, GFP_ATOMIC, tag, TARGET_SCF_ACK_KREF);
 }
 
 int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
@@ -1536,6 +1555,7 @@ static struct qla_tgt_func_tmpl tcm_qla2xxx_template = {
 	.handle_data		= tcm_qla2xxx_handle_data,
 	.handle_tmr		= tcm_qla2xxx_handle_tmr,
 	.free_cmd		= tcm_qla2xxx_free_cmd,
+	.free_mcmd		= tcm_qla2xxx_free_mcmd,
 	.free_session		= tcm_qla2xxx_free_session,
 	.check_initiator_node_acl = tcm_qla2xxx_check_initiator_node_acl,
 	.find_sess_by_s_id	= tcm_qla2xxx_find_sess_by_s_id,
-- 
1.7.2.5

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux