aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/mm/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/mm/init.c')
-rw-r--r--arch/x86_64/mm/init.c73
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
511void online_page(struct page *page) 510void 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 */
525int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) 526#ifdef CONFIG_NUMA
527int 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 */
552int add_memory(u64 start, u64 size) 537int 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}
571EXPORT_SYMBOL_GPL(add_memory); 556EXPORT_SYMBOL_GPL(arch_add_memory);
572 557
573int remove_memory(u64 start, u64 size) 558int remove_memory(u64 start, u64 size)
574{ 559{
@@ -576,7 +561,33 @@ int remove_memory(u64 start, u64 size)
576} 561}
577EXPORT_SYMBOL_GPL(remove_memory); 562EXPORT_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 */
569int __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
581static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules, 592static 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
659void free_initmem(void) 671void 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));