diff mbox

[5/6] target/iscsi: Introduce iscsit_get_cmd() and iscsit_put_cmd()

Message ID 20170330171244.8346-6-bart.vanassche@sandisk.com (mailing list archive)
State New, archived
Headers show

Commit Message

Bart Van Assche March 30, 2017, 5:12 p.m. UTC
Keep track in .refcnt of whether or not target_put_sess_cmd() has
already been called.

Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
---
 drivers/target/iscsi/cxgbit/cxgbit_target.c  |  2 +-
 drivers/target/iscsi/iscsi_target.c          | 16 ++++++-------
 drivers/target/iscsi/iscsi_target_configfs.c |  4 +++-
 drivers/target/iscsi/iscsi_target_util.c     | 35 +++++++++++++++++++++++++++-
 include/target/iscsi/iscsi_target_core.h     |  1 +
 include/target/iscsi/iscsi_transport.h       |  2 ++
 6 files changed, 49 insertions(+), 11 deletions(-)

Comments

Nicholas A. Bellinger April 2, 2017, 11:11 p.m. UTC | #1
On Thu, 2017-03-30 at 10:12 -0700, Bart Van Assche wrote:
> Keep track in .refcnt of whether or not target_put_sess_cmd() has
> already been called.
> 
> Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
> ---
>  drivers/target/iscsi/cxgbit/cxgbit_target.c  |  2 +-
>  drivers/target/iscsi/iscsi_target.c          | 16 ++++++-------
>  drivers/target/iscsi/iscsi_target_configfs.c |  4 +++-
>  drivers/target/iscsi/iscsi_target_util.c     | 35 +++++++++++++++++++++++++++-
>  include/target/iscsi/iscsi_target_core.h     |  1 +
>  include/target/iscsi/iscsi_transport.h       |  2 ++
>  6 files changed, 49 insertions(+), 11 deletions(-)
> 

Given the earlier incorrect assumptions wrt transport_generic_free_cmd()
return value during CMD_T_ABORTED, it's completely unnecessary to
introduce a driver specific reference count.

Dropping this patch.

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

Patch

diff --git a/drivers/target/iscsi/cxgbit/cxgbit_target.c b/drivers/target/iscsi/cxgbit/cxgbit_target.c
index bdcc8b4c522a..528a25e6cfbd 100644
--- a/drivers/target/iscsi/cxgbit/cxgbit_target.c
+++ b/drivers/target/iscsi/cxgbit/cxgbit_target.c
@@ -956,7 +956,7 @@  cxgbit_get_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr,
 			return -1;
 
 		if (cmd->sense_reason || cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
-			target_put_sess_cmd(&cmd->se_cmd);
+			iscsit_put_cmd(cmd);
 			return 0;
 		} else if (cmd->unsolicited_data) {
 			iscsit_set_unsoliticed_dataout(cmd);
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 73d8eaa0973b..de6b2e430d1a 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -872,8 +872,8 @@  static int iscsit_add_reject_from_cmd(
 	 * scsit_setup_scsi_cmd()
 	 */
 	if (cmd->se_cmd.se_tfo != NULL) {
-		pr_debug("iscsi reject: calling target_put_sess_cmd >>>>>>\n");
-		target_put_sess_cmd(&cmd->se_cmd);
+		pr_debug("iscsi reject: calling iscsit_put_cmd() >>>>>>\n");
+		iscsit_put_cmd(cmd);
 	}
 	return -1;
 }
@@ -1167,7 +1167,7 @@  int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
 		hdr->cmdsn, be32_to_cpu(hdr->data_length), payload_length,
 		conn->cid);
 
-	target_get_sess_cmd(&cmd->se_cmd, true);
+	iscsit_get_cmd(cmd);
 
 	cmd->sense_reason = transport_lookup_cmd_lun(&cmd->se_cmd,
 						     scsilun_to_int(&hdr->lun));
@@ -1235,7 +1235,7 @@  int iscsit_process_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
 		if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
 			return -1;
 		else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
-			target_put_sess_cmd(&cmd->se_cmd);
+			iscsit_put_cmd(cmd);
 			return 0;
 		}
 	}
@@ -1251,7 +1251,7 @@  int iscsit_process_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
 		if (!cmd->sense_reason)
 			return 0;
 
-		target_put_sess_cmd(&cmd->se_cmd);
+		iscsit_put_cmd(cmd);
 		return 0;
 	}
 
@@ -1308,7 +1308,7 @@  iscsit_get_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr,
 
 			rc = iscsit_dump_data_payload(cmd->conn,
 						      cmd->first_burst_len, 1);
-			target_put_sess_cmd(&cmd->se_cmd);
+			iscsit_put_cmd(cmd);
 			return rc;
 		} else if (cmd->unsolicited_data)
 			iscsit_set_unsoliticed_dataout(cmd);
