diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2007-05-30 13:57:19 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-06-02 15:34:46 -0400 |
commit | 1548271ece9e9312fd5feb41fd58773b56a71d39 (patch) | |
tree | 89f990788a619a52c3ba4ecbf5f2a596c5711d04 | |
parent | 77a23c21aaa723f6b0ffc4a701be8c8e5a32346d (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.c | 11 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iscsi_iser.h | 4 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_verbs.c | 4 | ||||
-rw-r--r-- | drivers/scsi/iscsi_tcp.c | 5 | ||||
-rw-r--r-- | drivers/scsi/libiscsi.c | 28 | ||||
-rw-r--r-- | drivers/scsi/scsi_transport_iscsi.c | 2 | ||||
-rw-r--r-- | include/scsi/iscsi_if.h | 2 | ||||
-rw-r--r-- | include/scsi/libiscsi.h | 7 | ||||
-rw-r--r-- | include/scsi/scsi_transport_iscsi.h | 3 |
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; | |||
373 | static struct iscsi_cls_session * | 373 | static struct iscsi_cls_session * |
374 | iscsi_iser_session_create(struct iscsi_transport *iscsit, | 374 | iscsi_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) | |||
543 | static struct scsi_host_template iscsi_iser_sht = { | 550 | static 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) | |||
2114 | static struct iscsi_cls_session * | 2114 | static struct iscsi_cls_session * |
2115 | iscsi_tcp_session_create(struct iscsi_transport *iscsit, | 2115 | iscsi_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); | |||
1339 | struct iscsi_cls_session * | 1343 | struct iscsi_cls_session * |
1340 | iscsi_session_setup(struct iscsi_transport *iscsit, | 1344 | iscsi_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 | */ |
269 | extern struct iscsi_cls_session * | 268 | extern struct iscsi_cls_session * |
270 | iscsi_session_setup(struct iscsi_transport *, struct scsi_transport_template *, | 269 | iscsi_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 *); |
272 | extern void iscsi_session_teardown(struct iscsi_cls_session *); | 271 | extern void iscsi_session_teardown(struct iscsi_cls_session *); |
273 | extern struct iscsi_session *class_to_transport_session(struct iscsi_cls_session *); | 272 | extern struct iscsi_session *class_to_transport_session(struct iscsi_cls_session *); |
274 | extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *); | 273 | extern 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); |