aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@daterainc.com>2013-08-17 18:49:08 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2013-09-09 17:29:22 -0400
commit988e3a85463d9b6dabc681df3f8f131b23c19953 (patch)
tree26ae4d803ff49f0938d20f910be19a172a64d8a4
parentd703ce2f7f4de20c03d71c22a9d5e3708798047b (diff)
iscsi-target: Convert to per-cpu ida_alloc + ida_free command map
This patch changes iscsi-target to use transport_alloc_session_tags() pre-allocation logic for per-cpu session tag pooling with internal ida_alloc() + ida_free() calls based upon the saved se_cmd->map_tag id. This includes tag pool setup based upon per NodeACL queue_depth after locating se_node_acl in iscsi_target_locate_portal(). Also update iscsit_allocate_cmd() and iscsit_release_cmd() to use percpu_ida_alloc() and percpu_ida_free() respectively. v5 changes; - Convert to percpu_ida.h include v2 changes: - Fix bug with SessionType=Discovery in iscsi_target_locate_portal() Cc: Or Gerlitz <ogerlitz@mellanox.com> Cc: Kent Overstreet <kmo@daterainc.com> Signed-off-by: Nicholas Bellinger <nab@daterainc.com>
-rw-r--r--drivers/target/iscsi/iscsi_target_core.h2
-rw-r--r--drivers/target/iscsi/iscsi_target_nego.c28
-rw-r--r--drivers/target/iscsi/iscsi_target_util.c27
3 files changed, 46 insertions, 11 deletions
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h
index 129b7d77c7cb..af3cd7a47799 100644
--- a/drivers/target/iscsi/iscsi_target_core.h
+++ b/drivers/target/iscsi/iscsi_target_core.h
@@ -17,6 +17,8 @@
17#define SECONDS_FOR_ASYNC_TEXT 10 17#define SECONDS_FOR_ASYNC_TEXT 10
18#define SECONDS_FOR_LOGOUT_COMP 15 18#define SECONDS_FOR_LOGOUT_COMP 15
19#define WHITE_SPACE " \t\v\f\n\r" 19#define WHITE_SPACE " \t\v\f\n\r"
20#define ISCSIT_MIN_TAGS 16
21#define ISCSIT_EXTRA_TAGS 8
20 22
21/* struct iscsi_node_attrib sanity values */ 23/* struct iscsi_node_attrib sanity values */
22#define NA_DATAOUT_TIMEOUT 3 24#define NA_DATAOUT_TIMEOUT 3
diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c
index 2cce636d1113..24b0e33e7c50 100644
--- a/drivers/target/iscsi/iscsi_target_nego.c
+++ b/drivers/target/iscsi/iscsi_target_nego.c
@@ -983,8 +983,9 @@ int iscsi_target_locate_portal(
983 struct iscsi_tiqn *tiqn; 983 struct iscsi_tiqn *tiqn;
984 struct iscsi_tpg_np *tpg_np = NULL; 984 struct iscsi_tpg_np *tpg_np = NULL;
985 struct iscsi_login_req *login_req; 985 struct iscsi_login_req *login_req;
986 u32 payload_length; 986 struct se_node_acl *se_nacl;
987 int sessiontype = 0, ret = 0; 987 u32 payload_length, queue_depth = 0;
988 int sessiontype = 0, ret = 0, tag_num, tag_size;
988 989
989 INIT_DELAYED_WORK(&conn->login_work, iscsi_target_do_login_rx); 990 INIT_DELAYED_WORK(&conn->login_work, iscsi_target_do_login_rx);
990 INIT_DELAYED_WORK(&conn->login_cleanup_work, iscsi_target_do_cleanup); 991 INIT_DELAYED_WORK(&conn->login_cleanup_work, iscsi_target_do_cleanup);
@@ -1084,7 +1085,7 @@ int iscsi_target_locate_portal(
1084 goto out; 1085 goto out;
1085 } 1086 }
1086 ret = 0; 1087 ret = 0;
1087 goto out; 1088 goto alloc_tags;
1088 } 1089 }
1089 1090
1090get_target: 1091get_target:
@@ -1181,8 +1182,27 @@ get_target:
1181 ret = -1; 1182 ret = -1;
1182 goto out; 1183 goto out;
1183 } 1184 }
1185 se_nacl = sess->se_sess->se_node_acl;
1186 queue_depth = se_nacl->queue_depth;
1187 /*
1188 * Setup pre-allocated tags based upon allowed per NodeACL CmdSN
1189 * depth for non immediate commands, plus extra tags for immediate
1190 * commands.
1191 *
1192 * Also enforce a ISCSIT_MIN_TAGS to prevent unnecessary contention
1193 * in per-cpu-ida tag allocation logic + small queue_depth.
1194 */
1195alloc_tags:
1196 tag_num = max_t(u32, ISCSIT_MIN_TAGS, queue_depth);
1197 tag_num += ISCSIT_EXTRA_TAGS;
1198 tag_size = sizeof(struct iscsi_cmd) + conn->conn_transport->priv_size;
1184 1199
1185 ret = 0; 1200 ret = transport_alloc_session_tags(sess->se_sess, tag_num, tag_size);
1201 if (ret < 0) {
1202 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
1203 ISCSI_LOGIN_STATUS_NO_RESOURCES);
1204 ret = -1;
1205 }
1186out: 1206out:
1187 kfree(tmpbuf); 1207 kfree(tmpbuf);
1188 return ret; 1208 return ret;
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c
index 5784cad16be1..8d85d8cceb42 100644
--- a/drivers/target/iscsi/iscsi_target_util.c
+++ b/drivers/target/iscsi/iscsi_target_util.c
@@ -19,6 +19,7 @@
19 ******************************************************************************/ 19 ******************************************************************************/
20 20
21#include <linux/list.h> 21#include <linux/list.h>
22#include <linux/percpu_ida.h>
22#include <scsi/scsi_tcq.h> 23#include <scsi/scsi_tcq.h>
23#include <scsi/iscsi_proto.h> 24#include <scsi/iscsi_proto.h>
24#include <target/target_core_base.h> 25#include <target/target_core_base.h>
@@ -156,13 +157,15 @@ void iscsit_free_r2ts_from_list(struct iscsi_cmd *cmd)
156struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *conn, gfp_t gfp_mask) 157struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *conn, gfp_t gfp_mask)
157{ 158{
158 struct iscsi_cmd *cmd; 159 struct iscsi_cmd *cmd;
159 int priv_size = conn->conn_transport->priv_size; 160 struct se_session *se_sess = conn->sess->se_sess;
161 int size, tag;
160 162
161 cmd = kzalloc(sizeof(struct iscsi_cmd) + priv_size, gfp_mask); 163 tag = percpu_ida_alloc(&se_sess->sess_tag_pool, gfp_mask);
162 if (!cmd) { 164 size = sizeof(struct iscsi_cmd) + conn->conn_transport->priv_size;
163 pr_err("Unable to allocate memory for struct iscsi_cmd.\n"); 165 cmd = (struct iscsi_cmd *)(se_sess->sess_cmd_map + (tag * size));
164 return NULL; 166 memset(cmd, 0, size);
165 } 167
168 cmd->se_cmd.map_tag = tag;
166 cmd->conn = conn; 169 cmd->conn = conn;
167 INIT_LIST_HEAD(&cmd->i_conn_node); 170 INIT_LIST_HEAD(&cmd->i_conn_node);
168 INIT_LIST_HEAD(&cmd->datain_list); 171 INIT_LIST_HEAD(&cmd->datain_list);
@@ -678,6 +681,16 @@ void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn)
678 681
679void iscsit_release_cmd(struct iscsi_cmd *cmd) 682void iscsit_release_cmd(struct iscsi_cmd *cmd)
680{ 683{
684 struct iscsi_session *sess;
685 struct se_cmd *se_cmd = &cmd->se_cmd;
686
687 if (cmd->conn)
688 sess = cmd->conn->sess;
689 else
690 sess = cmd->sess;
691
692 BUG_ON(!sess || !sess->se_sess);
693
681 kfree(cmd->buf_ptr); 694 kfree(cmd->buf_ptr);
682 kfree(cmd->pdu_list); 695 kfree(cmd->pdu_list);
683 kfree(cmd->seq_list); 696 kfree(cmd->seq_list);
@@ -685,7 +698,7 @@ void iscsit_release_cmd(struct iscsi_cmd *cmd)
685 kfree(cmd->iov_data); 698 kfree(cmd->iov_data);
686 kfree(cmd->text_in_ptr); 699 kfree(cmd->text_in_ptr);
687 700
688 kfree(cmd); 701 percpu_ida_free(&sess->se_sess->sess_tag_pool, se_cmd->map_tag);
689} 702}
690EXPORT_SYMBOL(iscsit_release_cmd); 703EXPORT_SYMBOL(iscsit_release_cmd);
691 704