[PATCH 3/4] lio-target: Convert to use pre-allocated struct se_cmd descriptors

From: Nicholas A. Bellinger
Date: Fri Sep 10 2010 - 05:27:32 EST


From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>

This patch converts the LIO-Target fabric module to use pre-allocated struct se_cmd
descriptors and sense data buffer located at struct iscsi_cmd->se_cmd and
struct iscsi_cmd->sense_buffer respectively.

This includes updating iscsi_allocate_se_cmd() to use transport_init_se_cmd() for
the main iSCSI CDB RX side entry point. It also includes some special case handling
in the struct iscsi_cmd I/O descriptor release path where previously assuming a NULL
struct iscsi_cmd->se_cmd in iscsi_target_tx_thread() and iscsi_release_commands_from_conn()
meant the struct iscsi_cmd is an iSCSI level PDU, and does not contain an
transport_init_se_cmd() initialized struct iscsi_cmd->se_cmd.

This also includes the conversion of a number of functions to use container_of()
instead of struct se_cmd->se_fabric_cmd_ptr to locate the struct iscsi_cmd.

Signed-off-by: Nicholas A. Bellinger <nab@xxxxxxxxxxxxxxx>
---
drivers/target/lio-target/iscsi_target.c | 27 +++++++++------
drivers/target/lio-target/iscsi_target_core.h | 10 ++++-
drivers/target/lio-target/iscsi_target_erl1.c | 8 ++--
drivers/target/lio-target/iscsi_target_tmr.c | 23 ++++---------
drivers/target/lio-target/iscsi_target_util.c | 44 ++++++++++++-------------
5 files changed, 57 insertions(+), 55 deletions(-)

diff --git a/drivers/target/lio-target/iscsi_target.c b/drivers/target/lio-target/iscsi_target.c
index 2228e45..1b51c0e 100644
--- a/drivers/target/lio-target/iscsi_target.c
+++ b/drivers/target/lio-target/iscsi_target.c
@@ -1170,18 +1170,22 @@ char *iscsi_get_fabric_name(void)

struct iscsi_cmd *iscsi_get_cmd(struct se_cmd *se_cmd)
{
- return (struct iscsi_cmd *)se_cmd->se_fabric_cmd_ptr;
+ struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
+
+ return cmd;
}

u32 iscsi_get_task_tag(struct se_cmd *se_cmd)
{
- struct iscsi_cmd *cmd = (struct iscsi_cmd *)se_cmd->se_fabric_cmd_ptr;
+ struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
+
return cmd->init_task_tag;
}

int iscsi_get_cmd_state(struct se_cmd *se_cmd)
{
- struct iscsi_cmd *cmd = (struct iscsi_cmd *)se_cmd->se_fabric_cmd_ptr;
+ struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
+
return cmd->i_state;
}

@@ -4294,6 +4298,7 @@ int iscsi_target_tx_thread(void *arg)
struct iscsi_cmd *cmd = NULL;
struct iscsi_conn *conn;
struct iscsi_queue_req *qr = NULL;
+ struct se_cmd *se_cmd;
struct se_thread_set *ts = (struct se_thread_set *) arg;
struct se_unmap_sg unmap_sg;

@@ -4352,11 +4357,12 @@ get_immediate:
* Determine if a struct se_cmd is assoicated with
* this struct iscsi_cmd.
*/
- if (!(SE_CMD(cmd)))
+ if (!(SE_CMD(cmd)->se_cmd_flags & SCF_SE_LUN_CMD) &&
+ !(cmd->tmr_req))
iscsi_release_cmd_to_pool(cmd);
else
- transport_generic_free_cmd(
- SE_CMD(cmd), 1, 1, 0);
+ transport_generic_free_cmd(SE_CMD(cmd),
+ 1, 1, 0);
goto get_immediate;
case ISTATE_SEND_NOPIN_WANT_RESPONSE:
spin_unlock_bh(&cmd->istate_lock);
@@ -4491,8 +4497,10 @@ check_rsp_state:
goto transport_err;
}

