[PATCH 2/7] target: Add TARGET_SCF_ACK_KREF flag usage

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

 



From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>

This patch adds TARGET_SCF_ACK_KREF for target_submit_cmd() that passes
a 'ack_kref' parameter into target_get_sess_cmd() to determine when
the fabric caller is expecting a second kref_put() from fabric
packet acknowledgement.

This also includes updating target_submit_cmd() usage in tcm_qla2xxx,
and target_get_sess_cmd() usage in ib_srpt ahead of a proper
target_submit_cmd() conversion in lio-core.

Cc: Christoph Hellwig <hch@xxxxxx>
Cc: Roland Dreier <roland@xxxxxxxxxxxxxxx>
Signed-off-by: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>
---
 drivers/infiniband/ulp/srpt/ib_srpt.c           |    2 +-
 drivers/target/target_core_transport.c          |   20 +++++++++++++++-----
 drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c |    4 ++--
 include/target/target_core_base.h               |    1 +
 include/target/target_core_transport.h          |    2 +-
 5 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index 7699b49..ebe39d8 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -1752,7 +1752,7 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch,
 	else
 		WARN_ON_ONCE(ret);
 
-	target_get_sess_cmd(ch->sess, cmd);
+	target_get_sess_cmd(ch->sess, cmd, true);
 	transport_handle_cdb_direct(cmd);
 	return 0;
 
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index f1a8e2e..322eac9 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1708,10 +1708,12 @@ int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
 	transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess,
 				data_length, data_dir, task_attr, sense);
 	/*
-	 * Obtain struct se_cmd->cmd_kref references and add new cmd to
-	 * se_sess->sess_cmd_list
+	 * Obtain struct se_cmd->cmd_kref reference and add new cmd to
+	 * se_sess->sess_cmd_list.  A second kref_get here is necessary
+	 * for fabrics using TARGET_SCF_ACK_KREF that expect a second
+	 * kref_put() to happen during fabric packet acknowledgement.
 	 */
-	target_get_sess_cmd(se_sess, se_cmd);
+	target_get_sess_cmd(se_sess, se_cmd, (flags & TARGET_SCF_ACK_KREF));
 	/*
 	 * Signal bidirectional data payloads to target-core
 	 */
@@ -3997,13 +3999,21 @@ EXPORT_SYMBOL(transport_generic_free_cmd);
 /* target_get_sess_cmd - Add command to active ->sess_cmd_list
  * @se_sess:	session to reference
  * @se_cmd:	command descriptor to add
+ * @ack_kref:	Signal that fabric will perform an ack target_put_sess_cmd()
  */
-void target_get_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd)
+void target_get_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd,
+			bool ack_kref)
 {
 	unsigned long flags;
 
 	kref_init(&se_cmd->cmd_kref);
-	kref_get(&se_cmd->cmd_kref);
+	/*
+	 * Add a second kref if the fabric caller is expecting to handle
+	 * fabric acknowledgement that requires two target_put_sess_cmd()
+	 * invocations before se_cmd descriptor release.
+	 */
+	if (ack_kref == true)
+		kref_get(&se_cmd->cmd_kref);
 
 	spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
 	list_add_tail(&se_cmd->se_cmd_list, &se_sess->sess_cmd_list);
diff --git a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c
index 5386e82..14e388d 100644
--- a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c
+++ b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c
@@ -610,7 +610,7 @@ int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
 	struct se_cmd *se_cmd = &cmd->se_cmd;
 	struct se_session *se_sess;
 	struct qla_tgt_sess *sess;
-	int rc;
+	int rc, flags = (bidi) ? TARGET_SCF_BIDI_OP : 0 | TARGET_SCF_ACK_KREF;
 
 	sess = cmd->sess;
 	if (!sess) {
@@ -626,7 +626,7 @@ int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
 
 	rc = target_submit_cmd(se_cmd, se_sess, cdb, &cmd->sense_buffer[0],
 				cmd->unpacked_lun, data_length, fcp_task_attr,
-				data_dir, (bidi) ? TARGET_SCF_BIDI_OP : 0);
+				data_dir, flags);
 	if (rc != 0)
 		return -EINVAL;
 
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 3f7105b..81bd34c 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -158,6 +158,7 @@ enum tcm_sense_reason_table {
 
 enum target_sc_flags_table {
 	TARGET_SCF_BIDI_OP		= 0x01,
+	TARGET_SCF_ACK_KREF		= 0x02,
 };
 
 struct se_obj {
diff --git a/include/target/target_core_transport.h b/include/target/target_core_transport.h
index 407aff9..b3e80e7 100644
--- a/include/target/target_core_transport.h
+++ b/include/target/target_core_transport.h
@@ -148,7 +148,7 @@ extern int transport_send_check_condition_and_sense(struct se_cmd *, u8, int);
 extern void transport_send_task_abort(struct se_cmd *);
 extern void transport_release_cmd(struct se_cmd *);
 extern void transport_generic_free_cmd(struct se_cmd *, int);
-extern void target_get_sess_cmd(struct se_session *, struct se_cmd *);
+extern void target_get_sess_cmd(struct se_session *, struct se_cmd *, bool);
 extern int target_put_sess_cmd(struct se_session *, struct se_cmd *);
 extern void target_splice_sess_cmd_list(struct se_session *);
 extern void target_wait_for_sess_cmds(struct se_session *, int);
-- 
1.7.2.5

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


[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux