diff options
-rw-r--r-- | drivers/scsi/iscsi_tcp.c | 87 | ||||
-rw-r--r-- | drivers/scsi/iscsi_tcp.h | 11 |
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"); | |||
67 | static unsigned int iscsi_max_lun = 512; | 67 | static unsigned int iscsi_max_lun = 512; |
68 | module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO); | 68 | module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO); |
69 | 69 | ||
70 | /* global data */ | ||
71 | static kmem_cache_t *taskcache; | ||
72 | |||
73 | static inline void | 70 | static inline void |
74 | iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size) | 71 | iscsi_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 | ||
1277 | static void | 1248 | static 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 | ||
2497 | static void iscsi_tcp_session_destroy(struct iscsi_cls_session *cls_session) | 2444 | static 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 | |||
2608 | iscsi_tcp_exit(void) | 2534 | iscsi_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 | ||
2614 | module_init(iscsi_tcp_init); | 2539 | module_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 { | |||
118 | struct iscsi_data_task { | 118 | struct 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 | ||
127 | struct iscsi_tcp_mgmt_task { | 125 | struct 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 | ||
150 | struct iscsi_tcp_cmd_task { | 148 | struct 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 */ |