aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-05-02 08:18:51 -0400
committerTejun Heo <tj@kernel.org>2011-05-02 08:18:51 -0400
commitacd26d611e60c1a7c2a14269ab99760f779121f4 (patch)
tree1ba64ef16bbf1f50226c9b48003743f0e8f141d0 /arch
parentebe685f24eeb85fbdb0f33792f1dabdbf35eff38 (diff)
x86-64, NUMA: simplify nodedata allocation
With top-down memblock allocation, the allocation range limits in ealry_node_mem() can be simplified - try node-local first, then any node but in any case don't allocate below DMA limit. Remove early_node_mem() and implement simplified allocation directly in setup_node_bootmem(). 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>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/mm/numa_64.c53
1 files changed, 17 insertions, 36 deletions
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 8043d5e7f0d3..b4fd25e753cb 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -37,38 +37,6 @@ __initdata
37static int numa_distance_cnt; 37static int numa_distance_cnt;
38static u8 *numa_distance; 38static u8 *numa_distance;
39 39
40static void * __init early_node_mem(int nodeid, unsigned long start,
41 unsigned long end, unsigned long size,
42 unsigned long align)
43{
44 unsigned long mem;
45
46 /*
47 * put it on high as possible
48 * something will go with NODE_DATA
49 */
50 if (start < (MAX_DMA_PFN<<PAGE_SHIFT))
51 start = MAX_DMA_PFN<<PAGE_SHIFT;
52 if (start < (MAX_DMA32_PFN<<PAGE_SHIFT) &&
53 end > (MAX_DMA32_PFN<<PAGE_SHIFT))
54 start = MAX_DMA32_PFN<<PAGE_SHIFT;
55 mem = memblock_x86_find_in_range_node(nodeid, start, end, size, align);
56 if (mem != MEMBLOCK_ERROR)
57 return __va(mem);
58
59 /* extend the search scope */
60 end = max_pfn_mapped << PAGE_SHIFT;
61 start = MAX_DMA_PFN << PAGE_SHIFT;
62 mem = memblock_find_in_range(start, end, size, align);
63 if (mem != MEMBLOCK_ERROR)
64 return __va(mem);
65
66 printk(KERN_ERR "Cannot find %lu bytes in node %d\n",
67 size, nodeid);
68
69 return NULL;
70}
71
72static int __init numa_add_memblk_to(int nid, u64 start, u64 end, 40static int __init numa_add_memblk_to(int nid, u64 start, u64 end,
73 struct numa_meminfo *mi) 41 struct numa_meminfo *mi)
74{ 42{
@@ -130,6 +98,8 @@ int __init numa_add_memblk(int nid, u64 start, u64 end)
130void __init 98void __init
131setup_node_bootmem(int nid, unsigned long start, unsigned long end) 99setup_node_bootmem(int nid, unsigned long start, unsigned long end)
132{ 100{
101 const u64 nd_low = (u64)MAX_DMA_PFN << PAGE_SHIFT;
102 const u64 nd_high = (u64)max_pfn_mapped << PAGE_SHIFT;
133 const size_t nd_size = roundup(sizeof(pg_data_t), PAGE_SIZE); 103 const size_t nd_size = roundup(sizeof(pg_data_t), PAGE_SIZE);
134 unsigned long nd_pa; 104 unsigned long nd_pa;
135 int tnid; 105 int tnid;
@@ -146,18 +116,29 @@ setup_node_bootmem(int nid, unsigned long start, unsigned long end)
146 printk(KERN_INFO "Initmem setup node %d %016lx-%016lx\n", 116 printk(KERN_INFO "Initmem setup node %d %016lx-%016lx\n",
147 nid, start, end); 117 nid, start, end);
148 118
149 node_data[nid] = early_node_mem(nid, start, end, nd_size, 119 /*
150 SMP_CACHE_BYTES); 120 * Try to allocate node data on local node and then fall back to
151 if (node_data[nid] == NULL) 121 * all nodes. Never allocate in DMA zone.
122 */
123 nd_pa = memblock_x86_find_in_range_node(nid, nd_low, nd_high,
124 nd_size, SMP_CACHE_BYTES);
125 if (nd_pa == MEMBLOCK_ERROR)
126 nd_pa = memblock_find_in_range(nd_low, nd_high,
127 nd_size, SMP_CACHE_BYTES);
128 if (nd_pa == MEMBLOCK_ERROR) {
129 pr_err("Cannot find %lu bytes in node %d\n", nd_size, nid);
152 return; 130 return;
153 nd_pa = __pa(node_data[nid]); 131 }
154 memblock_x86_reserve_range(nd_pa, nd_pa + nd_size, "NODE_DATA"); 132 memblock_x86_reserve_range(nd_pa, nd_pa + nd_size, "NODE_DATA");
133
134 /* report and initialize */
155 printk(KERN_INFO " NODE_DATA [%016lx - %016lx]\n", 135 printk(KERN_INFO " NODE_DATA [%016lx - %016lx]\n",
156 nd_pa, nd_pa + nd_size - 1); 136 nd_pa, nd_pa + nd_size - 1);
157 tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT); 137 tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT);
158 if (tnid != nid) 138 if (tnid != nid)
159 printk(KERN_INFO " NODE_DATA(%d) on node %d\n", nid, tnid); 139 printk(KERN_INFO " NODE_DATA(%d) on node %d\n", nid, tnid);
160 140
141 node_data[nid] = __va(nd_pa);
161 memset(NODE_DATA(nid), 0, sizeof(pg_data_t)); 142 memset(NODE_DATA(nid), 0, sizeof(pg_data_t));
162 NODE_DATA(nid)->node_id = nid; 143 NODE_DATA(nid)->node_id = nid;
163 NODE_DATA(nid)->node_start_pfn = start >> PAGE_SHIFT; 144 NODE_DATA(nid)->node_start_pfn = start >> PAGE_SHIFT;