diff options
Diffstat (limited to 'arch/x86_64/mm/init.c')
-rw-r--r-- | arch/x86_64/mm/init.c | 73 |
1 files changed, 43 insertions, 30 deletions
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 02add1d1dfa8..95bd232ff0cf 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/bootmem.h> | 23 | #include <linux/bootmem.h> |
24 | #include <linux/proc_fs.h> | 24 | #include <linux/proc_fs.h> |
25 | #include <linux/pci.h> | 25 | #include <linux/pci.h> |
26 | #include <linux/poison.h> | ||
26 | #include <linux/dma-mapping.h> | 27 | #include <linux/dma-mapping.h> |
27 | #include <linux/module.h> | 28 | #include <linux/module.h> |
28 | #include <linux/memory_hotplug.h> | 29 | #include <linux/memory_hotplug.h> |
@@ -506,8 +507,6 @@ void __init clear_kernel_mapping(unsigned long address, unsigned long size) | |||
506 | /* | 507 | /* |
507 | * Memory hotplug specific functions | 508 | * Memory hotplug specific functions |
508 | */ | 509 | */ |
509 | #if defined(CONFIG_ACPI_HOTPLUG_MEMORY) || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE) | ||
510 | |||
511 | void online_page(struct page *page) | 510 | void online_page(struct page *page) |
512 | { | 511 | { |
513 | ClearPageReserved(page); | 512 | ClearPageReserved(page); |
@@ -517,31 +516,17 @@ void online_page(struct page *page) | |||
517 | num_physpages++; | 516 | num_physpages++; |
518 | } | 517 | } |
519 | 518 | ||
520 | #ifndef CONFIG_MEMORY_HOTPLUG | 519 | #ifdef CONFIG_MEMORY_HOTPLUG |
521 | /* | 520 | /* |
522 | * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance, | 521 | * XXX: memory_add_physaddr_to_nid() is to find node id from physical address |
523 | * just online the pages. | 522 | * via probe interface of sysfs. If acpi notifies hot-add event, then it |
523 | * can tell node id by searching dsdt. But, probe interface doesn't have | ||
524 | * node id. So, return 0 as node id at this time. | ||
524 | */ | 525 | */ |
525 | int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) | 526 | #ifdef CONFIG_NUMA |
527 | int memory_add_physaddr_to_nid(u64 start) | ||
526 | { | 528 | { |
527 | int err = -EIO; | 529 | return 0; |
528 | unsigned long pfn; | ||
529 | unsigned long total = 0, mem = 0; | ||
530 | for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) { | ||
531 | if (pfn_valid(pfn)) { | ||
532 | online_page(pfn_to_page(pfn)); | ||
533 | err = 0; | ||
534 | mem++; | ||
535 | } | ||
536 | total++; | ||
537 | } | ||
538 | if (!err) { | ||
539 | z->spanned_pages += total; | ||
540 | z->present_pages += mem; | ||
541 | z->zone_pgdat->node_spanned_pages += total; | ||
542 | z->zone_pgdat->node_present_pages += mem; | ||
543 | } | ||
544 | return err; | ||
545 | } | 530 | } |
546 | #endif | 531 | #endif |
547 | 532 | ||
@@ -549,9 +534,9 @@ int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) | |||
549 | * Memory is added always to NORMAL zone. This means you will never get | 534 | * Memory is added always to NORMAL zone. This means you will never get |
550 | * additional DMA/DMA32 memory. | 535 | * additional DMA/DMA32 memory. |
551 | */ | 536 | */ |
552 | int add_memory(u64 start, u64 size) | 537 | int arch_add_memory(int nid, u64 start, u64 size) |
553 | { | 538 | { |
554 | struct pglist_data *pgdat = NODE_DATA(0); | 539 | struct pglist_data *pgdat = NODE_DATA(nid); |
555 | struct zone *zone = pgdat->node_zones + MAX_NR_ZONES-2; | 540 | struct zone *zone = pgdat->node_zones + MAX_NR_ZONES-2; |
556 | unsigned long start_pfn = start >> PAGE_SHIFT; | 541 | unsigned long start_pfn = start >> PAGE_SHIFT; |
557 | unsigned long nr_pages = size >> PAGE_SHIFT; | 542 | unsigned long nr_pages = size >> PAGE_SHIFT; |
@@ -568,7 +553,7 @@ error: | |||
568 | printk("%s: Problem encountered in __add_pages!\n", __func__); | 553 | printk("%s: Problem encountered in __add_pages!\n", __func__); |
569 | return ret; | 554 | return ret; |
570 | } | 555 | } |
571 | EXPORT_SYMBOL_GPL(add_memory); | 556 | EXPORT_SYMBOL_GPL(arch_add_memory); |
572 | 557 | ||
573 | int remove_memory(u64 start, u64 size) | 558 | int remove_memory(u64 start, u64 size) |
574 | { | 559 | { |
@@ -576,7 +561,33 @@ int remove_memory(u64 start, u64 size) | |||
576 | } | 561 | } |
577 | EXPORT_SYMBOL_GPL(remove_memory); | 562 | EXPORT_SYMBOL_GPL(remove_memory); |
578 | 563 | ||
579 | #endif | 564 | #else /* CONFIG_MEMORY_HOTPLUG */ |
565 | /* | ||
566 | * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance, | ||
567 | * just online the pages. | ||
568 | */ | ||
569 | int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) | ||
570 | { | ||
571 | int err = -EIO; | ||
572 | unsigned long pfn; | ||
573 | unsigned long total = 0, mem = 0; | ||
574 | for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) { | ||
575 | if (pfn_valid(pfn)) { | ||
576 | online_page(pfn_to_page(pfn)); | ||
577 | err = 0; | ||
578 | mem++; | ||
579 | } | ||
580 | total++; | ||
581 | } | ||
582 | if (!err) { | ||
583 | z->spanned_pages += total; | ||
584 | z->present_pages += mem; | ||
585 | z->zone_pgdat->node_spanned_pages += total; | ||
586 | z->zone_pgdat->node_present_pages += mem; | ||
587 | } | ||
588 | return err; | ||
589 | } | ||
590 | #endif /* CONFIG_MEMORY_HOTPLUG */ | ||
580 | 591 | ||
581 | static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules, | 592 | static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules, |
582 | kcore_vsyscall; | 593 | kcore_vsyscall; |
@@ -650,7 +661,8 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) | |||
650 | for (addr = begin; addr < end; addr += PAGE_SIZE) { | 661 | for (addr = begin; addr < end; addr += PAGE_SIZE) { |
651 | ClearPageReserved(virt_to_page(addr)); | 662 | ClearPageReserved(virt_to_page(addr)); |
652 | init_page_count(virt_to_page(addr)); | 663 | init_page_count(virt_to_page(addr)); |
653 | memset((void *)(addr & ~(PAGE_SIZE-1)), 0xcc, PAGE_SIZE); | 664 | memset((void *)(addr & ~(PAGE_SIZE-1)), |
665 | POISON_FREE_INITMEM, PAGE_SIZE); | ||
654 | free_page(addr); | 666 | free_page(addr); |
655 | totalram_pages++; | 667 | totalram_pages++; |
656 | } | 668 | } |
@@ -658,7 +670,8 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) | |||
658 | 670 | ||
659 | void free_initmem(void) | 671 | void free_initmem(void) |
660 | { | 672 | { |
661 | memset(__initdata_begin, 0xba, __initdata_end - __initdata_begin); | 673 | memset(__initdata_begin, POISON_FREE_INITDATA, |
674 | __initdata_end - __initdata_begin); | ||
662 | free_init_pages("unused kernel memory", | 675 | free_init_pages("unused kernel memory", |
663 | (unsigned long)(&__init_begin), | 676 | (unsigned long)(&__init_begin), |
664 | (unsigned long)(&__init_end)); | 677 | (unsigned long)(&__init_end)); |