diff options
| author | Tejun Heo <tj@kernel.org> | 2011-03-04 10:32:02 -0500 |
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2011-03-04 10:32:37 -0500 |
| commit | 078a198906c796981f93ff100c210506e91aade5 (patch) | |
| tree | 3c0c4c2cb7837aaf54a5e6592bbd20cfcfcd4c78 | |
| parent | c09cedf4f75f1e47ea17f55e18e9cfb81bec8575 (diff) | |
x86-64, NUMA: Don't assume phys node 0 is always online in numa_emulation()
Undetermined entries in emu_nid_to_phys[] are filled with zero
assuming that physical node 0 is always online; however, this might
not be true depending on hardware configuration. Find a physical node
which is actually online and use it instead.
Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: David Rientjes <rientjes@google.com>
LKML-Reference: <alpine.DEB.2.00.1103020628210.31626@chino.kir.corp.google.com>
| -rw-r--r-- | arch/x86/mm/numa_emulation.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/arch/x86/mm/numa_emulation.c b/arch/x86/mm/numa_emulation.c index 75b31dc0f32..3696be0c220 100644 --- a/arch/x86/mm/numa_emulation.c +++ b/arch/x86/mm/numa_emulation.c | |||
| @@ -301,6 +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 i, j, ret; | 305 | int i, j, ret; |
| 305 | 306 | ||
| 306 | if (!emu_cmdline) | 307 | if (!emu_cmdline) |
| @@ -357,6 +358,19 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt) | |||
| 357 | node_distance(i, j); | 358 | node_distance(i, j); |
| 358 | } | 359 | } |
| 359 | 360 | ||
| 361 | /* determine the default phys nid to use for unmapped nodes */ | ||
| 362 | dfl_phys_nid = NUMA_NO_NODE; | ||
| 363 | for (i = 0; i < ARRAY_SIZE(emu_nid_to_phys); i++) { | ||
| 364 | if (emu_nid_to_phys[i] != NUMA_NO_NODE) { | ||
| 365 | dfl_phys_nid = emu_nid_to_phys[i]; | ||
| 366 | break; | ||
| 367 | } | ||
| 368 | } | ||
| 369 | if (dfl_phys_nid == NUMA_NO_NODE) { | ||
| 370 | pr_warning("NUMA: Warning: can't determine default physical node, disabling emulation\n"); | ||
| 371 | goto no_emu; | ||
| 372 | } | ||
| 373 | |||
| 360 | /* commit */ | 374 | /* commit */ |
| 361 | *numa_meminfo = ei; | 375 | *numa_meminfo = ei; |
| 362 | 376 | ||
| @@ -377,7 +391,7 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt) | |||
| 377 | /* make sure all emulated nodes are mapped to a physical node */ | 391 | /* make sure all emulated nodes are mapped to a physical node */ |
| 378 | for (i = 0; i < ARRAY_SIZE(emu_nid_to_phys); i++) | 392 | for (i = 0; i < ARRAY_SIZE(emu_nid_to_phys); i++) |
| 379 | if (emu_nid_to_phys[i] == NUMA_NO_NODE) | 393 | if (emu_nid_to_phys[i] == NUMA_NO_NODE) |
| 380 | emu_nid_to_phys[i] = 0; | 394 | emu_nid_to_phys[i] = dfl_phys_nid; |
| 381 | 395 | ||
| 382 | /* | 396 | /* |
| 383 | * Transform distance table. numa_set_distance() ignores all | 397 | * Transform distance table. numa_set_distance() ignores all |
