aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2006-05-18 21:31:36 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-05-20 10:35:20 -0400
commitffbfe92533810bf1bb76fd275400825ef8898ed9 (patch)
treedbb251eaf0196df7b69d8af76a03cba0e1d9ad18 /drivers
parentd36ab6f3212053b260214bc915687765e2fd1178 (diff)
[SCSI] iscsi: kill dtask mempools
Discovered by steven@hayter.me.uk and patch by michaelc@cs.wisc.edu The dtask mempool is reserving 261120 items per session! Since we are now sending headers with sendmsg there is no reason for the mempool and that was causing us to us carzy amounts of mem. We can preallicate a header in the r2t and task struct and reuse them Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/iscsi_tcp.c87
-rw-r--r--drivers/scsi/iscsi_tcp.h11
2 files changed, 10 insertions, 88 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 7c2ed7bb7e94..08357a6c7e09 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -67,9 +67,6 @@ MODULE_VERSION("0:4.445");
67static unsigned int iscsi_max_lun = 512; 67static unsigned int iscsi_max_lun = 512;
68module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO); 68module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
69 69
70/* global data */
71static kmem_cache_t *taskcache;
72
73static inline void 70static inline void
74iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size) 71iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
75{ 72{
@@ -195,16 +192,6 @@ __iscsi_ctask_cleanup(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
195 if (unlikely(!sc)) 192 if (unlikely(!sc))
196 return; 193 return;
197 194
198 if (sc->sc_data_direction == DMA_TO_DEVICE) {
199 struct iscsi_data_task *dtask, *n;
200
201 /* WRITE: cleanup Data-Out's if any */
202 list_for_each_entry_safe(dtask, n, &tcp_ctask->dataqueue,
203 item) {
204 list_del(&dtask->item);
205 mempool_free(dtask, tcp_ctask->datapool);
206 }
207 }
208 tcp_ctask->xmstate = XMSTATE_IDLE; 195 tcp_ctask->xmstate = XMSTATE_IDLE;
209 tcp_ctask->r2t = NULL; 196 tcp_ctask->r2t = NULL;
210} 197}
@@ -286,14 +273,10 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
286 struct iscsi_r2t_info *r2t) 273 struct iscsi_r2t_info *r2t)
287{ 274{
288 struct iscsi_data *hdr; 275 struct iscsi_data *hdr;
289 struct iscsi_data_task *dtask;
290 struct scsi_cmnd *sc = ctask->sc; 276 struct scsi_cmnd *sc = ctask->sc;
291 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 277 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
292 278
293 dtask = mempool_alloc(tcp_ctask->datapool, GFP_ATOMIC); 279 hdr = &r2t->dtask.hdr;
294 BUG_ON(!dtask);
295 INIT_LIST_HEAD(&dtask->item);
296 hdr = &dtask->hdr;
297 memset(hdr, 0, sizeof(struct iscsi_data)); 280 memset(hdr, 0, sizeof(struct iscsi_data));
298 hdr->ttt = r2t->ttt; 281 hdr->ttt = r2t->ttt;
299 hdr->datasn = cpu_to_be32(r2t->solicit_datasn); 282 hdr->datasn = cpu_to_be32(r2t->solicit_datasn);
@@ -319,8 +302,6 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
319 iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr, 302 iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr,
320 sizeof(struct iscsi_hdr)); 303 sizeof(struct iscsi_hdr));
321 304
322 r2t->dtask = dtask;
323
324 if (sc->use_sg) { 305 if (sc->use_sg) {
325 int i, sg_count = 0; 306 int i, sg_count = 0;
326 struct scatterlist *sg = sc->request_buffer; 307 struct scatterlist *sg = sc->request_buffer;
@@ -352,8 +333,6 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
352 iscsi_buf_init_iov(&tcp_ctask->sendbuf, 333 iscsi_buf_init_iov(&tcp_ctask->sendbuf,
353 (char*)sc->request_buffer + r2t->data_offset, 334 (char*)sc->request_buffer + r2t->data_offset,
354 r2t->data_count); 335 r2t->data_count);
355
356 list_add(&dtask->item, &tcp_ctask->dataqueue);
357} 336}
358 337
359/** 338/**
@@ -1229,14 +1208,10 @@ iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1229{ 1208{
1230 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1209 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1231 struct iscsi_data *hdr; 1210 struct iscsi_data *hdr;
1232 struct iscsi_data_task *dtask;
1233 struct scsi_cmnd *sc = ctask->sc; 1211 struct scsi_cmnd *sc = ctask->sc;
1234 int new_offset; 1212 int new_offset;
1235 1213
1236 dtask = mempool_alloc(tcp_ctask->datapool, GFP_ATOMIC); 1214 hdr = &r2t->dtask.hdr;
1237 BUG_ON(!dtask);
1238 INIT_LIST_HEAD(&dtask->item);
1239 hdr = &dtask->hdr;
1240 memset(hdr, 0, sizeof(struct iscsi_data)); 1215 memset(hdr, 0, sizeof(struct iscsi_data));
1241 hdr->ttt = r2t->ttt; 1216 hdr->ttt = r2t->ttt;
1242 hdr->datasn = cpu_to_be32(r2t->solicit_datasn); 1217 hdr->datasn = cpu_to_be32(r2t->solicit_datasn);
@@ -1260,8 +1235,6 @@ iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1260 iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr, 1235 iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr,
1261 sizeof(struct iscsi_hdr)); 1236 sizeof(struct iscsi_hdr));
1262 1237
1263 r2t->dtask = dtask;
1264
1265 if (sc->use_sg && !iscsi_buf_left(&r2t->sendbuf)) { 1238 if (sc->use_sg && !iscsi_buf_left(&r2t->sendbuf)) {
1266 BUG_ON(tcp_ctask->bad_sg == r2t->sg); 1239 BUG_ON(tcp_ctask->bad_sg == r2t->sg);
1267 iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg); 1240 iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg);
@@ -1270,8 +1243,6 @@ iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1270 iscsi_buf_init_iov(&tcp_ctask->sendbuf, 1243 iscsi_buf_init_iov(&tcp_ctask->sendbuf,
1271 (char*)sc->request_buffer + new_offset, 1244 (char*)sc->request_buffer + new_offset,
1272 r2t->data_count); 1245 r2t->data_count);
1273
1274 list_add(&dtask->item, &tcp_ctask->dataqueue);
1275} 1246}
1276 1247
1277static void 1248static void
@@ -1280,17 +1251,11 @@ iscsi_unsolicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1280 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1251 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1281 struct iscsi_data_task *dtask; 1252 struct iscsi_data_task *dtask;
1282 1253
1283 dtask = mempool_alloc(tcp_ctask->datapool, GFP_ATOMIC); 1254 dtask = tcp_ctask->dtask = &tcp_ctask->unsol_dtask;
1284 BUG_ON(!dtask);
1285 INIT_LIST_HEAD(&dtask->item);
1286
1287 iscsi_prep_unsolicit_data_pdu(ctask, &dtask->hdr, 1255 iscsi_prep_unsolicit_data_pdu(ctask, &dtask->hdr,
1288 tcp_ctask->r2t_data_count); 1256 tcp_ctask->r2t_data_count);
1289 iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)&dtask->hdr, 1257 iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)&dtask->hdr,
1290 sizeof(struct iscsi_hdr)); 1258 sizeof(struct iscsi_hdr));
1291
1292 list_add(&dtask->item, &tcp_ctask->dataqueue);
1293 tcp_ctask->dtask = dtask;
1294} 1259}
1295 1260
1296/** 1261/**
@@ -1534,7 +1499,6 @@ handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1534 tcp_ctask->xmstate |= XMSTATE_UNS_DATA; 1499 tcp_ctask->xmstate |= XMSTATE_UNS_DATA;
1535 if (tcp_ctask->xmstate & XMSTATE_UNS_INIT) { 1500 if (tcp_ctask->xmstate & XMSTATE_UNS_INIT) {
1536 iscsi_unsolicit_data_init(conn, ctask); 1501 iscsi_unsolicit_data_init(conn, ctask);
1537 BUG_ON(!tcp_ctask->dtask);
1538 dtask = tcp_ctask->dtask; 1502 dtask = tcp_ctask->dtask;
1539 if (conn->hdrdgst_en) 1503 if (conn->hdrdgst_en)
1540 iscsi_hdr_digest(conn, &tcp_ctask->headbuf, 1504 iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
@@ -1643,7 +1607,7 @@ handle_xmstate_sol_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1643 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 1607 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1644 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1608 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1645 struct iscsi_r2t_info *r2t = tcp_ctask->r2t; 1609 struct iscsi_r2t_info *r2t = tcp_ctask->r2t;
1646 struct iscsi_data_task *dtask = r2t->dtask; 1610 struct iscsi_data_task *dtask = &r2t->dtask;
1647 int left; 1611 int left;
1648 1612
1649 tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA; 1613 tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA;
@@ -1857,7 +1821,7 @@ solicit_head_again:
1857 r2t = tcp_ctask->r2t; 1821 r2t = tcp_ctask->r2t;
1858 if (conn->hdrdgst_en) 1822 if (conn->hdrdgst_en)
1859 iscsi_hdr_digest(conn, &r2t->headbuf, 1823 iscsi_hdr_digest(conn, &r2t->headbuf,
1860 (u8*)r2t->dtask->hdrext); 1824 (u8*)r2t->dtask.hdrext);
1861 if (iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count)) { 1825 if (iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count)) {
1862 tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA; 1826 tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA;
1863 tcp_ctask->xmstate |= XMSTATE_SOL_HDR; 1827 tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
@@ -2113,21 +2077,6 @@ iscsi_r2tpool_alloc(struct iscsi_session *session)
2113 (void**)tcp_ctask->r2ts); 2077 (void**)tcp_ctask->r2ts);
2114 goto r2t_alloc_fail; 2078 goto r2t_alloc_fail;
2115 } 2079 }
2116
2117 /*
2118 * number of
2119 * Data-Out PDU's within R2T-sequence can be quite big;
2120 * using mempool
2121 */
2122 tcp_ctask->datapool = mempool_create_slab_pool(ISCSI_DTASK_DEFAULT_MAX,
2123 taskcache);
2124 if (tcp_ctask->datapool == NULL) {
2125 kfifo_free(tcp_ctask->r2tqueue);
2126 iscsi_pool_free(&tcp_ctask->r2tpool,
2127 (void**)tcp_ctask->r2ts);
2128 goto r2t_alloc_fail;
2129 }
2130 INIT_LIST_HEAD(&tcp_ctask->dataqueue);
2131 } 2080 }
2132 2081
2133 return 0; 2082 return 0;
@@ -2137,7 +2086,6 @@ r2t_alloc_fail:
2137 struct iscsi_cmd_task *ctask = session->cmds[i]; 2086 struct iscsi_cmd_task *ctask = session->cmds[i];
2138 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 2087 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
2139 2088
2140 mempool_destroy(tcp_ctask->datapool);
2141 kfifo_free(tcp_ctask->r2tqueue); 2089 kfifo_free(tcp_ctask->r2tqueue);
2142 iscsi_pool_free(&tcp_ctask->r2tpool, 2090 iscsi_pool_free(&tcp_ctask->r2tpool,
2143 (void**)tcp_ctask->r2ts); 2091 (void**)tcp_ctask->r2ts);
@@ -2154,7 +2102,6 @@ iscsi_r2tpool_free(struct iscsi_session *session)
2154 struct iscsi_cmd_task *ctask = session->cmds[i]; 2102 struct iscsi_cmd_task *ctask = session->cmds[i];
2155 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 2103 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
2156 2104
2157 mempool_destroy(tcp_ctask->datapool);
2158 kfifo_free(tcp_ctask->r2tqueue); 2105 kfifo_free(tcp_ctask->r2tqueue);
2159 iscsi_pool_free(&tcp_ctask->r2tpool, 2106 iscsi_pool_free(&tcp_ctask->r2tpool,
2160 (void**)tcp_ctask->r2ts); 2107 (void**)tcp_ctask->r2ts);
@@ -2496,21 +2443,6 @@ r2tpool_alloc_fail:
2496 2443
2497static void iscsi_tcp_session_destroy(struct iscsi_cls_session *cls_session) 2444static void iscsi_tcp_session_destroy(struct iscsi_cls_session *cls_session)
2498{ 2445{
2499 struct iscsi_session *session = class_to_transport_session(cls_session);
2500 struct iscsi_data_task *dtask, *n;
2501 int cmd_i;
2502
2503 for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
2504 struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
2505 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
2506
2507 list_for_each_entry_safe(dtask, n, &tcp_ctask->dataqueue,
2508 item) {
2509 list_del(&dtask->item);
2510 mempool_free(dtask, tcp_ctask->datapool);
2511 }
2512 }
2513
2514 iscsi_r2tpool_free(class_to_transport_session(cls_session)); 2446 iscsi_r2tpool_free(class_to_transport_session(cls_session));
2515 iscsi_session_teardown(cls_session); 2447 iscsi_session_teardown(cls_session);
2516} 2448}
@@ -2592,14 +2524,8 @@ iscsi_tcp_init(void)
2592 } 2524 }
2593 iscsi_tcp_transport.max_lun = iscsi_max_lun; 2525 iscsi_tcp_transport.max_lun = iscsi_max_lun;
2594 2526
2595 taskcache = kmem_cache_create("iscsi_taskcache",
2596 sizeof(struct iscsi_data_task), 0,
2597 SLAB_HWCACHE_ALIGN, NULL, NULL);
2598 if (!taskcache)
2599 return -ENOMEM;
2600
2601 if (!iscsi_register_transport(&iscsi_tcp_transport)) 2527 if (!iscsi_register_transport(&iscsi_tcp_transport))
2602 kmem_cache_destroy(taskcache); 2528 return -ENODEV;
2603 2529
2604 return 0; 2530 return 0;
2605} 2531}
@@ -2608,7 +2534,6 @@ static void __exit
2608iscsi_tcp_exit(void) 2534iscsi_tcp_exit(void)
2609{ 2535{
2610 iscsi_unregister_transport(&iscsi_tcp_transport); 2536 iscsi_unregister_transport(&iscsi_tcp_transport);
2611 kmem_cache_destroy(taskcache);
2612} 2537}
2613 2538
2614module_init(iscsi_tcp_init); 2539module_init(iscsi_tcp_init);
diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h
index c5918854d595..808302832e68 100644
--- a/drivers/scsi/iscsi_tcp.h
+++ b/drivers/scsi/iscsi_tcp.h
@@ -118,11 +118,9 @@ struct iscsi_buf {
118struct iscsi_data_task { 118struct iscsi_data_task {
119 struct iscsi_data hdr; /* PDU */ 119 struct iscsi_data hdr; /* PDU */
120 char hdrext[sizeof(__u32)]; /* Header-Digest */ 120 char hdrext[sizeof(__u32)]; /* Header-Digest */
121 struct list_head item; /* data queue item */
122 struct iscsi_buf digestbuf; /* digest buffer */ 121 struct iscsi_buf digestbuf; /* digest buffer */
123 uint32_t digest; /* data digest */ 122 uint32_t digest; /* data digest */
124}; 123};
125#define ISCSI_DTASK_DEFAULT_MAX ISCSI_SG_TABLESIZE * PAGE_SIZE / 512
126 124
127struct iscsi_tcp_mgmt_task { 125struct iscsi_tcp_mgmt_task {
128 struct iscsi_hdr hdr; 126 struct iscsi_hdr hdr;
@@ -144,7 +142,7 @@ struct iscsi_r2t_info {
144 int data_count; /* DATA-Out payload progress */ 142 int data_count; /* DATA-Out payload progress */
145 struct scatterlist *sg; /* per-R2T SG list */ 143 struct scatterlist *sg; /* per-R2T SG list */
146 int solicit_datasn; 144 int solicit_datasn;
147 struct iscsi_data_task *dtask; /* which data task */ 145 struct iscsi_data_task dtask; /* which data task */
148}; 146};
149 147
150struct iscsi_tcp_cmd_task { 148struct iscsi_tcp_cmd_task {
@@ -167,14 +165,13 @@ struct iscsi_tcp_cmd_task {
167 struct iscsi_queue r2tpool; 165 struct iscsi_queue r2tpool;
168 struct kfifo *r2tqueue; 166 struct kfifo *r2tqueue;
169 struct iscsi_r2t_info **r2ts; 167 struct iscsi_r2t_info **r2ts;
170 struct list_head dataqueue; /* Data-Out dataqueue */
171 mempool_t *datapool;
172 uint32_t datadigest; /* for recover digest */ 168 uint32_t datadigest; /* for recover digest */
173 int digest_count; 169 int digest_count;
174 uint32_t immdigest; /* for imm data */ 170 uint32_t immdigest; /* for imm data */
175 struct iscsi_buf immbuf; /* for imm data digest */ 171 struct iscsi_buf immbuf; /* for imm data digest */
176 struct iscsi_data_task *dtask; /* data task in progress*/ 172 struct iscsi_data_task *dtask; /* data task in progress*/
177 int digest_offset; /* for partial buff digest */ 173 struct iscsi_data_task unsol_dtask; /* unsol data task */
174 int digest_offset; /* for partial buff digest */
178}; 175};
179 176
180#endif /* ISCSI_H */ 177#endif /* ISCSI_H */