aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-03-11 04:33:31 -0500
committerTejun Heo <tj@kernel.org>2011-03-12 05:41:10 -0500
commit56396e6823fe9b42fe9cf9403d6ed67756255f70 (patch)
treefcdab8e467b74217e76aa5047e2fa7d5b1ea71b4 /arch/x86
parentca764aaf025d2c83054191895b366fa81a9ccf48 (diff)
x86-64, NUMA: Don't call numa_set_distanc() for all possible node combinations during emulation
The distance transforming in numa_emulation() used to call numa_set_distance() for all MAX_NUMNODES * MAX_NUMNODES node combinations regardless of which are enabled. As numa_set_distance() ignores all out-of-bound distance settings, this doesn't cause any problem other than looping unnecessarily many times during boot. However, as MAX_NUMNODES * MAX_NUMNODES can be pretty high, update the code such that it iterates through only the enabled combinations. Yinghai Lu identified the issue and provided an initial patch to address the issue; however, the patch was incorrect in that it didn't build emulated distance table when there's no physical distance table and unnecessarily complex. http://thread.gmane.org/gmane.linux.kernel/1107986/focus=1107988 Signed-off-by: Tejun Heo <tj@kernel.org> Reported-by: Yinghai Lu <yinghai@kernel.org> Acked-by: Yinghai Lu <yinghai@kernel.org>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/mm/numa_emulation.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/arch/x86/mm/numa_emulation.c b/arch/x86/mm/numa_emulation.c
index 3696be0c2204..ad091e4cff17 100644
--- a/arch/x86/mm/numa_emulation.c
+++ b/arch/x86/mm/numa_emulation.c
@@ -301,7 +301,7 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt)
301 const u64 max_addr = max_pfn << PAGE_SHIFT; 301 const u64 max_addr = max_pfn << PAGE_SHIFT;
302 u8 *phys_dist = NULL; 302 u8 *phys_dist = NULL;
303 size_t phys_size = numa_dist_cnt * numa_dist_cnt * sizeof(phys_dist[0]); 303 size_t phys_size = numa_dist_cnt * numa_dist_cnt * sizeof(phys_dist[0]);
304 int dfl_phys_nid; 304 int max_emu_nid, dfl_phys_nid;
305 int i, j, ret; 305 int i, j, ret;
306 306
307 if (!emu_cmdline) 307 if (!emu_cmdline)
@@ -358,12 +358,17 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt)
358 node_distance(i, j); 358 node_distance(i, j);
359 } 359 }
360 360
361 /* determine the default phys nid to use for unmapped nodes */ 361 /*
362 * Determine the max emulated nid and the default phys nid to use
363 * for unmapped nodes.
364 */
365 max_emu_nid = 0;
362 dfl_phys_nid = NUMA_NO_NODE; 366 dfl_phys_nid = NUMA_NO_NODE;
363 for (i = 0; i < ARRAY_SIZE(emu_nid_to_phys); i++) { 367 for (i = 0; i < ARRAY_SIZE(emu_nid_to_phys); i++) {
364 if (emu_nid_to_phys[i] != NUMA_NO_NODE) { 368 if (emu_nid_to_phys[i] != NUMA_NO_NODE) {
365 dfl_phys_nid = emu_nid_to_phys[i]; 369 max_emu_nid = i;
366 break; 370 if (dfl_phys_nid == NUMA_NO_NODE)
371 dfl_phys_nid = emu_nid_to_phys[i];
367 } 372 }
368 } 373 }
369 if (dfl_phys_nid == NUMA_NO_NODE) { 374 if (dfl_phys_nid == NUMA_NO_NODE) {
@@ -393,14 +398,10 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt)
393 if (emu_nid_to_phys[i] == NUMA_NO_NODE) 398 if (emu_nid_to_phys[i] == NUMA_NO_NODE)
394 emu_nid_to_phys[i] = dfl_phys_nid; 399 emu_nid_to_phys[i] = dfl_phys_nid;
395 400
396 /* 401 /* transform distance table */
397 * Transform distance table. numa_set_distance() ignores all
398 * out-of-bound distances. Just call it for every possible node
399 * combination.
400 */
401 numa_reset_distance(); 402 numa_reset_distance();
402 for (i = 0; i < MAX_NUMNODES; i++) { 403 for (i = 0; i < max_emu_nid + 1; i++) {
403 for (j = 0; j < MAX_NUMNODES; j++) { 404 for (j = 0; j < max_emu_nid + 1; j++) {
404 int physi = emu_nid_to_phys[i]; 405 int physi = emu_nid_to_phys[i];
405 int physj = emu_nid_to_phys[j]; 406 int physj = emu_nid_to_phys[j];
406 int dist; 407 int dist;