mirror of
https://github.com/torvalds/linux.git
synced 2024-11-16 17:12:06 +00:00
8b8ca80e19
Extends the numa=fake x86_64 command-line option to allow for configurable node sizes. These nodes can be used in conjunction with cpusets for coarse memory resource management. The old command-line option is still supported: numa=fake=32 gives 32 fake NUMA nodes, ignoring the NUMA setup of the actual machine. But now you may configure your system for the node sizes of your choice: numa=fake=2*512,1024,2*256 gives two 512M nodes, one 1024M node, two 256M nodes, and the rest of system memory to a sixth node. The existing hash function is maintained to support the various node sizes that are possible with this implementation. Each node of the same size receives roughly the same amount of available pages, regardless of any reserved memory with its address range. The total available pages on the system is calculated and divided by the number of equal nodes to allocate. These nodes are then dynamically allocated and their borders extended until such time as their number of available pages reaches the required size. Configurable node sizes are recommended when used in conjunction with cpusets for memory control because it eliminates the overhead associated with scanning the zonelists of many smaller full nodes on page_alloc(). Cc: Andi Kleen <ak@suse.de> Signed-off-by: David Rientjes <rientjes@google.com> Signed-off-by: Andi Kleen <ak@suse.de> Cc: Paul Jackson <pj@sgi.com> Cc: Christoph Lameter <clameter@engr.sgi.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
57 lines
1.4 KiB
C
57 lines
1.4 KiB
C
/* K8 NUMA support */
|
|
/* Copyright 2002,2003 by Andi Kleen, SuSE Labs */
|
|
/* 2.5 Version loosely based on the NUMAQ Code by Pat Gaughen. */
|
|
#ifndef _ASM_X86_64_MMZONE_H
|
|
#define _ASM_X86_64_MMZONE_H 1
|
|
|
|
|
|
#ifdef CONFIG_NUMA
|
|
|
|
#define VIRTUAL_BUG_ON(x)
|
|
|
|
#include <asm/smp.h>
|
|
|
|
/* Simple perfect hash to map physical addresses to node numbers */
|
|
struct memnode {
|
|
int shift;
|
|
unsigned int mapsize;
|
|
u8 *map;
|
|
u8 embedded_map[64-16];
|
|
} ____cacheline_aligned; /* total size = 64 bytes */
|
|
extern struct memnode memnode;
|
|
#define memnode_shift memnode.shift
|
|
#define memnodemap memnode.map
|
|
#define memnodemapsize memnode.mapsize
|
|
|
|
extern struct pglist_data *node_data[];
|
|
|
|
static inline __attribute__((pure)) int phys_to_nid(unsigned long addr)
|
|
{
|
|
unsigned nid;
|
|
VIRTUAL_BUG_ON(!memnodemap);
|
|
VIRTUAL_BUG_ON((addr >> memnode_shift) >= memnodemapsize);
|
|
nid = memnodemap[addr >> memnode_shift];
|
|
VIRTUAL_BUG_ON(nid >= MAX_NUMNODES || !node_data[nid]);
|
|
return nid;
|
|
}
|
|
|
|
#define NODE_DATA(nid) (node_data[nid])
|
|
|
|
#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
|
|
#define node_end_pfn(nid) (NODE_DATA(nid)->node_start_pfn + \
|
|
NODE_DATA(nid)->node_spanned_pages)
|
|
|
|
#ifdef CONFIG_DISCONTIGMEM
|
|
#define pfn_to_nid(pfn) phys_to_nid((unsigned long)(pfn) << PAGE_SHIFT)
|
|
|
|
extern int pfn_valid(unsigned long pfn);
|
|
#endif
|
|
|
|
#ifdef CONFIG_NUMA_EMU
|
|
#define FAKE_NODE_MIN_SIZE (64*1024*1024)
|
|
#define FAKE_NODE_MIN_HASH_MASK (~(FAKE_NODE_MIN_SIZE - 1uL))
|
|
#endif
|
|
|
|
#endif
|
|
#endif
|