mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-11-20 08:38:24 +08:00
x86, NUMA: Enable emulation on 32bit too
Now that NUMA init path is unified, NUMA emulation can be enabled on 32bit. Make numa_emluation.c safe on 32bit by doing the followings. * Define MAX_DMA32_PFN on 32bit too. * Include bootmem.h for max_pfn declaration. * Use u64 explicitly and always use PFN_PHYS() when converting page number to address. * Avoid __udivdi3() generation on 32bit by doing number of pages calculation instead in split_nodes_interleave(). And drop X86_64 dependency from Kconfig. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: Yinghai Lu <yinghai@kernel.org> Cc: David Rientjes <rientjes@google.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: "H. Peter Anvin" <hpa@zytor.com>
This commit is contained in:
parent
2706a0bf7b
commit
1b7e03ef75
@ -1201,7 +1201,7 @@ config NODES_SPAN_OTHER_NODES
|
|||||||
|
|
||||||
config NUMA_EMU
|
config NUMA_EMU
|
||||||
bool "NUMA emulation"
|
bool "NUMA emulation"
|
||||||
depends on X86_64 && NUMA
|
depends on NUMA
|
||||||
---help---
|
---help---
|
||||||
Enable NUMA emulation. A flat machine will be split
|
Enable NUMA emulation. A flat machine will be split
|
||||||
into virtual nodes when booted with "numa=fake=N", where N is the
|
into virtual nodes when booted with "numa=fake=N", where N is the
|
||||||
|
@ -72,19 +72,15 @@
|
|||||||
/* 16MB ISA DMA zone */
|
/* 16MB ISA DMA zone */
|
||||||
#define MAX_DMA_PFN ((16 * 1024 * 1024) >> PAGE_SHIFT)
|
#define MAX_DMA_PFN ((16 * 1024 * 1024) >> PAGE_SHIFT)
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
|
||||||
|
|
||||||
/* The maximum address that we can perform a DMA transfer to on this platform */
|
|
||||||
#define MAX_DMA_ADDRESS (PAGE_OFFSET + 0x1000000)
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* 4GB broken PCI/AGP hardware bus master zone */
|
/* 4GB broken PCI/AGP hardware bus master zone */
|
||||||
#define MAX_DMA32_PFN ((4UL * 1024 * 1024 * 1024) >> PAGE_SHIFT)
|
#define MAX_DMA32_PFN ((4UL * 1024 * 1024 * 1024) >> PAGE_SHIFT)
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_32
|
||||||
|
/* The maximum address that we can perform a DMA transfer to on this platform */
|
||||||
|
#define MAX_DMA_ADDRESS (PAGE_OFFSET + 0x1000000)
|
||||||
|
#else
|
||||||
/* Compat define for old dma zone */
|
/* Compat define for old dma zone */
|
||||||
#define MAX_DMA_ADDRESS ((unsigned long)__va(MAX_DMA_PFN << PAGE_SHIFT))
|
#define MAX_DMA_ADDRESS ((unsigned long)__va(MAX_DMA_PFN << PAGE_SHIFT))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* 8237 DMA controllers */
|
/* 8237 DMA controllers */
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/topology.h>
|
#include <linux/topology.h>
|
||||||
#include <linux/memblock.h>
|
#include <linux/memblock.h>
|
||||||
|
#include <linux/bootmem.h>
|
||||||
#include <asm/dma.h>
|
#include <asm/dma.h>
|
||||||
|
|
||||||
#include "numa_internal.h"
|
#include "numa_internal.h"
|
||||||
@ -84,7 +85,13 @@ static int __init split_nodes_interleave(struct numa_meminfo *ei,
|
|||||||
nr_nodes = MAX_NUMNODES;
|
nr_nodes = MAX_NUMNODES;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = (max_addr - addr - memblock_x86_hole_size(addr, max_addr)) / nr_nodes;
|
/*
|
||||||
|
* Calculate target node size. x86_32 freaks on __udivdi3() so do
|
||||||
|
* the division in ulong number of pages and convert back.
|
||||||
|
*/
|
||||||
|
size = max_addr - addr - memblock_x86_hole_size(addr, max_addr);
|
||||||
|
size = PFN_PHYS((unsigned long)(size >> PAGE_SHIFT) / nr_nodes);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate the number of big nodes that can be allocated as a result
|
* Calculate the number of big nodes that can be allocated as a result
|
||||||
* of consolidating the remainder.
|
* of consolidating the remainder.
|
||||||
@ -226,7 +233,7 @@ static int __init split_nodes_size_interleave(struct numa_meminfo *ei,
|
|||||||
*/
|
*/
|
||||||
while (nodes_weight(physnode_mask)) {
|
while (nodes_weight(physnode_mask)) {
|
||||||
for_each_node_mask(i, physnode_mask) {
|
for_each_node_mask(i, physnode_mask) {
|
||||||
u64 dma32_end = MAX_DMA32_PFN << PAGE_SHIFT;
|
u64 dma32_end = PFN_PHYS(MAX_DMA32_PFN);
|
||||||
u64 start, limit, end;
|
u64 start, limit, end;
|
||||||
int phys_blk;
|
int phys_blk;
|
||||||
|
|
||||||
@ -298,7 +305,7 @@ 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 = PFN_PHYS(max_pfn);
|
||||||
u8 *phys_dist = NULL;
|
u8 *phys_dist = NULL;
|
||||||
size_t phys_size = numa_dist_cnt * numa_dist_cnt * sizeof(phys_dist[0]);
|
size_t phys_size = numa_dist_cnt * numa_dist_cnt * sizeof(phys_dist[0]);
|
||||||
int max_emu_nid, dfl_phys_nid;
|
int max_emu_nid, dfl_phys_nid;
|
||||||
@ -342,8 +349,7 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt)
|
|||||||
if (numa_dist_cnt) {
|
if (numa_dist_cnt) {
|
||||||
u64 phys;
|
u64 phys;
|
||||||
|
|
||||||
phys = memblock_find_in_range(0,
|
phys = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
|
||||||
(u64)max_pfn_mapped << PAGE_SHIFT,
|
|
||||||
phys_size, PAGE_SIZE);
|
phys_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");
|
||||||
|
Loading…
Reference in New Issue
Block a user