diff options
author | Yinghai Lu <yinghai@kernel.org> | 2011-02-22 05:18:49 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2011-02-22 05:18:49 -0500 |
commit | 2bf50555b0920be7e29d3823f6bbd20ee5920489 (patch) | |
tree | 43d1a7b547af3e87c18543caff7b398be66413d2 /arch/x86 | |
parent | 90e6b677b47ff8c5ba1637941af6b9f92723b003 (diff) |
x86-64, NUMA: Seperate out numa_alloc_distance() from numa_set_distance()
Alloc code is much bigger the distance setting. Separate it out into
numa_alloc_distance() for readability.
-v2: Let alloc_numa_distance to return -ENOMEM on failing path,
requested by tj.
-tj: Description update. Minor tweaks including function name,
location and return value check.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: David Rientjes <rientjes@google.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/mm/numa_64.c | 75 |
1 files changed, 40 insertions, 35 deletions
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c index 848381bdd358..cccc01d8415c 100644 --- a/arch/x86/mm/numa_64.c +++ b/arch/x86/mm/numa_64.c | |||
@@ -401,6 +401,44 @@ void __init numa_reset_distance(void) | |||
401 | numa_distance = NULL; | 401 | numa_distance = NULL; |
402 | } | 402 | } |
403 | 403 | ||
404 | static int __init numa_alloc_distance(void) | ||
405 | { | ||
406 | nodemask_t nodes_parsed; | ||
407 | size_t size; | ||
408 | int i, j, cnt = 0; | ||
409 | u64 phys; | ||
410 | |||
411 | /* size the new table and allocate it */ | ||
412 | nodes_parsed = numa_nodes_parsed; | ||
413 | numa_nodemask_from_meminfo(&nodes_parsed, &numa_meminfo); | ||
414 | |||
415 | for_each_node_mask(i, nodes_parsed) | ||
416 | cnt = i; | ||
417 | size = ++cnt * sizeof(numa_distance[0]); | ||
418 | |||
419 | phys = memblock_find_in_range(0, (u64)max_pfn_mapped << PAGE_SHIFT, | ||
420 | size, PAGE_SIZE); | ||
421 | if (phys == MEMBLOCK_ERROR) { | ||
422 | pr_warning("NUMA: Warning: can't allocate distance table!\n"); | ||
423 | /* don't retry until explicitly reset */ | ||
424 | numa_distance = (void *)1LU; | ||
425 | return -ENOMEM; | ||
426 | } | ||
427 | memblock_x86_reserve_range(phys, phys + size, "NUMA DIST"); | ||
428 | |||
429 | numa_distance = __va(phys); | ||
430 | numa_distance_cnt = cnt; | ||
431 | |||
432 | /* fill with the default distances */ | ||
433 | for (i = 0; i < cnt; i++) | ||
434 | for (j = 0; j < cnt; j++) | ||
435 | numa_distance[i * cnt + j] = i == j ? | ||
436 | LOCAL_DISTANCE : REMOTE_DISTANCE; | ||
437 | printk(KERN_DEBUG "NUMA: Initialized distance table, cnt=%d\n", cnt); | ||
438 | |||
439 | return 0; | ||
440 | } | ||
441 | |||
404 | /** | 442 | /** |
405 | * numa_set_distance - Set NUMA distance from one NUMA to another | 443 | * numa_set_distance - Set NUMA distance from one NUMA to another |
406 | * @from: the 'from' node to set distance | 444 | * @from: the 'from' node to set distance |
@@ -413,41 +451,8 @@ void __init numa_reset_distance(void) | |||
413 | */ | 451 | */ |
414 | void __init numa_set_distance(int from, int to, int distance) | 452 | void __init numa_set_distance(int from, int to, int distance) |
415 | { | 453 | { |
416 | if (!numa_distance) { | 454 | if (!numa_distance && numa_alloc_distance() < 0) |
417 | nodemask_t nodes_parsed; | 455 | return; |
418 | size_t size; | ||
419 | int i, j, cnt = 0; | ||
420 | u64 phys; | ||
421 | |||
422 | /* size the new table and allocate it */ | ||
423 | nodes_parsed = numa_nodes_parsed; | ||
424 | numa_nodemask_from_meminfo(&nodes_parsed, &numa_meminfo); | ||
425 | |||
426 | for_each_node_mask(i, nodes_parsed) | ||
427 | cnt = i; | ||
428 | size = ++cnt * sizeof(numa_distance[0]); | ||
429 | |||
430 | phys = memblock_find_in_range(0, | ||
431 | (u64)max_pfn_mapped << PAGE_SHIFT, | ||
432 | size, PAGE_SIZE); | ||
433 | if (phys == MEMBLOCK_ERROR) { | ||
434 | pr_warning("NUMA: Warning: can't allocate distance table!\n"); | ||
435 | /* don't retry until explicitly reset */ | ||
436 | numa_distance = (void *)1LU; | ||
437 | return; | ||
438 | } | ||
439 | memblock_x86_reserve_range(phys, phys + size, "NUMA DIST"); | ||
440 | |||
441 | numa_distance = __va(phys); | ||
442 | numa_distance_cnt = cnt; | ||
443 | |||
444 | /* fill with the default distances */ | ||
445 | for (i = 0; i < cnt; i++) | ||
446 | for (j = 0; j < cnt; j++) | ||
447 | numa_distance[i * cnt + j] = i == j ? | ||
448 | LOCAL_DISTANCE : REMOTE_DISTANCE; | ||
449 | printk(KERN_DEBUG "NUMA: Initialized distance table, cnt=%d\n", cnt); | ||
450 | } | ||
451 | 456 | ||
452 | if (from >= numa_distance_cnt || to >= numa_distance_cnt) { | 457 | if (from >= numa_distance_cnt || to >= numa_distance_cnt) { |
453 | printk_once(KERN_DEBUG "NUMA: Debug: distance out of bound, from=%d to=%d distance=%d\n", | 458 | printk_once(KERN_DEBUG "NUMA: Debug: distance out of bound, from=%d to=%d distance=%d\n", |