aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/iscsi_tcp.c12
-rw-r--r--drivers/scsi/iscsi_tcp.h3
-rw-r--r--drivers/scsi/libiscsi.c75
-rw-r--r--include/scsi/libiscsi.h10
4 files changed, 50 insertions, 50 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 491845f18710..f79a457099e6 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -1998,8 +1998,7 @@ iscsi_r2tpool_alloc(struct iscsi_session *session)
1998 */ 1998 */
1999 1999
2000 /* R2T pool */ 2000 /* R2T pool */
2001 if (iscsi_pool_init(&tcp_ctask->r2tpool, session->max_r2t * 4, 2001 if (iscsi_pool_init(&tcp_ctask->r2tpool, session->max_r2t * 4, NULL,
2002 (void***)&tcp_ctask->r2ts,
2003 sizeof(struct iscsi_r2t_info))) { 2002 sizeof(struct iscsi_r2t_info))) {
2004 goto r2t_alloc_fail; 2003 goto r2t_alloc_fail;
2005 } 2004 }
@@ -2008,8 +2007,7 @@ iscsi_r2tpool_alloc(struct iscsi_session *session)
2008 tcp_ctask->r2tqueue = kfifo_alloc( 2007 tcp_ctask->r2tqueue = kfifo_alloc(
2009 session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL); 2008 session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL);
2010 if (tcp_ctask->r2tqueue == ERR_PTR(-ENOMEM)) { 2009 if (tcp_ctask->r2tqueue == ERR_PTR(-ENOMEM)) {
2011 iscsi_pool_free(&tcp_ctask->r2tpool, 2010 iscsi_pool_free(&tcp_ctask->r2tpool);
2012 (void**)tcp_ctask->r2ts);
2013 goto r2t_alloc_fail; 2011 goto r2t_alloc_fail;
2014 } 2012 }
2015 } 2013 }
@@ -2022,8 +2020,7 @@ r2t_alloc_fail:
2022 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 2020 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
2023 2021
2024 kfifo_free(tcp_ctask->r2tqueue); 2022 kfifo_free(tcp_ctask->r2tqueue);
2025 iscsi_pool_free(&tcp_ctask->r2tpool, 2023 iscsi_pool_free(&tcp_ctask->r2tpool);
2026 (void**)tcp_ctask->r2ts);
2027 } 2024 }
2028 return -ENOMEM; 2025 return -ENOMEM;
2029} 2026}
@@ -2038,8 +2035,7 @@ iscsi_r2tpool_free(struct iscsi_session *session)
2038 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 2035 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
2039 2036
2040 kfifo_free(tcp_ctask->r2tqueue); 2037 kfifo_free(tcp_ctask->r2tqueue);
2041 iscsi_pool_free(&tcp_ctask->r2tpool, 2038 iscsi_pool_free(&tcp_ctask->r2tpool);
2042 (void**)tcp_ctask->r2ts);
2043 } 2039 }
2044} 2040}
2045 2041
diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h
index eb3784f949fd..d49d87611e82 100644
--- a/drivers/scsi/iscsi_tcp.h
+++ b/drivers/scsi/iscsi_tcp.h
@@ -175,9 +175,8 @@ struct iscsi_tcp_cmd_task {
175 uint32_t exp_datasn; /* expected target's R2TSN/DataSN */ 175 uint32_t exp_datasn; /* expected target's R2TSN/DataSN */
176 int data_offset; 176 int data_offset;
177 struct iscsi_r2t_info *r2t; /* in progress R2T */ 177 struct iscsi_r2t_info *r2t; /* in progress R2T */
178 struct iscsi_queue r2tpool; 178 struct iscsi_pool r2tpool;
179 struct kfifo *r2tqueue; 179 struct kfifo *r2tqueue;
180 struct iscsi_r2t_info **r2ts;
181 int digest_count; 180 int digest_count;
182 uint32_t immdigest; /* for imm data */ 181 uint32_t immdigest; /* for imm data */
183 struct iscsi_buf immbuf; /* for imm data digest */ 182 struct iscsi_buf immbuf; /* for imm data digest */
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 59365864c989..d43f909a022c 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1413,59 +1413,64 @@ done:
1413} 1413}
1414EXPORT_SYMBOL_GPL(iscsi_eh_device_reset); 1414EXPORT_SYMBOL_GPL(iscsi_eh_device_reset);
1415 1415
1416/*
1417 * Pre-allocate a pool of @max items of @item_size. By default, the pool
1418 * should be accessed via kfifo_{get,put} on q->queue.
1419 * Optionally, the caller can obtain the array of object pointers
1420 * by passing in a non-NULL @items pointer
1421 */
1416int 1422int
1417iscsi_pool_init(struct iscsi_queue *q, int max, void ***items, int item_size) 1423iscsi_pool_init(struct iscsi_pool *q, int max, void ***items, int item_size)
1418{ 1424{
1419 int i; 1425 int i, num_arrays = 1;
1420 1426
1421 *items = kmalloc(max * sizeof(void*), GFP_KERNEL); 1427 memset(q, 0, sizeof(*q));
1422 if (*items == NULL)
1423 return -ENOMEM;
1424 1428
1425 q->max = max; 1429 q->max = max;
1426 q->pool = kmalloc(max * sizeof(void*), GFP_KERNEL); 1430
1427 if (q->pool == NULL) { 1431 /* If the user passed an items pointer, he wants a copy of
1428 kfree(*items); 1432 * the array. */
1429 return -ENOMEM; 1433 if (items)
1430 } 1434 num_arrays++;
1435 q->pool = kzalloc(num_arrays * max * sizeof(void*), GFP_KERNEL);
1436 if (q->pool == NULL)
1437 goto enomem;
1431 1438
1432 q->queue = kfifo_init((void*)q->pool, max * sizeof(void*), 1439 q->queue = kfifo_init((void*)q->pool, max * sizeof(void*),
1433 GFP_KERNEL, NULL); 1440 GFP_KERNEL, NULL);
1434 if (q->queue == ERR_PTR(-ENOMEM)) { 1441 if (q->queue == ERR_PTR(-ENOMEM))
1435 kfree(q->pool); 1442 goto enomem;
1436 kfree(*items);
1437 return -ENOMEM;
1438 }
1439 1443
1440 for (i = 0; i < max; i++) { 1444 for (i = 0; i < max; i++) {
1441 q->pool[i] = kmalloc(item_size, GFP_KERNEL); 1445 q->pool[i] = kzalloc(item_size, GFP_KERNEL);
1442 if (q->pool[i] == NULL) { 1446 if (q->pool[i] == NULL) {
1443 int j; 1447 q->max = i;
1444 1448 goto enomem;
1445 for (j = 0; j < i; j++)
1446 kfree(q->pool[j]);
1447
1448 kfifo_free(q->queue);
1449 kfree(q->pool);
1450 kfree(*items);
1451 return -ENOMEM;
1452 } 1449 }
1453 memset(q->pool[i], 0, item_size);
1454 (*items)[i] = q->pool[i];
1455 __kfifo_put(q->queue, (void*)&q->pool[i], sizeof(void*)); 1450 __kfifo_put(q->queue, (void*)&q->pool[i], sizeof(void*));
1456 } 1451 }
1452
1453 if (items) {
1454 *items = q->pool + max;
1455 memcpy(*items, q->pool, max * sizeof(void *));
1456 }
1457
1457 return 0; 1458 return 0;
1459
1460enomem:
1461 iscsi_pool_free(q);
1462 return -ENOMEM;
1458} 1463}
1459EXPORT_SYMBOL_GPL(iscsi_pool_init); 1464EXPORT_SYMBOL_GPL(iscsi_pool_init);
1460 1465
1461void iscsi_pool_free(struct iscsi_queue *q, void **items) 1466void iscsi_pool_free(struct iscsi_pool *q)
1462{ 1467{
1463 int i; 1468 int i;
1464 1469
1465 for (i = 0; i < q->max; i++) 1470 for (i = 0; i < q->max; i++)
1466 kfree(items[i]); 1471 kfree(q->pool[i]);
1467 kfree(q->pool); 1472 if (q->pool)
1468 kfree(items); 1473 kfree(q->pool);
1469} 1474}
1470EXPORT_SYMBOL_GPL(iscsi_pool_free); 1475EXPORT_SYMBOL_GPL(iscsi_pool_free);
1471 1476
@@ -1610,9 +1615,9 @@ module_put:
1610cls_session_fail: 1615cls_session_fail:
1611 scsi_remove_host(shost); 1616 scsi_remove_host(shost);
1612add_host_fail: 1617add_host_fail:
1613 iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); 1618 iscsi_pool_free(&session->mgmtpool);
1614mgmtpool_alloc_fail: 1619mgmtpool_alloc_fail:
1615 iscsi_pool_free(&session->cmdpool, (void**)session->cmds); 1620 iscsi_pool_free(&session->cmdpool);
1616cmdpool_alloc_fail: 1621cmdpool_alloc_fail:
1617 scsi_host_put(shost); 1622 scsi_host_put(shost);
1618 return NULL; 1623 return NULL;
@@ -1635,8 +1640,8 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
1635 iscsi_unblock_session(cls_session); 1640 iscsi_unblock_session(cls_session);
1636 scsi_remove_host(shost); 1641 scsi_remove_host(shost);
1637 1642
1638 iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); 1643 iscsi_pool_free(&session->mgmtpool);
1639 iscsi_pool_free(&session->cmdpool, (void**)session->cmds); 1644 iscsi_pool_free(&session->cmdpool);
1640 1645
1641 kfree(session->password); 1646 kfree(session->password);
1642 kfree(session->password_in); 1647 kfree(session->password_in);
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index a9a9e869188d..4b3e3c15121a 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -215,7 +215,7 @@ struct iscsi_conn {
215 uint32_t eh_abort_cnt; 215 uint32_t eh_abort_cnt;
216}; 216};
217 217
218struct iscsi_queue { 218struct iscsi_pool {
219 struct kfifo *queue; /* FIFO Queue */ 219 struct kfifo *queue; /* FIFO Queue */
220 void **pool; /* Pool of elements */ 220 void **pool; /* Pool of elements */
221 int max; /* Max number of elements */ 221 int max; /* Max number of elements */
@@ -274,10 +274,10 @@ struct iscsi_session {
274 274
275 int cmds_max; /* size of cmds array */ 275 int cmds_max; /* size of cmds array */
276 struct iscsi_cmd_task **cmds; /* Original Cmds arr */ 276 struct iscsi_cmd_task **cmds; /* Original Cmds arr */
277 struct iscsi_queue cmdpool; /* PDU's pool */ 277 struct iscsi_pool cmdpool; /* PDU's pool */
278 int mgmtpool_max; /* size of mgmt array */ 278 int mgmtpool_max; /* size of mgmt array */
279 struct iscsi_mgmt_task **mgmt_cmds; /* Original mgmt arr */ 279 struct iscsi_mgmt_task **mgmt_cmds; /* Original mgmt arr */
280 struct iscsi_queue mgmtpool; /* Mgmt PDU's pool */ 280 struct iscsi_pool mgmtpool; /* Mgmt PDU's pool */
281}; 281};
282 282
283/* 283/*
@@ -350,8 +350,8 @@ extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask);
350/* 350/*
351 * generic helpers 351 * generic helpers
352 */ 352 */
353extern void iscsi_pool_free(struct iscsi_queue *, void **); 353extern void iscsi_pool_free(struct iscsi_pool *);
354extern int iscsi_pool_init(struct iscsi_queue *, int, void ***, int); 354extern int iscsi_pool_init(struct iscsi_pool *, int, void ***, int);
355 355
356/* 356/*
357 * inline functions to deal with padding. 357 * inline functions to deal with padding.