From dfbb9042801eaeb4df9015bb86224291a39a0f52 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 23 May 2007 17:48:36 +0900 Subject: sh: sparsemem support. This implements basic sparsemem support for SH. Presently this only uses static sparsemem, and we still permit explicit selection of flatmem. Those boards that want sparsemem can select it as usual. Signed-off-by: Paul Mundt --- arch/sh/mm/init.c | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) (limited to 'arch/sh/mm/init.c') diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index e0e644ff320..1589466f9f8 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -36,14 +36,11 @@ void show_mem(void) show_free_areas(); for_each_online_pgdat(pgdat) { - struct page *page, *end; - unsigned long flags; + unsigned long flags, i; pgdat_resize_lock(pgdat, &flags); - page = pgdat->node_mem_map; - end = page + pgdat->node_spanned_pages; - - do { + for (i = 0; i < pgdat->node_spanned_pages; i++) { + struct page *page = pgdat_page_nr(pgdat, i); total++; if (PageReserved(page)) reserved++; @@ -55,9 +52,7 @@ void show_mem(void) free++; else shared += page_count(page) - 1; - page++; - } while (page < end); - + } pgdat_resize_unlock(pgdat, &flags); } @@ -169,15 +164,11 @@ void __init paging_init(void) low = pgdat->bdata->node_low_pfn; max_zone_pfns[ZONE_NORMAL] = low; - add_active_range(nid, start_pfn, low); printk("Node %u: start_pfn = 0x%lx, low = 0x%lx\n", nid, start_pfn, low); free_area_init_nodes(max_zone_pfns); - - printk("Node %u: mem_map starts at %p\n", - pgdat->node_id, pgdat->node_mem_map); } } @@ -185,16 +176,13 @@ static struct kcore_list kcore_mem, kcore_vmalloc; void __init mem_init(void) { - int codesize, reservedpages, datasize, initsize; + int codesize, datasize, initsize; int nid; - reservedpages = 0; - for_each_online_node(nid) { pg_data_t *pgdat = NODE_DATA(nid); unsigned long node_pages = 0; void *node_high_memory; - int i; num_physpages += pgdat->node_present_pages; @@ -203,10 +191,6 @@ void __init mem_init(void) totalram_pages += node_pages; - for (i = 0; i < node_pages; i++) - if (PageReserved(pgdat->node_mem_map + i)) - reservedpages++; - node_high_memory = (void *)((pgdat->node_start_pfn + pgdat->node_spanned_pages) << PAGE_SHIFT); @@ -239,11 +223,10 @@ void __init mem_init(void) VMALLOC_END - VMALLOC_START); printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, " - "%dk reserved, %dk data, %dk init)\n", + "%dk data, %dk init)\n", (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), totalram_pages << (PAGE_SHIFT-10), codesize >> 10, - reservedpages << (PAGE_SHIFT-10), datasize >> 10, initsize >> 10); -- cgit v1.2.3 From 2de212ebd8d5c1a17e40bffcc7e434443105c4b8 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 6 Jun 2007 12:09:54 +0900 Subject: sh: Fix up max_zone_pfns[] with multiple nodes. Currently using multiple nodes tramples the ZONE_NORMAL max low pfn, tidy up the logic a bit to get it all working as expected. Signed-off-by: Paul Mundt --- arch/sh/mm/init.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'arch/sh/mm/init.c') diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 1589466f9f8..2032b39c229 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -142,6 +142,7 @@ extern char __init_begin, __init_end; */ void __init paging_init(void) { + unsigned long max_zone_pfns[MAX_NR_ZONES]; int nid; /* We don't need to map the kernel through the TLB, as @@ -153,23 +154,23 @@ void __init paging_init(void) * check for a null value. */ set_TTB(swapper_pg_dir); + memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); + for_each_online_node(nid) { pg_data_t *pgdat = NODE_DATA(nid); - unsigned long max_zone_pfns[MAX_NR_ZONES]; unsigned long low, start_pfn; - memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); - start_pfn = pgdat->bdata->node_boot_start >> PAGE_SHIFT; low = pgdat->bdata->node_low_pfn; - max_zone_pfns[ZONE_NORMAL] = low; + if (max_zone_pfns[ZONE_NORMAL] < low) + max_zone_pfns[ZONE_NORMAL] = low; printk("Node %u: start_pfn = 0x%lx, low = 0x%lx\n", nid, start_pfn, low); - - free_area_init_nodes(max_zone_pfns); } + + free_area_init_nodes(max_zone_pfns); } static struct kcore_list kcore_mem, kcore_vmalloc; @@ -179,6 +180,9 @@ void __init mem_init(void) int codesize, datasize, initsize; int nid; + num_physpages = 0; + high_memory = NULL; + for_each_online_node(nid) { pg_data_t *pgdat = NODE_DATA(nid); unsigned long node_pages = 0; @@ -191,9 +195,9 @@ void __init mem_init(void) totalram_pages += node_pages; - node_high_memory = (void *)((pgdat->node_start_pfn + - pgdat->node_spanned_pages) << - PAGE_SHIFT); + node_high_memory = (void *)__va((pgdat->node_start_pfn + + pgdat->node_spanned_pages) << + PAGE_SHIFT); if (node_high_memory > high_memory) high_memory = node_high_memory; } @@ -225,7 +229,7 @@ void __init mem_init(void) printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, " "%dk data, %dk init)\n", (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), - totalram_pages << (PAGE_SHIFT-10), + num_physpages << (PAGE_SHIFT-10), codesize >> 10, datasize >> 10, initsize >> 10); @@ -247,7 +251,8 @@ void free_initmem(void) free_page(addr); totalram_pages++; } - printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); + printk("Freeing unused kernel memory: %dk freed\n", + (&__init_end - &__init_begin) >> 10); } #ifdef CONFIG_BLK_DEV_INITRD @@ -260,6 +265,6 @@ void free_initrd_mem(unsigned long start, unsigned long end) free_page(p); totalram_pages++; } - printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); + printk("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); } #endif -- cgit v1.2.3 From 07cbb41b5308b92f29649254ff755e48ea60e24c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 6 Jun 2007 12:23:06 +0900 Subject: sh: Use asm/sections.h for linker section symbols. Kill off a bunch of externs, and use sections.h instead.. Signed-off-by: Paul Mundt --- arch/sh/mm/init.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'arch/sh/mm/init.c') diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 2032b39c229..753e11d5e62 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -18,6 +18,7 @@ #include #include #include +#include #include DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); @@ -132,11 +133,6 @@ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) } #endif /* CONFIG_MMU */ -/* References to section boundaries */ - -extern char _text, _etext, _edata, __bss_start, _end; -extern char __init_begin, __init_end; - /* * paging_init() sets up the page tables */ @@ -251,8 +247,9 @@ void free_initmem(void) free_page(addr); totalram_pages++; } - printk("Freeing unused kernel memory: %dk freed\n", - (&__init_end - &__init_begin) >> 10); + printk("Freeing unused kernel memory: %ldk freed\n", + ((unsigned long)&__init_end - + (unsigned long)&__init_begin) >> 10); } #ifdef CONFIG_BLK_DEV_INITRD -- cgit v1.2.3 From 33d63bd83bf9aa6b662a376a96b825acba721e8f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 7 Jun 2007 11:32:52 +0900 Subject: sh: memory hot-add for sparsemem users support. This enables simple hotplug support for sparsemem users. Presently this only permits memory being added in to node 0 on ZONE_NORMAL. Signed-off-by: Paul Mundt --- arch/sh/mm/init.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'arch/sh/mm/init.c') diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 753e11d5e62..40d4e798e7f 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -265,3 +265,45 @@ void free_initrd_mem(unsigned long start, unsigned long end) printk("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); } #endif + +#ifdef CONFIG_MEMORY_HOTPLUG +void online_page(struct page *page) +{ + ClearPageReserved(page); + init_page_count(page); + __free_page(page); + totalram_pages++; + num_physpages++; +} + +int arch_add_memory(int nid, u64 start, u64 size) +{ + pg_data_t *pgdat; + unsigned long start_pfn = start >> PAGE_SHIFT; + unsigned long nr_pages = size >> PAGE_SHIFT; + int ret; + + pgdat = NODE_DATA(nid); + + /* We only have ZONE_NORMAL, so this is easy.. */ + ret = __add_pages(pgdat->node_zones + ZONE_NORMAL, start_pfn, nr_pages); + if (unlikely(ret)) + printk("%s: Failed, __add_pages() == %d\n", __FUNCTION__, ret); + + return ret; +} +EXPORT_SYMBOL_GPL(arch_add_memory); + +int remove_memory(u64 start, u64 size) +{ + return -EINVAL; +} +EXPORT_SYMBOL_GPL(remove_memory); + +int memory_add_physaddr_to_nid(u64 addr) +{ + /* Node 0 for now.. */ + return 0; +} +EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); +#endif -- cgit v1.2.3 From 357d59469c1179c30b8c425aba302346fac3594e Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 11 Jun 2007 15:32:07 +0900 Subject: sh: Tidy up dependencies for SH-2 build. SH-2 can presently get in to some pretty bogus states, so we tidy up the dependencies a bit and get it all building again. This gets us a bit closer to a functional allyesconfig and allmodconfig, though there are still a few things to fix up. Signed-off-by: Paul Mundt --- arch/sh/mm/init.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/sh/mm/init.c') diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 40d4e798e7f..82b68c789a5 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -300,6 +300,7 @@ int remove_memory(u64 start, u64 size) } EXPORT_SYMBOL_GPL(remove_memory); +#ifdef CONFIG_NUMA int memory_add_physaddr_to_nid(u64 addr) { /* Node 0 for now.. */ @@ -307,3 +308,4 @@ int memory_add_physaddr_to_nid(u64 addr) } EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); #endif +#endif -- cgit v1.2.3