diff options
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/mm/discontig.c | 4 | ||||
-rw-r--r-- | arch/i386/mm/init.c | 62 |
2 files changed, 59 insertions, 7 deletions
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c index 244d8ec66be2..c4af9638dbfa 100644 --- a/arch/i386/mm/discontig.c +++ b/arch/i386/mm/discontig.c | |||
@@ -98,7 +98,7 @@ unsigned long node_memmap_size_bytes(int nid, unsigned long start_pfn, | |||
98 | 98 | ||
99 | extern unsigned long find_max_low_pfn(void); | 99 | extern unsigned long find_max_low_pfn(void); |
100 | extern void find_max_pfn(void); | 100 | extern void find_max_pfn(void); |
101 | extern void one_highpage_init(struct page *, int, int); | 101 | extern void add_one_highpage_init(struct page *, int, int); |
102 | 102 | ||
103 | extern struct e820map e820; | 103 | extern struct e820map e820; |
104 | extern unsigned long init_pg_tables_end; | 104 | extern unsigned long init_pg_tables_end; |
@@ -427,7 +427,7 @@ void __init set_highmem_pages_init(int bad_ppro) | |||
427 | if (!pfn_valid(node_pfn)) | 427 | if (!pfn_valid(node_pfn)) |
428 | continue; | 428 | continue; |
429 | page = pfn_to_page(node_pfn); | 429 | page = pfn_to_page(node_pfn); |
430 | one_highpage_init(page, node_pfn, bad_ppro); | 430 | add_one_highpage_init(page, node_pfn, bad_ppro); |
431 | } | 431 | } |
432 | } | 432 | } |
433 | totalram_pages += totalhigh_pages; | 433 | totalram_pages += totalhigh_pages; |
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 2ebaf75f732e..542d9298da5e 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/proc_fs.h> | 28 | #include <linux/proc_fs.h> |
29 | #include <linux/efi.h> | 29 | #include <linux/efi.h> |
30 | #include <linux/memory_hotplug.h> | ||
30 | 31 | ||
31 | #include <asm/processor.h> | 32 | #include <asm/processor.h> |
32 | #include <asm/system.h> | 33 | #include <asm/system.h> |
@@ -266,17 +267,46 @@ static void __init permanent_kmaps_init(pgd_t *pgd_base) | |||
266 | pkmap_page_table = pte; | 267 | pkmap_page_table = pte; |
267 | } | 268 | } |
268 | 269 | ||
269 | void __init one_highpage_init(struct page *page, int pfn, int bad_ppro) | 270 | void __devinit free_new_highpage(struct page *page) |
271 | { | ||
272 | set_page_count(page, 1); | ||
273 | __free_page(page); | ||
274 | totalhigh_pages++; | ||
275 | } | ||
276 | |||
277 | void __init add_one_highpage_init(struct page *page, int pfn, int bad_ppro) | ||
270 | { | 278 | { |
271 | if (page_is_ram(pfn) && !(bad_ppro && page_kills_ppro(pfn))) { | 279 | if (page_is_ram(pfn) && !(bad_ppro && page_kills_ppro(pfn))) { |
272 | ClearPageReserved(page); | 280 | ClearPageReserved(page); |
273 | set_page_count(page, 1); | 281 | free_new_highpage(page); |
274 | __free_page(page); | ||
275 | totalhigh_pages++; | ||
276 | } else | 282 | } else |
277 | SetPageReserved(page); | 283 | SetPageReserved(page); |
278 | } | 284 | } |
279 | 285 | ||
286 | static int add_one_highpage_hotplug(struct page *page, unsigned long pfn) | ||
287 | { | ||
288 | free_new_highpage(page); | ||
289 | totalram_pages++; | ||
290 | #ifdef CONFIG_FLATMEM | ||
291 | max_mapnr = max(pfn, max_mapnr); | ||
292 | #endif | ||
293 | num_physpages++; | ||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | /* | ||
298 | * Not currently handling the NUMA case. | ||
299 | * Assuming single node and all memory that | ||
300 | * has been added dynamically that would be | ||
301 | * onlined here is in HIGHMEM | ||
302 | */ | ||
303 | void online_page(struct page *page) | ||
304 | { | ||
305 | ClearPageReserved(page); | ||
306 | add_one_highpage_hotplug(page, page_to_pfn(page)); | ||
307 | } | ||
308 | |||
309 | |||
280 | #ifdef CONFIG_NUMA | 310 | #ifdef CONFIG_NUMA |
281 | extern void set_highmem_pages_init(int); | 311 | extern void set_highmem_pages_init(int); |
282 | #else | 312 | #else |
@@ -284,7 +314,7 @@ static void __init set_highmem_pages_init(int bad_ppro) | |||
284 | { | 314 | { |
285 | int pfn; | 315 | int pfn; |
286 | for (pfn = highstart_pfn; pfn < highend_pfn; pfn++) | 316 | for (pfn = highstart_pfn; pfn < highend_pfn; pfn++) |
287 | one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro); | 317 | add_one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro); |
288 | totalram_pages += totalhigh_pages; | 318 | totalram_pages += totalhigh_pages; |
289 | } | 319 | } |
290 | #endif /* CONFIG_FLATMEM */ | 320 | #endif /* CONFIG_FLATMEM */ |
@@ -615,6 +645,28 @@ void __init mem_init(void) | |||
615 | #endif | 645 | #endif |
616 | } | 646 | } |
617 | 647 | ||
648 | /* | ||
649 | * this is for the non-NUMA, single node SMP system case. | ||
650 | * Specifically, in the case of x86, we will always add | ||
651 | * memory to the highmem for now. | ||
652 | */ | ||
653 | #ifndef CONFIG_NEED_MULTIPLE_NODES | ||
654 | int add_memory(u64 start, u64 size) | ||
655 | { | ||
656 | struct pglist_data *pgdata = &contig_page_data; | ||
657 | struct zone *zone = pgdata->node_zones + MAX_NR_ZONES-1; | ||
658 | unsigned long start_pfn = start >> PAGE_SHIFT; | ||
659 | unsigned long nr_pages = size >> PAGE_SHIFT; | ||
660 | |||
661 | return __add_pages(zone, start_pfn, nr_pages); | ||
662 | } | ||
663 | |||
664 | int remove_memory(u64 start, u64 size) | ||
665 | { | ||
666 | return -EINVAL; | ||
667 | } | ||
668 | #endif | ||
669 | |||
618 | kmem_cache_t *pgd_cache; | 670 | kmem_cache_t *pgd_cache; |
619 | kmem_cache_t *pmd_cache; | 671 | kmem_cache_t *pmd_cache; |
620 | 672 | ||