diff options
Diffstat (limited to 'arch/i386/mm/init.c')
| -rw-r--r-- | arch/i386/mm/init.c | 62 |
1 files changed, 57 insertions, 5 deletions
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 | ||
