|
@@ -48,10 +48,6 @@ static struct numa_meminfo numa_meminfo __initdata;
|
|
static int numa_distance_cnt;
|
|
static int numa_distance_cnt;
|
|
static u8 *numa_distance;
|
|
static u8 *numa_distance;
|
|
|
|
|
|
-#ifdef CONFIG_NUMA_EMU
|
|
|
|
-static bool numa_emu_dist;
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
* Given a shift value, try to populate memnodemap[]
|
|
* Given a shift value, try to populate memnodemap[]
|
|
* Returns :
|
|
* Returns :
|
|
@@ -443,10 +439,6 @@ void __init numa_set_distance(int from, int to, int distance)
|
|
|
|
|
|
int __node_distance(int from, int to)
|
|
int __node_distance(int from, int to)
|
|
{
|
|
{
|
|
-#if defined(CONFIG_ACPI_NUMA) && defined(CONFIG_NUMA_EMU)
|
|
|
|
- if (numa_emu_dist)
|
|
|
|
- return acpi_emu_node_distance(from, to);
|
|
|
|
-#endif
|
|
|
|
if (from >= numa_distance_cnt || to >= numa_distance_cnt)
|
|
if (from >= numa_distance_cnt || to >= numa_distance_cnt)
|
|
return from == to ? LOCAL_DISTANCE : REMOTE_DISTANCE;
|
|
return from == to ? LOCAL_DISTANCE : REMOTE_DISTANCE;
|
|
return numa_distance[from * numa_distance_cnt + to];
|
|
return numa_distance[from * numa_distance_cnt + to];
|
|
@@ -559,56 +551,6 @@ static int __init emu_find_memblk_by_nid(int nid, const struct numa_meminfo *mi)
|
|
return -ENOENT;
|
|
return -ENOENT;
|
|
}
|
|
}
|
|
|
|
|
|
-int __init find_node_by_addr(unsigned long addr)
|
|
|
|
-{
|
|
|
|
- const struct numa_meminfo *mi = &numa_meminfo;
|
|
|
|
- int i;
|
|
|
|
-
|
|
|
|
- for (i = 0; i < mi->nr_blks; i++) {
|
|
|
|
- /*
|
|
|
|
- * Find the real node that this emulated node appears on. For
|
|
|
|
- * the sake of simplicity, we only use a real node's starting
|
|
|
|
- * address to determine which emulated node it appears on.
|
|
|
|
- */
|
|
|
|
- if (addr >= mi->blk[i].start && addr < mi->blk[i].end)
|
|
|
|
- return mi->blk[i].nid;
|
|
|
|
- }
|
|
|
|
- return NUMA_NO_NODE;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void __init fake_physnodes(int acpi, int amd,
|
|
|
|
- const struct numa_meminfo *ei)
|
|
|
|
-{
|
|
|
|
- static struct bootnode nodes[MAX_NUMNODES] __initdata;
|
|
|
|
- int i, nr_nodes = 0;
|
|
|
|
-
|
|
|
|
- for (i = 0; i < ei->nr_blks; i++) {
|
|
|
|
- int nid = ei->blk[i].nid;
|
|
|
|
-
|
|
|
|
- if (nodes[nid].start == nodes[nid].end) {
|
|
|
|
- nodes[nid].start = ei->blk[i].start;
|
|
|
|
- nodes[nid].end = ei->blk[i].end;
|
|
|
|
- nr_nodes++;
|
|
|
|
- } else {
|
|
|
|
- nodes[nid].start = min(ei->blk[i].start, nodes[nid].start);
|
|
|
|
- nodes[nid].end = max(ei->blk[i].end, nodes[nid].end);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- BUG_ON(acpi && amd);
|
|
|
|
-#ifdef CONFIG_ACPI_NUMA
|
|
|
|
- if (acpi)
|
|
|
|
- acpi_fake_nodes(nodes, nr_nodes);
|
|
|
|
-#endif
|
|
|
|
-#ifdef CONFIG_AMD_NUMA
|
|
|
|
- if (amd)
|
|
|
|
- amd_fake_nodes(nodes, nr_nodes);
|
|
|
|
-#endif
|
|
|
|
- if (!acpi && !amd)
|
|
|
|
- for (i = 0; i < nr_cpu_ids; i++)
|
|
|
|
- numa_set_node(i, 0);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
* Sets up nid to range from @start to @end. The return value is -errno if
|
|
* Sets up nid to range from @start to @end. The return value is -errno if
|
|
* something went wrong, 0 otherwise.
|
|
* something went wrong, 0 otherwise.
|
|
@@ -853,11 +795,13 @@ static int __init split_nodes_size_interleave(struct numa_meminfo *ei,
|
|
* Sets up the system RAM area from start_pfn to last_pfn according to the
|
|
* Sets up the system RAM area from start_pfn to last_pfn according to the
|
|
* numa=fake command-line option.
|
|
* numa=fake command-line option.
|
|
*/
|
|
*/
|
|
-static bool __init numa_emulation(int acpi, int amd)
|
|
|
|
|
|
+static bool __init numa_emulation(void)
|
|
{
|
|
{
|
|
static struct numa_meminfo ei __initdata;
|
|
static struct numa_meminfo ei __initdata;
|
|
static struct numa_meminfo pi __initdata;
|
|
static struct numa_meminfo pi __initdata;
|
|
const u64 max_addr = max_pfn << PAGE_SHIFT;
|
|
const u64 max_addr = max_pfn << PAGE_SHIFT;
|
|
|
|
+ int phys_dist_cnt = numa_distance_cnt;
|
|
|
|
+ u8 *phys_dist = NULL;
|
|
int i, j, ret;
|
|
int i, j, ret;
|
|
|
|
|
|
memset(&ei, 0, sizeof(ei));
|
|
memset(&ei, 0, sizeof(ei));
|
|
@@ -891,6 +835,25 @@ static bool __init numa_emulation(int acpi, int amd)
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Copy the original distance table. It's temporary so no need to
|
|
|
|
+ * reserve it.
|
|
|
|
+ */
|
|
|
|
+ if (phys_dist_cnt) {
|
|
|
|
+ size_t size = phys_dist_cnt * sizeof(numa_distance[0]);
|
|
|
|
+ u64 phys;
|
|
|
|
+
|
|
|
|
+ phys = memblock_find_in_range(0,
|
|
|
|
+ (u64)max_pfn_mapped << PAGE_SHIFT,
|
|
|
|
+ size, PAGE_SIZE);
|
|
|
|
+ if (phys == MEMBLOCK_ERROR) {
|
|
|
|
+ pr_warning("NUMA: Warning: can't allocate copy of distance table, disabling emulation\n");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ phys_dist = __va(phys);
|
|
|
|
+ memcpy(phys_dist, numa_distance, size);
|
|
|
|
+ }
|
|
|
|
+
|
|
/* commit */
|
|
/* commit */
|
|
numa_meminfo = ei;
|
|
numa_meminfo = ei;
|
|
|
|
|
|
@@ -913,8 +876,23 @@ static bool __init numa_emulation(int acpi, int amd)
|
|
if (emu_nid_to_phys[i] == NUMA_NO_NODE)
|
|
if (emu_nid_to_phys[i] == NUMA_NO_NODE)
|
|
emu_nid_to_phys[i] = 0;
|
|
emu_nid_to_phys[i] = 0;
|
|
|
|
|
|
- fake_physnodes(acpi, amd, &ei);
|
|
|
|
- numa_emu_dist = true;
|
|
|
|
|
|
+ /* transform distance table */
|
|
|
|
+ numa_reset_distance();
|
|
|
|
+ for (i = 0; i < MAX_NUMNODES; i++) {
|
|
|
|
+ for (j = 0; j < MAX_NUMNODES; j++) {
|
|
|
|
+ int physi = emu_nid_to_phys[i];
|
|
|
|
+ int physj = emu_nid_to_phys[j];
|
|
|
|
+ int dist;
|
|
|
|
+
|
|
|
|
+ if (physi >= phys_dist_cnt || physj >= phys_dist_cnt)
|
|
|
|
+ dist = physi == physj ?
|
|
|
|
+ LOCAL_DISTANCE : REMOTE_DISTANCE;
|
|
|
|
+ else
|
|
|
|
+ dist = phys_dist[physi * phys_dist_cnt + physj];
|
|
|
|
+
|
|
|
|
+ numa_set_distance(i, j, dist);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
#endif /* CONFIG_NUMA_EMU */
|
|
#endif /* CONFIG_NUMA_EMU */
|
|
@@ -970,7 +948,7 @@ void __init initmem_init(void)
|
|
* If requested, try emulation. If emulation is not used,
|
|
* If requested, try emulation. If emulation is not used,
|
|
* build identity emu_nid_to_phys[] for numa_add_cpu()
|
|
* build identity emu_nid_to_phys[] for numa_add_cpu()
|
|
*/
|
|
*/
|
|
- if (!emu_cmdline || !numa_emulation(i == 0, i == 1))
|
|
|
|
|
|
+ if (!emu_cmdline || !numa_emulation())
|
|
for (j = 0; j < ARRAY_SIZE(emu_nid_to_phys); j++)
|
|
for (j = 0; j < ARRAY_SIZE(emu_nid_to_phys); j++)
|
|
emu_nid_to_phys[j] = j;
|
|
emu_nid_to_phys[j] = j;
|
|
#endif
|
|
#endif
|