@@ -2015,7 +2015,7 @@  iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
 				      conn->sess->se_sess, 0, DMA_NONE,
 				      TCM_SIMPLE_TAG, cmd->sense_buffer + 2);
 
-		target_get_sess_cmd(&cmd->se_cmd, true);
+		iscsit_get_cmd(cmd);
 		sess_ref = true;
 		tcm_function = iscsit_convert_tmf(function);
 		if (tcm_function == TMR_UNKNOWN) {
@@ -2134,7 +2134,7 @@  iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
 	 */
 	if (sess_ref) {
 		pr_debug("Handle TMR, using sess_ref=true check\n");
-		target_put_sess_cmd(&cmd->se_cmd);
+		iscsit_put_cmd(cmd);
 	}
 
 	iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
index bf40f03755dd..39a7294dfac7 100644
--- a/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -1559,7 +1559,9 @@  static void lio_set_default_node_attributes(struct se_node_acl *se_acl)
 
 static int lio_check_stop_free(struct se_cmd *se_cmd)
 {
-	return target_put_sess_cmd(se_cmd);
+	struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
+
+	return iscsit_put_cmd(cmd);
 }
 
 static void lio_release_cmd(struct se_cmd *se_cmd)
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c
index 139746b3b189..1cacfe1003e3 100644
--- a/drivers/target/iscsi/iscsi_target_util.c
+++ b/drivers/target/iscsi/iscsi_target_util.c
@@ -688,6 +688,39 @@  void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn)
 	spin_unlock_bh(&conn->response_queue_lock);
 }
 
+/**
+ * iscsit_get_cmd - add @cmd to the list of active commands
+ * @cmd: iSCSI command.
+ */
+int iscsit_get_cmd(struct iscsi_cmd *cmd)
+{
+	long refcnt = atomic_read(&cmd->refcnt);
+	int ret;
+
+	WARN_ONCE(refcnt != 0, "refcnt = %ld\n", refcnt);
+	ret = target_get_sess_cmd(&cmd->se_cmd, true);
+	if (ret)
+		return ret;
+	atomic_inc(&cmd->refcnt);
+	return ret;
+}
+
+/**
+ * iscsit_put_cmd() - decrease the reference count of @cmd
+ * @cmd: iSCSI command.
+ *
+ * Note: this function must be called only once per command.
+ */
+int iscsit_put_cmd(struct iscsi_cmd *cmd)
+{
+	long refcnt = atomic_read(&cmd->refcnt);
+
+	WARN_ONCE(refcnt <= 0, "refcnt = %ld\n", refcnt);
+	atomic_dec(&cmd->refcnt);
+	return target_put_sess_cmd(&cmd->se_cmd);
+}
+EXPORT_SYMBOL(iscsit_put_cmd);
+
 void iscsit_release_cmd(struct iscsi_cmd *cmd)
 {
 	struct iscsi_session *sess;
@@ -744,7 +777,7 @@  void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown)
 		rc = transport_generic_free_cmd(&cmd->se_cmd, shutdown);
 		if (!rc && shutdown && se_cmd && se_cmd->se_sess) {
 			__iscsit_free_cmd(cmd, shutdown);
-			target_put_sess_cmd(se_cmd);
+			iscsit_put_cmd(cmd);
 		}
 	} else {
 		iscsit_release_cmd(cmd);
diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h
index 275581d483dd..83afb5c80fcc 100644
--- a/include/target/iscsi/iscsi_target_core.h
+++ b/include/target/iscsi/iscsi_target_core.h
@@ -349,6 +349,7 @@  struct iscsi_r2t {
 } ____cacheline_aligned;
 
 struct iscsi_cmd {
+	atomic_t		refcnt;
 	enum iscsi_timer_flags_table dataout_timer_flags;
 	/* DataOUT timeout retries */
 	u8			dataout_timeout_retries;
diff --git a/include/target/iscsi/iscsi_transport.h b/include/target/iscsi/iscsi_transport.h
index ff1a4f4cd66d..dd4aa931b14e 100644
--- a/include/target/iscsi/iscsi_transport.h
+++ b/include/target/iscsi/iscsi_transport.h
@@ -125,6 +125,8 @@  extern int iscsit_tmr_post_handler(struct iscsi_cmd *, struct iscsi_conn *);
 extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, int);
 extern int iscsit_sequence_cmd(struct iscsi_conn *, struct iscsi_cmd *,
 			       unsigned char *, __be32);
+extern int iscsit_get_cmd(struct iscsi_cmd *cmd);
+extern int iscsit_put_cmd(struct iscsi_cmd *cmd);
 extern void iscsit_release_cmd(struct iscsi_cmd *);
 extern void iscsit_free_cmd(struct iscsi_cmd *, bool);
 extern void iscsit_add_cmd_to_immediate_queue(struct iscsi_cmd *,