aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-26 17:04:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-26 17:04:32 -0400
commitc3bf9bc243092c53946fd6d8ebd6dc2f4e572d48 (patch)
tree4cabbf33e11e3a71b64394b24fe70453f41cefe8 /arch
parente3505dd50caf54e6f81f897cb347441409974a15 (diff)
parentc2b91e2eec9678dbda274e906cc32ea8f711da3b (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86-bigbox-bootmem-v3
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86-bigbox-bootmem-v3: x86_64/mm: check and print vmemmap allocation continuous x86_64: fix setup_node_bootmem to support big mem excluding with memmap x86_64: make reserve_bootmem_generic() use new reserve_bootmem() mm: allow reserve_bootmem() cross nodes mm: offset align in alloc_bootmem() mm: fix alloc_bootmem_core to use fast searching for all nodes mm: make mem_map allocation continuous
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/e820_64.c13
-rw-r--r--arch/x86/kernel/setup_64.c3
-rw-r--r--arch/x86/mm/init_64.c38
-rw-r--r--arch/x86/mm/numa_64.c42
4 files changed, 80 insertions, 16 deletions
diff --git a/arch/x86/kernel/e820_64.c b/arch/x86/kernel/e820_64.c
index 79f0d52fa99a..645ee5e32a27 100644
--- a/arch/x86/kernel/e820_64.c
+++ b/arch/x86/kernel/e820_64.c
@@ -106,14 +106,19 @@ void __init free_early(unsigned long start, unsigned long end)
106 early_res[j - 1].end = 0; 106 early_res[j - 1].end = 0;
107} 107}
108 108
109void __init early_res_to_bootmem(void) 109void __init early_res_to_bootmem(unsigned long start, unsigned long end)
110{ 110{
111 int i; 111 int i;
112 unsigned long final_start, final_end;
112 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) { 113 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
113 struct early_res *r = &early_res[i]; 114 struct early_res *r = &early_res[i];
114 printk(KERN_INFO "early res: %d [%lx-%lx] %s\n", i, 115 final_start = max(start, r->start);
115 r->start, r->end - 1, r->name); 116 final_end = min(end, r->end);
116 reserve_bootmem_generic(r->start, r->end - r->start); 117 if (final_start >= final_end)
118 continue;
119 printk(KERN_INFO " early res: %d [%lx-%lx] %s\n", i,
120 final_start, final_end - 1, r->name);
121 reserve_bootmem_generic(final_start, final_end - final_start);
117 } 122 }
118} 123}
119 124
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c
index b04e2c011e1a..60e64c8eee92 100644
--- a/arch/x86/kernel/setup_64.c
+++ b/arch/x86/kernel/setup_64.c
@@ -190,6 +190,7 @@ contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
190 bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn); 190 bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
191 e820_register_active_regions(0, start_pfn, end_pfn); 191 e820_register_active_regions(0, start_pfn, end_pfn);
192 free_bootmem_with_active_regions(0, end_pfn); 192 free_bootmem_with_active_regions(0, end_pfn);
193 early_res_to_bootmem(0, end_pfn<<PAGE_SHIFT);
193 reserve_bootmem(bootmap, bootmap_size, BOOTMEM_DEFAULT); 194 reserve_bootmem(bootmap, bootmap_size, BOOTMEM_DEFAULT);
194} 195}
195#endif 196#endif
@@ -421,8 +422,6 @@ void __init setup_arch(char **cmdline_p)
421 contig_initmem_init(0, end_pfn); 422 contig_initmem_init(0, end_pfn);
422#endif 423#endif
423 424
424 early_res_to_bootmem();
425
426 dma32_reserve_bootmem(); 425 dma32_reserve_bootmem();
427 426
428#ifdef CONFIG_ACPI_SLEEP 427#ifdef CONFIG_ACPI_SLEEP
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 0cca62663037..5fbb8652cf59 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -810,7 +810,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
810void __init reserve_bootmem_generic(unsigned long phys, unsigned len) 810void __init reserve_bootmem_generic(unsigned long phys, unsigned len)
811{ 811{
812#ifdef CONFIG_NUMA 812#ifdef CONFIG_NUMA
813 int nid = phys_to_nid(phys); 813 int nid, next_nid;
814#endif 814#endif
815 unsigned long pfn = phys >> PAGE_SHIFT; 815 unsigned long pfn = phys >> PAGE_SHIFT;
816 816
@@ -829,10 +829,16 @@ void __init reserve_bootmem_generic(unsigned long phys, unsigned len)
829 829
830 /* Should check here against the e820 map to avoid double free */ 830 /* Should check here against the e820 map to avoid double free */
831#ifdef CONFIG_NUMA 831#ifdef CONFIG_NUMA
832 reserve_bootmem_node(NODE_DATA(nid), phys, len, BOOTMEM_DEFAULT); 832 nid = phys_to_nid(phys);
833 next_nid = phys_to_nid(phys + len - 1);
834 if (nid == next_nid)
835 reserve_bootmem_node(NODE_DATA(nid), phys, len, BOOTMEM_DEFAULT);
836 else
837 reserve_bootmem(phys, len, BOOTMEM_DEFAULT);
833#else 838#else
834 reserve_bootmem(phys, len, BOOTMEM_DEFAULT); 839 reserve_bootmem(phys, len, BOOTMEM_DEFAULT);
835#endif 840#endif
841
836 if (phys+len <= MAX_DMA_PFN*PAGE_SIZE) { 842 if (phys+len <= MAX_DMA_PFN*PAGE_SIZE) {
837 dma_reserve += len / PAGE_SIZE; 843 dma_reserve += len / PAGE_SIZE;
838 set_dma_reserve(dma_reserve); 844 set_dma_reserve(dma_reserve);
@@ -926,6 +932,10 @@ const char *arch_vma_name(struct vm_area_struct *vma)
926/* 932/*
927 * Initialise the sparsemem vmemmap using huge-pages at the PMD level. 933 * Initialise the sparsemem vmemmap using huge-pages at the PMD level.
928 */ 934 */
935static long __meminitdata addr_start, addr_end;
936static void __meminitdata *p_start, *p_end;
937static int __meminitdata node_start;
938
929int __meminit 939int __meminit
930vmemmap_populate(struct page *start_page, unsigned long size, int node) 940vmemmap_populate(struct page *start_page, unsigned long size, int node)
931{ 941{
@@ -960,12 +970,32 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node)
960 PAGE_KERNEL_LARGE); 970 PAGE_KERNEL_LARGE);
961 set_pmd(pmd, __pmd(pte_val(entry))); 971 set_pmd(pmd, __pmd(pte_val(entry)));
962 972
963 printk(KERN_DEBUG " [%lx-%lx] PMD ->%p on node %d\n", 973 /* check to see if we have contiguous blocks */
964 addr, addr + PMD_SIZE - 1, p, node); 974 if (p_end != p || node_start != node) {
975 if (p_start)
976 printk(KERN_DEBUG " [%lx-%lx] PMD -> [%p-%p] on node %d\n",
977 addr_start, addr_end-1, p_start, p_end-1, node_start);
978 addr_start = addr;
979 node_start = node;
980 p_start = p;
981 }
982 addr_end = addr + PMD_SIZE;
983 p_end = p + PMD_SIZE;
965 } else { 984 } else {
966 vmemmap_verify((pte_t *)pmd, node, addr, next); 985 vmemmap_verify((pte_t *)pmd, node, addr, next);
967 } 986 }
968 } 987 }
969 return 0; 988 return 0;
970} 989}
990
991void __meminit vmemmap_populate_print_last(void)
992{
993 if (p_start) {
994 printk(KERN_DEBUG " [%lx-%lx] PMD -> [%p-%p] on node %d\n",
995 addr_start, addr_end-1, p_start, p_end-1, node_start);
996 p_start = NULL;
997 p_end = NULL;
998 node_start = 0;
999 }
1000}
971#endif 1001#endif
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 9a6892200b27..c5066d519e5d 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -196,6 +196,7 @@ void __init setup_node_bootmem(int nodeid, unsigned long start,
196 unsigned long bootmap_start, nodedata_phys; 196 unsigned long bootmap_start, nodedata_phys;
197 void *bootmap; 197 void *bootmap;
198 const int pgdat_size = round_up(sizeof(pg_data_t), PAGE_SIZE); 198 const int pgdat_size = round_up(sizeof(pg_data_t), PAGE_SIZE);
199 int nid;
199 200
200 start = round_up(start, ZONE_ALIGN); 201 start = round_up(start, ZONE_ALIGN);
201 202
@@ -218,9 +219,19 @@ void __init setup_node_bootmem(int nodeid, unsigned long start,
218 NODE_DATA(nodeid)->node_start_pfn = start_pfn; 219 NODE_DATA(nodeid)->node_start_pfn = start_pfn;
219 NODE_DATA(nodeid)->node_spanned_pages = end_pfn - start_pfn; 220 NODE_DATA(nodeid)->node_spanned_pages = end_pfn - start_pfn;
220 221
221 /* Find a place for the bootmem map */ 222 /*
223 * Find a place for the bootmem map
224 * nodedata_phys could be on other nodes by alloc_bootmem,
225 * so need to sure bootmap_start not to be small, otherwise
226 * early_node_mem will get that with find_e820_area instead
227 * of alloc_bootmem, that could clash with reserved range
228 */
222 bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); 229 bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
223 bootmap_start = round_up(nodedata_phys + pgdat_size, PAGE_SIZE); 230 nid = phys_to_nid(nodedata_phys);
231 if (nid == nodeid)
232 bootmap_start = round_up(nodedata_phys + pgdat_size, PAGE_SIZE);
233 else
234 bootmap_start = round_up(start, PAGE_SIZE);
224 /* 235 /*
225 * SMP_CAHCE_BYTES could be enough, but init_bootmem_node like 236 * SMP_CAHCE_BYTES could be enough, but init_bootmem_node like
226 * to use that to align to PAGE_SIZE 237 * to use that to align to PAGE_SIZE
@@ -245,10 +256,29 @@ void __init setup_node_bootmem(int nodeid, unsigned long start,
245 256
246 free_bootmem_with_active_regions(nodeid, end); 257 free_bootmem_with_active_regions(nodeid, end);
247 258
248 reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size, 259 /*
249 BOOTMEM_DEFAULT); 260 * convert early reserve to bootmem reserve earlier
250 reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start, 261 * otherwise early_node_mem could use early reserved mem
251 bootmap_pages<<PAGE_SHIFT, BOOTMEM_DEFAULT); 262 * on previous node
263 */
264 early_res_to_bootmem(start, end);
265
266 /*
267 * in some case early_node_mem could use alloc_bootmem
268 * to get range on other node, don't reserve that again
269 */
270 if (nid != nodeid)
271 printk(KERN_INFO " NODE_DATA(%d) on node %d\n", nodeid, nid);
272 else
273 reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys,
274 pgdat_size, BOOTMEM_DEFAULT);
275 nid = phys_to_nid(bootmap_start);
276 if (nid != nodeid)
277 printk(KERN_INFO " bootmap(%d) on node %d\n", nodeid, nid);
278 else
279 reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start,
280 bootmap_pages<<PAGE_SHIFT, BOOTMEM_DEFAULT);
281
252#ifdef CONFIG_ACPI_NUMA 282#ifdef CONFIG_ACPI_NUMA
253 srat_reserve_add_area(nodeid); 283 srat_reserve_add_area(nodeid);
254#endif 284#endif