diff options
author | Jörn Engel <joern@logfs.org> | 2012-03-15 15:05:12 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-03-15 22:15:38 -0400 |
commit | 4a5a75f32dcbcd0b2685f74fd4ede26edf8765a9 (patch) | |
tree | 9c05e0df5d2cfe06ed490ce763347f65aaf64c6a /drivers/target | |
parent | b168fe8cfe530daabbdf632af4554600006a81a9 (diff) |
target: Use array_zalloc for tpg_lun_list
Turns an order-10 allocation into slab-sized ones, thereby preventing
allocation failures with memory fragmentation.
This likely saves memory as well, as the slab allocator can pack objects
more tightly than the buddy allocator.
Signed-off-by: Joern Engel <joern@logfs.org>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_device.c | 4 | ||||
-rw-r--r-- | drivers/target/target_core_tpg.c | 44 |
2 files changed, 38 insertions, 10 deletions
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 5cfaa4b6da4..fd7f17c303a 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -1429,7 +1429,7 @@ struct se_lun *core_get_lun_from_tpg(struct se_portal_group *tpg, u32 unpacked_l | |||
1429 | spin_unlock(&tpg->tpg_lun_lock); | 1429 | spin_unlock(&tpg->tpg_lun_lock); |
1430 | return NULL; | 1430 | return NULL; |
1431 | } | 1431 | } |
1432 | lun = &tpg->tpg_lun_list[unpacked_lun]; | 1432 | lun = tpg->tpg_lun_list[unpacked_lun]; |
1433 | 1433 | ||
1434 | if (lun->lun_status != TRANSPORT_LUN_STATUS_FREE) { | 1434 | if (lun->lun_status != TRANSPORT_LUN_STATUS_FREE) { |
1435 | pr_err("%s Logical Unit Number: %u is not free on" | 1435 | pr_err("%s Logical Unit Number: %u is not free on" |
@@ -1462,7 +1462,7 @@ static struct se_lun *core_dev_get_lun(struct se_portal_group *tpg, u32 unpacked | |||
1462 | spin_unlock(&tpg->tpg_lun_lock); | 1462 | spin_unlock(&tpg->tpg_lun_lock); |
1463 | return NULL; | 1463 | return NULL; |
1464 | } | 1464 | } |
1465 | lun = &tpg->tpg_lun_list[unpacked_lun]; | 1465 | lun = tpg->tpg_lun_list[unpacked_lun]; |
1466 | 1466 | ||
1467 | if (lun->lun_status != TRANSPORT_LUN_STATUS_ACTIVE) { | 1467 | if (lun->lun_status != TRANSPORT_LUN_STATUS_ACTIVE) { |
1468 | pr_err("%s Logical Unit Number: %u is not active on" | 1468 | pr_err("%s Logical Unit Number: %u is not active on" |
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index f3ea385737d..146fe47f11c 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c | |||
@@ -163,7 +163,7 @@ void core_tpg_add_node_to_devs( | |||
163 | 163 | ||
164 | spin_lock(&tpg->tpg_lun_lock); | 164 | spin_lock(&tpg->tpg_lun_lock); |
165 | for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { | 165 | for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { |
166 | lun = &tpg->tpg_lun_list[i]; | 166 | lun = tpg->tpg_lun_list[i]; |
167 | if (lun->lun_status != TRANSPORT_LUN_STATUS_ACTIVE) | 167 | if (lun->lun_status != TRANSPORT_LUN_STATUS_ACTIVE) |
168 | continue; | 168 | continue; |
169 | 169 | ||
@@ -222,6 +222,34 @@ static int core_set_queue_depth_for_node( | |||
222 | return 0; | 222 | return 0; |
223 | } | 223 | } |
224 | 224 | ||
225 | void array_free(void *array, int n) | ||
226 | { | ||
227 | void **a = array; | ||
228 | int i; | ||
229 | |||
230 | for (i = 0; i < n; i++) | ||
231 | kfree(a[i]); | ||
232 | kfree(a); | ||
233 | } | ||
234 | |||
235 | static void *array_zalloc(int n, size_t size, gfp_t flags) | ||
236 | { | ||
237 | void **a; | ||
238 | int i; | ||
239 | |||
240 | a = kzalloc(n * sizeof(void*), flags); | ||
241 | if (!a) | ||
242 | return NULL; | ||
243 | for (i = 0; i < n; i++) { | ||
244 | a[i] = kzalloc(size, flags); | ||
245 | if (!a[i]) { | ||
246 | array_free(a, n); | ||
247 | return NULL; | ||
248 | } | ||
249 | } | ||
250 | return a; | ||
251 | } | ||
252 | |||
225 | /* core_create_device_list_for_node(): | 253 | /* core_create_device_list_for_node(): |
226 | * | 254 | * |
227 | * | 255 | * |
@@ -336,7 +364,7 @@ void core_tpg_clear_object_luns(struct se_portal_group *tpg) | |||
336 | 364 | ||
337 | spin_lock(&tpg->tpg_lun_lock); | 365 | spin_lock(&tpg->tpg_lun_lock); |
338 | for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { | 366 | for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { |
339 | lun = &tpg->tpg_lun_list[i]; | 367 | lun = tpg->tpg_lun_list[i]; |
340 | 368 | ||
341 | if ((lun->lun_status != TRANSPORT_LUN_STATUS_ACTIVE) || | 369 | if ((lun->lun_status != TRANSPORT_LUN_STATUS_ACTIVE) || |
342 | (lun->lun_se_dev == NULL)) | 370 | (lun->lun_se_dev == NULL)) |
@@ -661,8 +689,8 @@ int core_tpg_register( | |||
661 | struct se_lun *lun; | 689 | struct se_lun *lun; |
662 | u32 i; | 690 | u32 i; |
663 | 691 | ||
664 | se_tpg->tpg_lun_list = kzalloc((sizeof(struct se_lun) * | 692 | se_tpg->tpg_lun_list = array_zalloc(TRANSPORT_MAX_LUNS_PER_TPG, |
665 | TRANSPORT_MAX_LUNS_PER_TPG), GFP_KERNEL); | 693 | sizeof(struct se_lun), GFP_KERNEL); |
666 | if (!se_tpg->tpg_lun_list) { | 694 | if (!se_tpg->tpg_lun_list) { |
667 | pr_err("Unable to allocate struct se_portal_group->" | 695 | pr_err("Unable to allocate struct se_portal_group->" |
668 | "tpg_lun_list\n"); | 696 | "tpg_lun_list\n"); |
@@ -670,7 +698,7 @@ int core_tpg_register( | |||
670 | } | 698 | } |
671 | 699 | ||
672 | for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { | 700 | for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { |
673 | lun = &se_tpg->tpg_lun_list[i]; | 701 | lun = se_tpg->tpg_lun_list[i]; |
674 | lun->unpacked_lun = i; | 702 | lun->unpacked_lun = i; |
675 | lun->lun_status = TRANSPORT_LUN_STATUS_FREE; | 703 | lun->lun_status = TRANSPORT_LUN_STATUS_FREE; |
676 | atomic_set(&lun->lun_acl_count, 0); | 704 | atomic_set(&lun->lun_acl_count, 0); |
@@ -756,7 +784,7 @@ int core_tpg_deregister(struct se_portal_group *se_tpg) | |||
756 | core_tpg_release_virtual_lun0(se_tpg); | 784 | core_tpg_release_virtual_lun0(se_tpg); |
757 | 785 | ||
758 | se_tpg->se_tpg_fabric_ptr = NULL; | 786 | se_tpg->se_tpg_fabric_ptr = NULL; |
759 | kfree(se_tpg->tpg_lun_list); | 787 | array_free(se_tpg->tpg_lun_list, TRANSPORT_MAX_LUNS_PER_TPG); |
760 | return 0; | 788 | return 0; |
761 | } | 789 | } |
762 | EXPORT_SYMBOL(core_tpg_deregister); | 790 | EXPORT_SYMBOL(core_tpg_deregister); |
@@ -777,7 +805,7 @@ struct se_lun *core_tpg_pre_addlun( | |||
777 | } | 805 | } |
778 | 806 | ||
779 | spin_lock(&tpg->tpg_lun_lock); | 807 | spin_lock(&tpg->tpg_lun_lock); |
780 | lun = &tpg->tpg_lun_list[unpacked_lun]; | 808 | lun = tpg->tpg_lun_list[unpacked_lun]; |
781 | if (lun->lun_status == TRANSPORT_LUN_STATUS_ACTIVE) { | 809 | if (lun->lun_status == TRANSPORT_LUN_STATUS_ACTIVE) { |
782 | pr_err("TPG Logical Unit Number: %u is already active" | 810 | pr_err("TPG Logical Unit Number: %u is already active" |
783 | " on %s Target Portal Group: %u, ignoring request.\n", | 811 | " on %s Target Portal Group: %u, ignoring request.\n", |
@@ -835,7 +863,7 @@ struct se_lun *core_tpg_pre_dellun( | |||
835 | } | 863 | } |
836 | 864 | ||
837 | spin_lock(&tpg->tpg_lun_lock); | 865 | spin_lock(&tpg->tpg_lun_lock); |
838 | lun = &tpg->tpg_lun_list[unpacked_lun]; | 866 | lun = tpg->tpg_lun_list[unpacked_lun]; |
839 | if (lun->lun_status != TRANSPORT_LUN_STATUS_ACTIVE) { | 867 | if (lun->lun_status != TRANSPORT_LUN_STATUS_ACTIVE) { |
840 | pr_err("%s Logical Unit Number: %u is not active on" | 868 | pr_err("%s Logical Unit Number: %u is not active on" |
841 | " Target Portal Group: %u, ignoring request.\n", | 869 | " Target Portal Group: %u, ignoring request.\n", |