+ se_cmd = &cmd->se_cmd;
+
if (map_sg && !CONN_OPS(conn)->IFMarker &&
- T_TASK(cmd->se_cmd)->t_tasks_se_num) {
+ T_TASK(se_cmd)->t_tasks_se_num) {
SE_CMD(cmd)->transport_map_SG_segments(&unmap_sg);
if (iscsi_fe_sendpage_sg(&unmap_sg, conn) < 0) {
conn->tx_response_queue = 0;
@@ -4816,10 +4824,9 @@ static void iscsi_release_commands_from_conn(struct iscsi_conn *conn)
* transport_get_lun_for_cmd() failing from
* iscsi_get_lun_for_cmd() in iscsi_handle_scsi_cmd().
*/
- if (cmd->tmr_req && se_cmd &&
- se_cmd->transport_wait_for_tasks)
+ if (cmd->tmr_req && se_cmd->transport_wait_for_tasks)
se_cmd->transport_wait_for_tasks(se_cmd, 1, 1);
- else if (se_cmd)
+ else if (SE_CMD(cmd)->se_cmd_flags & SCF_SE_LUN_CMD)
transport_release_cmd_to_pool(se_cmd);
else
__iscsi_release_cmd_to_pool(cmd, sess);
diff --git a/drivers/target/lio-target/iscsi_target_core.h b/drivers/target/lio-target/iscsi_target_core.h
index 418c425..7fa24b1 100644
--- a/drivers/target/lio-target/iscsi_target_core.h
+++ b/drivers/target/lio-target/iscsi_target_core.h
@@ -5,6 +5,7 @@
#include <linux/configfs.h>
#include <net/sock.h>
#include <net/tcp.h>
+#include <scsi/scsi_cmnd.h>
#include <iscsi_target_version.h> /* get version definition */

#include <target/target_core_base.h>
@@ -29,6 +30,8 @@
#define ISCSI_MAX_TPGS 64
/* Size of the Network Device Name Buffer */
#define ISCSI_NETDEV_NAME_SIZE 12
+/* Size of iSCSI specific sense buffer */
+#define ISCSI_SENSE_BUFFER_LEN TRANSPORT_SENSE_BUFFER + 2

#include <iscsi_target_mib.h>

@@ -487,10 +490,13 @@ struct iscsi_cmd {
struct iscsi_cmd *t_next;
/* Previous command in DAS transport list */
struct iscsi_cmd *t_prev;
- struct se_cmd *se_cmd;
+ /* The TCM I/O descriptor that is accessed via container_of() */
+ struct se_cmd se_cmd;
+ /* Sense buffer that will be mapped into outgoing status */
+ unsigned char sense_buffer[ISCSI_SENSE_BUFFER_LEN];
} ____cacheline_aligned;

-#define SE_CMD(cmd) ((struct se_cmd *)(cmd)->se_cmd)
+#define SE_CMD(cmd) (&(cmd)->se_cmd)

#include <iscsi_seq_and_pdu_list.h>

diff --git a/drivers/target/lio-target/iscsi_target_erl1.c b/drivers/target/lio-target/iscsi_target_erl1.c
index 6b6ad6d..6de09e1 100644
--- a/drivers/target/lio-target/iscsi_target_erl1.c
+++ b/drivers/target/lio-target/iscsi_target_erl1.c
@@ -443,7 +443,7 @@ static inline int iscsi_handle_recovery_datain(
{
struct iscsi_conn *conn = CONN(cmd);
struct iscsi_datain_req *dr;
- struct se_cmd *se_cmd = cmd->se_cmd;
+ struct se_cmd *se_cmd = &cmd->se_cmd;

if (!(atomic_read(&T_TASK(se_cmd)->t_transport_complete))) {
printk(KERN_ERR "Ignoring ITT: 0x%08x Data SNACK\n",
@@ -991,7 +991,7 @@ int iscsi_execute_ooo_cmdsns(struct iscsi_session *sess)
*/
int iscsi_execute_cmd(struct iscsi_cmd *cmd, int ooo)
{
- struct se_cmd *se_cmd = cmd->se_cmd;
+ struct se_cmd *se_cmd = &cmd->se_cmd;
int lr = 0;

spin_lock_bh(&cmd->istate_lock);
@@ -1040,7 +1040,7 @@ int iscsi_execute_cmd(struct iscsi_cmd *cmd, int ooo)
if (cmd->cmd_flags & ICF_GOT_LAST_DATAOUT) {
spin_unlock_bh(&cmd->istate_lock);
return transport_generic_handle_data(
- cmd->se_cmd);
+ &cmd->se_cmd);
}
spin_unlock_bh(&cmd->istate_lock);

@@ -1079,7 +1079,7 @@ int iscsi_execute_cmd(struct iscsi_cmd *cmd, int ooo)
iscsi_start_dataout_timer(cmd, CONN(cmd));
spin_unlock_bh(&cmd->dataout_timeout_lock);
}
- return transport_generic_handle_cdb(cmd->se_cmd);
+ return transport_generic_handle_cdb(&cmd->se_cmd);

case ISCSI_INIT_NOP_OUT:
case ISCSI_INIT_TEXT_CMND:
diff --git a/drivers/target/lio-target/iscsi_target_tmr.c b/drivers/target/lio-target/iscsi_target_tmr.c
index 21d62db..8a62939 100644
--- a/drivers/target/lio-target/iscsi_target_tmr.c
+++ b/drivers/target/lio-target/iscsi_target_tmr.c
@@ -71,11 +71,6 @@ u8 iscsi_tmr_abort_task(
(hdr->ref_cmd_sn <= SESS(conn)->max_cmd_sn)) ?
FUNCTION_COMPLETE : TASK_DOES_NOT_EXIST;
}
- if (!(ref_cmd->se_cmd)) {
- printk(KERN_ERR "ref_cmd->se_cmd for RefTaskTag: 0x%08x is"
- " NULL!\n", hdr->ref_task_tag);
- return TASK_DOES_NOT_EXIST;
- }
if (ref_cmd->cmd_sn != hdr->ref_cmd_sn) {
printk(KERN_ERR "RefCmdSN 0x%08x does not equal"
" task's CmdSN 0x%08x. Rejecting ABORT_TASK.\n",
@@ -84,7 +79,7 @@ u8 iscsi_tmr_abort_task(
}

se_tmr->ref_task_tag = hdr->ref_task_tag;
- se_tmr->ref_cmd = ref_cmd->se_cmd;
+ se_tmr->ref_cmd = &ref_cmd->se_cmd;
se_tmr->ref_task_lun = hdr->lun;
tmr_req->ref_cmd_sn = hdr->ref_cmd_sn;
tmr_req->exp_data_sn = hdr->exp_data_sn;
@@ -182,10 +177,6 @@ u8 iscsi_tmr_task_reassign(
" connection recovery command list.\n",
hdr->ref_task_tag);
return TASK_DOES_NOT_EXIST;
- } else if (!(ref_cmd->se_cmd)) {
- printk(KERN_ERR "ref_cmd->se_cmd for RefTaskTag: 0x%08x is"
- " NULL!\n", hdr->ref_task_tag);
- return TASK_DOES_NOT_EXIST;
}
/*
* Temporary check to prevent connection recovery for
@@ -200,7 +191,7 @@ u8 iscsi_tmr_task_reassign(
}

se_tmr->ref_task_tag = hdr->ref_task_tag;
- se_tmr->ref_cmd = ref_cmd->se_cmd;
+ se_tmr->ref_cmd = &ref_cmd->se_cmd;
se_tmr->ref_task_lun = hdr->lun;
tmr_req->ref_cmd_sn = hdr->ref_cmd_sn;
tmr_req->exp_data_sn = hdr->exp_data_sn;
@@ -247,7 +238,7 @@ static int iscsi_task_reassign_complete_nop_out(
{
struct se_tmr_req *se_tmr = tmr_req->se_tmr_req;
struct se_cmd *se_cmd = se_tmr->ref_cmd;
- struct iscsi_cmd *cmd = (struct iscsi_cmd *)se_cmd->se_fabric_cmd_ptr;
+ struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
struct iscsi_conn_recovery *cr;

if (!cmd->cr) {
@@ -433,7 +424,7 @@ static int iscsi_task_reassign_complete_scsi_cmnd(
{
struct se_tmr_req *se_tmr = tmr_req->se_tmr_req;
struct se_cmd *se_cmd = se_tmr->ref_cmd;
- struct iscsi_cmd *cmd = (struct iscsi_cmd *)se_cmd->se_fabric_cmd_ptr;
+ struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
struct iscsi_conn_recovery *cr;

if (!cmd->cr) {
@@ -493,7 +484,7 @@ static int iscsi_task_reassign_complete(
return -1;
}
se_cmd = se_tmr->ref_cmd;
- cmd = se_cmd->se_fabric_cmd_ptr;
+ cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);

cmd->conn = conn;

@@ -633,7 +624,7 @@ int iscsi_task_reassign_prepare_write(
{
struct se_tmr_req *se_tmr = tmr_req->se_tmr_req;
struct se_cmd *se_cmd = se_tmr->ref_cmd;
- struct iscsi_cmd *cmd = (struct iscsi_cmd *)se_cmd->se_fabric_cmd_ptr;
+ struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
struct iscsi_pdu *pdu = NULL;
struct iscsi_r2t *r2t = NULL, *r2t_tmp;
int first_incomplete_r2t = 1, i = 0;
@@ -869,7 +860,7 @@ int iscsi_check_task_reassign_expdatasn(
{
struct se_tmr_req *se_tmr = tmr_req->se_tmr_req;
struct se_cmd *se_cmd = se_tmr->ref_cmd;
- struct iscsi_cmd *ref_cmd = (struct iscsi_cmd *)se_cmd->se_fabric_cmd_ptr;
+ struct iscsi_cmd *ref_cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);

if (ref_cmd->iscsi_opcode != ISCSI_INIT_SCSI_CMND)
return 0;
diff --git a/drivers/target/lio-target/iscsi_target_util.c b/drivers/target/lio-target/iscsi_target_util.c
index ad05952..91bbf80 100644
--- a/drivers/target/lio-target/iscsi_target_util.c
+++ b/drivers/target/lio-target/iscsi_target_util.c
@@ -277,6 +277,7 @@ struct iscsi_cmd *iscsi_allocate_se_cmd(
int iscsi_task_attr)
{
struct iscsi_cmd *cmd;
+ struct se_cmd *se_cmd;
int sam_task_attr;

cmd = iscsi_allocate_cmd(conn);
@@ -302,21 +303,15 @@ struct iscsi_cmd *iscsi_allocate_se_cmd(
" TASK_ATTR_SIMPLE\n", iscsi_task_attr);
sam_task_attr = TASK_ATTR_SIMPLE;
}
+
+ se_cmd = &cmd->se_cmd;
/*
- * Use struct target_fabric_configfs->tf_ops for
- * lio_target_fabric_configfs
+ * Initialize struct se_cmd descriptor from target_core_mod infrastructure
*/
- cmd->se_cmd = transport_alloc_se_cmd(
- &lio_target_fabric_configfs->tf_ops,
- SESS(conn)->se_sess, (void *)cmd, data_length,
- data_direction, sam_task_attr);
- if (!(cmd->se_cmd))
- goto out;
-
+ transport_init_se_cmd(se_cmd, &lio_target_fabric_configfs->tf_ops,
+ SESS(conn)->se_sess, data_length, data_direction,
+ sam_task_attr, &cmd->sense_buffer[0]);
return cmd;
-out:
- iscsi_release_cmd_to_pool(cmd);
- return NULL;
}

/* iscsi_allocate_tmr_req():
@@ -328,7 +323,7 @@ struct iscsi_cmd *iscsi_allocate_se_cmd_for_tmr(
u8 function)
{
struct iscsi_cmd *cmd;
- struct se_cmd *se_cmd = NULL;
+ struct se_cmd *se_cmd;

cmd = iscsi_allocate_cmd(conn);
if (!(cmd))
@@ -349,14 +344,13 @@ struct iscsi_cmd *iscsi_allocate_se_cmd_for_tmr(
if (function == TASK_REASSIGN)
return cmd;

- cmd->se_cmd = transport_alloc_se_cmd(
- &lio_target_fabric_configfs->tf_ops,
- SESS(conn)->se_sess, (void *)cmd, 0,
- SE_DIRECTION_NONE, TASK_ATTR_SIMPLE);
- if (!(cmd->se_cmd))
- goto out;
-
- se_cmd = cmd->se_cmd;
+ se_cmd = &cmd->se_cmd;
+ /*
+ * Initialize struct se_cmd descriptor from target_core_mod infrastructure
+ */
+ transport_init_se_cmd(se_cmd, &lio_target_fabric_configfs->tf_ops,
+ SESS(conn)->se_sess, 0, SE_DIRECTION_NONE,
+ TASK_ATTR_SIMPLE, &cmd->sense_buffer[0]);

se_cmd->se_tmr_req = core_tmr_alloc_req(se_cmd,
(void *)cmd->tmr_req, function);
@@ -1030,7 +1024,9 @@ void iscsi_release_cmd_direct(struct iscsi_cmd *cmd)

void lio_release_cmd_direct(struct se_cmd *se_cmd)
{
- iscsi_release_cmd_direct((struct iscsi_cmd *)se_cmd->se_fabric_cmd_ptr);
+ struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
+
+ iscsi_release_cmd_direct(cmd);
}

/* __iscsi_release_cmd_to_pool():
@@ -1074,7 +1070,9 @@ void iscsi_release_cmd_to_pool(struct iscsi_cmd *cmd)

void lio_release_cmd_to_pool(struct se_cmd *se_cmd)
{
- iscsi_release_cmd_to_pool((struct iscsi_cmd *)se_cmd->se_fabric_cmd_ptr);
+ struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
+
+ iscsi_release_cmd_to_pool(cmd);
}

/* iscsi_pack_lun():
--
1.5.6.5

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