mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
x86-64, NUMA: Prepare numa_emulation() for moving NUMA emulation into a separate file
Update numa_emulation() such that, it - takes @numa_meminfo and @numa_dist_cnt instead of directly referencing the global variables. - copies the distance table by iterating each distance with node_distance() instead of memcpy'ing the distance table. - tests emu_cmdline to determine whether emulation is requested and fills emu_nid_to_phys[] with identity mapping if emulation is not used. This allows the caller to call numa_emulation() unconditionally and makes return value unncessary. - defines dummy version if CONFIG_NUMA_EMU is disabled. This patch doesn't introduce any behavior change. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Yinghai Lu <yinghai@kernel.org> Cc: Ingo Molnar <mingo@redhat.com>
This commit is contained in:
parent
69efcc6d90
commit
fbe99959d1
1 changed files with 33 additions and 23 deletions
|
@ -789,17 +789,20 @@ 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(void)
|
static void __init numa_emulation(struct numa_meminfo *numa_meminfo,
|
||||||
|
int numa_dist_cnt)
|
||||||
{
|
{
|
||||||
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;
|
u8 *phys_dist = NULL;
|
||||||
int i, j, ret;
|
int i, j, ret;
|
||||||
|
|
||||||
|
if (!emu_cmdline)
|
||||||
|
goto no_emu;
|
||||||
|
|
||||||
memset(&ei, 0, sizeof(ei));
|
memset(&ei, 0, sizeof(ei));
|
||||||
pi = numa_meminfo;
|
pi = *numa_meminfo;
|
||||||
|
|
||||||
for (i = 0; i < MAX_NUMNODES; i++)
|
for (i = 0; i < MAX_NUMNODES; i++)
|
||||||
emu_nid_to_phys[i] = NUMA_NO_NODE;
|
emu_nid_to_phys[i] = NUMA_NO_NODE;
|
||||||
|
@ -822,19 +825,19 @@ static bool __init numa_emulation(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return false;
|
goto no_emu;
|
||||||
|
|
||||||
if (numa_cleanup_meminfo(&ei) < 0) {
|
if (numa_cleanup_meminfo(&ei) < 0) {
|
||||||
pr_warning("NUMA: Warning: constructed meminfo invalid, disabling emulation\n");
|
pr_warning("NUMA: Warning: constructed meminfo invalid, disabling emulation\n");
|
||||||
return false;
|
goto no_emu;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy the original distance table. It's temporary so no need to
|
* Copy the original distance table. It's temporary so no need to
|
||||||
* reserve it.
|
* reserve it.
|
||||||
*/
|
*/
|
||||||
if (phys_dist_cnt) {
|
if (numa_dist_cnt) {
|
||||||
size_t size = phys_dist_cnt * sizeof(numa_distance[0]);
|
size_t size = numa_dist_cnt * sizeof(phys_dist[0]);
|
||||||
u64 phys;
|
u64 phys;
|
||||||
|
|
||||||
phys = memblock_find_in_range(0,
|
phys = memblock_find_in_range(0,
|
||||||
|
@ -842,14 +845,18 @@ static bool __init numa_emulation(void)
|
||||||
size, PAGE_SIZE);
|
size, PAGE_SIZE);
|
||||||
if (phys == MEMBLOCK_ERROR) {
|
if (phys == MEMBLOCK_ERROR) {
|
||||||
pr_warning("NUMA: Warning: can't allocate copy of distance table, disabling emulation\n");
|
pr_warning("NUMA: Warning: can't allocate copy of distance table, disabling emulation\n");
|
||||||
return false;
|
goto no_emu;
|
||||||
}
|
}
|
||||||
phys_dist = __va(phys);
|
phys_dist = __va(phys);
|
||||||
memcpy(phys_dist, numa_distance, size);
|
|
||||||
|
for (i = 0; i < numa_dist_cnt; i++)
|
||||||
|
for (j = 0; j < numa_dist_cnt; j++)
|
||||||
|
phys_dist[i * numa_dist_cnt + j] =
|
||||||
|
node_distance(i, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* commit */
|
/* commit */
|
||||||
numa_meminfo = ei;
|
*numa_meminfo = ei;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transform __apicid_to_node table to use emulated nids by
|
* Transform __apicid_to_node table to use emulated nids by
|
||||||
|
@ -878,18 +885,27 @@ static bool __init numa_emulation(void)
|
||||||
int physj = emu_nid_to_phys[j];
|
int physj = emu_nid_to_phys[j];
|
||||||
int dist;
|
int dist;
|
||||||
|
|
||||||
if (physi >= phys_dist_cnt || physj >= phys_dist_cnt)
|
if (physi >= numa_dist_cnt || physj >= numa_dist_cnt)
|
||||||
dist = physi == physj ?
|
dist = physi == physj ?
|
||||||
LOCAL_DISTANCE : REMOTE_DISTANCE;
|
LOCAL_DISTANCE : REMOTE_DISTANCE;
|
||||||
else
|
else
|
||||||
dist = phys_dist[physi * phys_dist_cnt + physj];
|
dist = phys_dist[physi * numa_dist_cnt + physj];
|
||||||
|
|
||||||
numa_set_distance(i, j, dist);
|
numa_set_distance(i, j, dist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return;
|
||||||
|
|
||||||
|
no_emu:
|
||||||
|
/* No emulation. Build identity emu_nid_to_phys[] for numa_add_cpu() */
|
||||||
|
for (i = 0; i < ARRAY_SIZE(emu_nid_to_phys); i++)
|
||||||
|
emu_nid_to_phys[i] = i;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NUMA_EMU */
|
#else /* CONFIG_NUMA_EMU */
|
||||||
|
static inline void numa_emulation(struct numa_meminfo *numa_meminfo,
|
||||||
|
int numa_dist_cnt)
|
||||||
|
{ }
|
||||||
|
#endif /* CONFIG_NUMA_EMU */
|
||||||
|
|
||||||
static int __init dummy_numa_init(void)
|
static int __init dummy_numa_init(void)
|
||||||
{
|
{
|
||||||
|
@ -937,15 +953,9 @@ void __init initmem_init(void)
|
||||||
|
|
||||||
if (numa_cleanup_meminfo(&numa_meminfo) < 0)
|
if (numa_cleanup_meminfo(&numa_meminfo) < 0)
|
||||||
continue;
|
continue;
|
||||||
#ifdef CONFIG_NUMA_EMU
|
|
||||||
/*
|
numa_emulation(&numa_meminfo, numa_distance_cnt);
|
||||||
* If requested, try emulation. If emulation is not used,
|
|
||||||
* build identity emu_nid_to_phys[] for numa_add_cpu()
|
|
||||||
*/
|
|
||||||
if (!emu_cmdline || !numa_emulation())
|
|
||||||
for (j = 0; j < ARRAY_SIZE(emu_nid_to_phys); j++)
|
|
||||||
emu_nid_to_phys[j] = j;
|
|
||||||
#endif
|
|
||||||
if (numa_register_memblks(&numa_meminfo) < 0)
|
if (numa_register_memblks(&numa_meminfo) < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue