aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2007-05-30 13:57:19 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-06-02 15:34:46 -0400
commit1548271ece9e9312fd5feb41fd58773b56a71d39 (patch)
tree89f990788a619a52c3ba4ecbf5f2a596c5711d04
parent77a23c21aaa723f6b0ffc4a701be8c8e5a32346d (diff)
[SCSI] libiscsi: make can_queue configurable
This patch allows us to set can_queue and cmds_per_lun from userspace when we create the session/host. From there we can set it on a per target basis. The patch fully converts iscsi_tcp, but only hooks up ib_iser for cmd_per_lun since it currently has a lots of preallocations based on can_queue. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Cc: Roland Dreier <rdreier@cisco.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c11
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.h4
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c4
-rw-r--r--drivers/scsi/iscsi_tcp.c5
-rw-r--r--drivers/scsi/libiscsi.c28
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c2
-rw-r--r--include/scsi/iscsi_if.h2
-rw-r--r--include/scsi/libiscsi.h7
-rw-r--r--include/scsi/scsi_transport_iscsi.h3
9 files changed, 52 insertions, 14 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 9782190a9ee5..bed583c426e6 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -373,7 +373,8 @@ static struct iscsi_transport iscsi_iser_transport;
373static struct iscsi_cls_session * 373static struct iscsi_cls_session *
374iscsi_iser_session_create(struct iscsi_transport *iscsit, 374iscsi_iser_session_create(struct iscsi_transport *iscsit,
375 struct scsi_transport_template *scsit, 375 struct scsi_transport_template *scsit,
376 uint32_t initial_cmdsn, uint32_t *hostno) 376 uint16_t cmds_max, uint16_t qdepth,
377 uint32_t initial_cmdsn, uint32_t *hostno)
377{ 378{
378 struct iscsi_cls_session *cls_session; 379 struct iscsi_cls_session *cls_session;
379 struct iscsi_session *session; 380 struct iscsi_session *session;
@@ -384,7 +385,13 @@ iscsi_iser_session_create(struct iscsi_transport *iscsit,
384 struct iscsi_iser_cmd_task *iser_ctask; 385 struct iscsi_iser_cmd_task *iser_ctask;
385 struct iser_desc *desc; 386 struct iser_desc *desc;
386 387
388 /*
389 * we do not support setting can_queue cmd_per_lun from userspace yet
390 * because we preallocate so many resources
391 */
387 cls_session = iscsi_session_setup(iscsit, scsit, 392 cls_session = iscsi_session_setup(iscsit, scsit,
393 ISCSI_DEF_XMIT_CMDS_MAX,
394 ISCSI_MAX_CMD_PER_LUN,
388 sizeof(struct iscsi_iser_cmd_task), 395 sizeof(struct iscsi_iser_cmd_task),
389 sizeof(struct iser_desc), 396 sizeof(struct iser_desc),
390 initial_cmdsn, &hn); 397 initial_cmdsn, &hn);
@@ -543,7 +550,7 @@ iscsi_iser_ep_disconnect(__u64 ep_handle)
543static struct scsi_host_template iscsi_iser_sht = { 550static struct scsi_host_template iscsi_iser_sht = {
544 .name = "iSCSI Initiator over iSER, v." DRV_VER, 551 .name = "iSCSI Initiator over iSER, v." DRV_VER,
545 .queuecommand = iscsi_queuecommand, 552 .queuecommand = iscsi_queuecommand,
546 .can_queue = ISCSI_XMIT_CMDS_MAX - 1, 553 .can_queue = ISCSI_DEF_XMIT_CMDS_MAX - 1,
547 .sg_tablesize = ISCSI_ISER_SG_TABLESIZE, 554 .sg_tablesize = ISCSI_ISER_SG_TABLESIZE,
548 .max_sectors = 1024, 555 .max_sectors = 1024,
549 .cmd_per_lun = ISCSI_MAX_CMD_PER_LUN, 556 .cmd_per_lun = ISCSI_MAX_CMD_PER_LUN,
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
index 8960196ffb0f..e2353701e8bb 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -98,7 +98,7 @@
98#define ISER_MAX_TX_MISC_PDUS 6 /* NOOP_OUT(2), TEXT(1), * 98#define ISER_MAX_TX_MISC_PDUS 6 /* NOOP_OUT(2), TEXT(1), *
99 * SCSI_TMFUNC(2), LOGOUT(1) */ 99 * SCSI_TMFUNC(2), LOGOUT(1) */
100 100
101#define ISER_QP_MAX_RECV_DTOS (ISCSI_XMIT_CMDS_MAX + \ 101#define ISER_QP_MAX_RECV_DTOS (ISCSI_DEF_XMIT_CMDS_MAX + \
102 ISER_MAX_RX_MISC_PDUS + \ 102 ISER_MAX_RX_MISC_PDUS + \
103 ISER_MAX_TX_MISC_PDUS) 103 ISER_MAX_TX_MISC_PDUS)
104 104
@@ -110,7 +110,7 @@
110 110
111#define ISER_INFLIGHT_DATAOUTS 8 111#define ISER_INFLIGHT_DATAOUTS 8
112 112
113#define ISER_QP_MAX_REQ_DTOS (ISCSI_XMIT_CMDS_MAX * \ 113#define ISER_QP_MAX_REQ_DTOS (ISCSI_DEF_XMIT_CMDS_MAX * \
114 (1 + ISER_INFLIGHT_DATAOUTS) + \ 114 (1 + ISER_INFLIGHT_DATAOUTS) + \
115 ISER_MAX_TX_MISC_PDUS + \ 115 ISER_MAX_TX_MISC_PDUS + \
116 ISER_MAX_RX_MISC_PDUS) 116 ISER_MAX_RX_MISC_PDUS)
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 3702e2375553..2044de1164ac 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -155,8 +155,8 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
155 params.max_pages_per_fmr = ISCSI_ISER_SG_TABLESIZE + 1; 155 params.max_pages_per_fmr = ISCSI_ISER_SG_TABLESIZE + 1;
156 /* make the pool size twice the max number of SCSI commands * 156 /* make the pool size twice the max number of SCSI commands *
157 * the ML is expected to queue, watermark for unmap at 50% */ 157 * the ML is expected to queue, watermark for unmap at 50% */
158 params.pool_size = ISCSI_XMIT_CMDS_MAX * 2; 158 params.pool_size = ISCSI_DEF_XMIT_CMDS_MAX * 2;
159 params.dirty_watermark = ISCSI_XMIT_CMDS_MAX; 159 params.dirty_watermark = ISCSI_DEF_XMIT_CMDS_MAX;
160 params.cache = 0; 160 params.cache = 0;
161 params.flush_function = NULL; 161 params.flush_function = NULL;
162 params.access = (IB_ACCESS_LOCAL_WRITE | 162 params.access = (IB_ACCESS_LOCAL_WRITE |
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 8edcfddc0baf..eca4d611dd49 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -2114,6 +2114,7 @@ iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats)
2114static struct iscsi_cls_session * 2114static struct iscsi_cls_session *
2115iscsi_tcp_session_create(struct iscsi_transport *iscsit, 2115iscsi_tcp_session_create(struct iscsi_transport *iscsit,
2116 struct scsi_transport_template *scsit, 2116 struct scsi_transport_template *scsit,
2117 uint16_t cmds_max, uint16_t qdepth,
2117 uint32_t initial_cmdsn, uint32_t *hostno) 2118 uint32_t initial_cmdsn, uint32_t *hostno)
2118{ 2119{
2119 struct iscsi_cls_session *cls_session; 2120 struct iscsi_cls_session *cls_session;
@@ -2121,7 +2122,7 @@ iscsi_tcp_session_create(struct iscsi_transport *iscsit,
2121 uint32_t hn; 2122 uint32_t hn;
2122 int cmd_i; 2123 int cmd_i;
2123 2124
2124 cls_session = iscsi_session_setup(iscsit, scsit, 2125 cls_session = iscsi_session_setup(iscsit, scsit, cmds_max, qdepth,
2125 sizeof(struct iscsi_tcp_cmd_task), 2126 sizeof(struct iscsi_tcp_cmd_task),
2126 sizeof(struct iscsi_tcp_mgmt_task), 2127 sizeof(struct iscsi_tcp_mgmt_task),
2127 initial_cmdsn, &hn); 2128 initial_cmdsn, &hn);
@@ -2164,7 +2165,7 @@ static struct scsi_host_template iscsi_sht = {
2164 .name = "iSCSI Initiator over TCP/IP", 2165 .name = "iSCSI Initiator over TCP/IP",
2165 .queuecommand = iscsi_queuecommand, 2166 .queuecommand = iscsi_queuecommand,
2166 .change_queue_depth = iscsi_change_queue_depth, 2167 .change_queue_depth = iscsi_change_queue_depth,
2167 .can_queue = ISCSI_XMIT_CMDS_MAX - 1, 2168 .can_queue = ISCSI_DEF_XMIT_CMDS_MAX - 1,
2168 .sg_tablesize = ISCSI_SG_TABLESIZE, 2169 .sg_tablesize = ISCSI_SG_TABLESIZE,
2169 .max_sectors = 0xFFFF, 2170 .max_sectors = 0xFFFF,
2170 .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, 2171 .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN,
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 938f527cd81a..1632866f52cc 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1330,6 +1330,10 @@ EXPORT_SYMBOL_GPL(iscsi_pool_free);
1330 * iscsi_session_setup - create iscsi cls session and host and session 1330 * iscsi_session_setup - create iscsi cls session and host and session
1331 * @scsit: scsi transport template 1331 * @scsit: scsi transport template
1332 * @iscsit: iscsi transport template 1332 * @iscsit: iscsi transport template
1333 * @cmds_max: scsi host can queue
1334 * @qdepth: scsi host cmds per lun
1335 * @cmd_task_size: LLD ctask private data size
1336 * @mgmt_task_size: LLD mtask private data size
1333 * @initial_cmdsn: initial CmdSN 1337 * @initial_cmdsn: initial CmdSN
1334 * @hostno: host no allocated 1338 * @hostno: host no allocated
1335 * 1339 *
@@ -1339,6 +1343,7 @@ EXPORT_SYMBOL_GPL(iscsi_pool_free);
1339struct iscsi_cls_session * 1343struct iscsi_cls_session *
1340iscsi_session_setup(struct iscsi_transport *iscsit, 1344iscsi_session_setup(struct iscsi_transport *iscsit,
1341 struct scsi_transport_template *scsit, 1345 struct scsi_transport_template *scsit,
1346 uint16_t cmds_max, uint16_t qdepth,
1342 int cmd_task_size, int mgmt_task_size, 1347 int cmd_task_size, int mgmt_task_size,
1343 uint32_t initial_cmdsn, uint32_t *hostno) 1348 uint32_t initial_cmdsn, uint32_t *hostno)
1344{ 1349{
@@ -1347,11 +1352,32 @@ iscsi_session_setup(struct iscsi_transport *iscsit,
1347 struct iscsi_cls_session *cls_session; 1352 struct iscsi_cls_session *cls_session;
1348 int cmd_i; 1353 int cmd_i;
1349 1354
1355 if (qdepth > ISCSI_MAX_CMD_PER_LUN || qdepth < 1) {
1356 if (qdepth != 0)
1357 printk(KERN_ERR "iscsi: invalid queue depth of %d. "
1358 "Queue depth must be between 1 and %d.\n",
1359 qdepth, ISCSI_MAX_CMD_PER_LUN);
1360 qdepth = ISCSI_DEF_CMD_PER_LUN;
1361 }
1362
1363 if (cmds_max < 2 || (cmds_max & (cmds_max - 1)) ||
1364 cmds_max >= ISCSI_MGMT_ITT_OFFSET) {
1365 if (cmds_max != 0)
1366 printk(KERN_ERR "iscsi: invalid can_queue of %d. "
1367 "can_queue must be a power of 2 and between "
1368 "2 and %d - setting to %d.\n", cmds_max,
1369 ISCSI_MGMT_ITT_OFFSET, ISCSI_DEF_XMIT_CMDS_MAX);
1370 cmds_max = ISCSI_DEF_XMIT_CMDS_MAX;
1371 }
1372
1350 shost = scsi_host_alloc(iscsit->host_template, 1373 shost = scsi_host_alloc(iscsit->host_template,
1351 hostdata_privsize(sizeof(*session))); 1374 hostdata_privsize(sizeof(*session)));
1352 if (!shost) 1375 if (!shost)
1353 return NULL; 1376 return NULL;
1354 1377
1378 /* the iscsi layer takes one task for reserve */
1379 shost->can_queue = cmds_max - 1;
1380 shost->cmd_per_lun = qdepth;
1355 shost->max_id = 1; 1381 shost->max_id = 1;
1356 shost->max_channel = 0; 1382 shost->max_channel = 0;
1357 shost->max_lun = iscsit->max_lun; 1383 shost->max_lun = iscsit->max_lun;
@@ -1365,7 +1391,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit,
1365 session->host = shost; 1391 session->host = shost;
1366 session->state = ISCSI_STATE_FREE; 1392 session->state = ISCSI_STATE_FREE;
1367 session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX; 1393 session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX;
1368 session->cmds_max = ISCSI_XMIT_CMDS_MAX; 1394 session->cmds_max = cmds_max;
1369 session->cmdsn = initial_cmdsn; 1395 session->cmdsn = initial_cmdsn;
1370 session->exp_cmdsn = initial_cmdsn + 1; 1396 session->exp_cmdsn = initial_cmdsn + 1;
1371 session->max_cmdsn = initial_cmdsn + 1; 1397 session->max_cmdsn = initial_cmdsn + 1;
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 341d4fb5c6f8..859bd2100856 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -814,6 +814,8 @@ iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev)
814 uint32_t hostno; 814 uint32_t hostno;
815 815
816 session = transport->create_session(transport, &priv->t, 816 session = transport->create_session(transport, &priv->t,
817 ev->u.c_session.cmds_max,
818 ev->u.c_session.queue_depth,
817 ev->u.c_session.initial_cmdsn, 819 ev->u.c_session.initial_cmdsn,
818 &hostno); 820 &hostno);
819 if (!session) 821 if (!session)
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index 1a18196d77f6..a046a329189c 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -72,6 +72,8 @@ struct iscsi_uevent {
72 /* messages u -> k */ 72 /* messages u -> k */
73 struct msg_create_session { 73 struct msg_create_session {
74 uint32_t initial_cmdsn; 74 uint32_t initial_cmdsn;
75 uint16_t cmds_max;
76 uint16_t queue_depth;
75 } c_session; 77 } c_session;
76 struct msg_destroy_session { 78 struct msg_destroy_session {
77 uint32_t sid; 79 uint32_t sid;
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 8d48cf8f2e3f..2f303a3b270e 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -48,9 +48,8 @@ struct iscsi_nopin;
48#define debug_scsi(fmt...) 48#define debug_scsi(fmt...)
49#endif 49#endif
50 50
51#define ISCSI_XMIT_CMDS_MAX 128 /* must be power of 2 */ 51#define ISCSI_DEF_XMIT_CMDS_MAX 128 /* must be power of 2 */
52#define ISCSI_MGMT_CMDS_MAX 32 /* must be power of 2 */ 52#define ISCSI_MGMT_CMDS_MAX 16 /* must be power of 2 */
53#define ISCSI_CONN_MAX 1
54 53
55#define ISCSI_MGMT_ITT_OFFSET 0xa00 54#define ISCSI_MGMT_ITT_OFFSET 0xa00
56 55
@@ -268,7 +267,7 @@ extern int iscsi_host_get_param(struct Scsi_Host *shost,
268 */ 267 */
269extern struct iscsi_cls_session * 268extern struct iscsi_cls_session *
270iscsi_session_setup(struct iscsi_transport *, struct scsi_transport_template *, 269iscsi_session_setup(struct iscsi_transport *, struct scsi_transport_template *,
271 int, int, uint32_t, uint32_t *); 270 uint16_t, uint16_t, int, int, uint32_t, uint32_t *);
272extern void iscsi_session_teardown(struct iscsi_cls_session *); 271extern void iscsi_session_teardown(struct iscsi_cls_session *);
273extern struct iscsi_session *class_to_transport_session(struct iscsi_cls_session *); 272extern struct iscsi_session *class_to_transport_session(struct iscsi_cls_session *);
274extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *); 273extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *);
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index abc4068621d8..706c0cd36c14 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -90,7 +90,8 @@ struct iscsi_transport {
90 unsigned int max_conn; 90 unsigned int max_conn;
91 unsigned int max_cmd_len; 91 unsigned int max_cmd_len;
92 struct iscsi_cls_session *(*create_session) (struct iscsi_transport *it, 92 struct iscsi_cls_session *(*create_session) (struct iscsi_transport *it,
93 struct scsi_transport_template *t, uint32_t sn, uint32_t *hn); 93 struct scsi_transport_template *t, uint16_t, uint16_t,
94 uint32_t sn, uint32_t *hn);
94 void (*destroy_session) (struct iscsi_cls_session *session); 95 void (*destroy_session) (struct iscsi_cls_session *session);
95 struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess, 96 struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess,
96 uint32_t cid); 97 uint32_t cid);