Commit 145e664231648121026d470094c200851a446a73
Committed by
Linus Torvalds
1 parent
74b30be2e1
Exists in
master
and in
4 other branches
[PATCH] ppc64: sparsemem memory model
Provide the architecture specific implementation for SPARSEMEM for PPC64 systems. Signed-off-by: Andy Whitcroft <apw@shadowen.org> Signed-off-by: Dave Hansen <haveblue@us.ibm.com> Signed-off-by: Mike Kravetz <kravetz@us.ibm.com> (in part) Signed-off-by: Martin Bligh <mbligh@aracnet.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Showing 7 changed files with 68 additions and 21 deletions Side-by-side Diff
arch/ppc64/Kconfig
| ... | ... | @@ -198,6 +198,13 @@ |
| 198 | 198 | This option enables hardware multithreading on RS64 cpus. |
| 199 | 199 | pSeries systems p620 and p660 have such a cpu type. |
| 200 | 200 | |
| 201 | +config ARCH_SELECT_MEMORY_MODEL | |
| 202 | + def_bool y | |
| 203 | + | |
| 204 | +config ARCH_FLATMEM_ENABLE | |
| 205 | + def_bool y | |
| 206 | + depends on !NUMA | |
| 207 | + | |
| 201 | 208 | config ARCH_DISCONTIGMEM_ENABLE |
| 202 | 209 | def_bool y |
| 203 | 210 | depends on SMP && PPC_PSERIES |
| ... | ... | @@ -209,6 +216,10 @@ |
| 209 | 216 | config ARCH_FLATMEM_ENABLE |
| 210 | 217 | def_bool y |
| 211 | 218 | |
| 219 | +config ARCH_SPARSEMEM_ENABLE | |
| 220 | + def_bool y | |
| 221 | + depends on ARCH_DISCONTIGMEM_ENABLE | |
| 222 | + | |
| 212 | 223 | source "mm/Kconfig" |
| 213 | 224 | |
| 214 | 225 | config HAVE_ARCH_EARLY_PFN_TO_NID |
| ... | ... | @@ -229,7 +240,7 @@ |
| 229 | 240 | |
| 230 | 241 | config NUMA |
| 231 | 242 | bool "NUMA support" |
| 232 | - depends on DISCONTIGMEM | |
| 243 | + default y if DISCONTIGMEM || SPARSEMEM | |
| 233 | 244 | |
| 234 | 245 | config SCHED_SMT |
| 235 | 246 | bool "SMT (Hyperthreading) scheduler support" |
arch/ppc64/kernel/setup.c
arch/ppc64/mm/Makefile
| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | |
| 7 | 7 | obj-y := fault.o init.o imalloc.o hash_utils.o hash_low.o tlb.o \ |
| 8 | 8 | slb_low.o slb.o stab.o mmap.o |
| 9 | -obj-$(CONFIG_DISCONTIGMEM) += numa.o | |
| 9 | +obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o | |
| 10 | 10 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o |
| 11 | 11 | obj-$(CONFIG_PPC_MULTIPLATFORM) += hash_native.o |
arch/ppc64/mm/init.c
| ... | ... | @@ -531,7 +531,7 @@ |
| 531 | 531 | * Initialize the bootmem system and give it all the memory we |
| 532 | 532 | * have available. |
| 533 | 533 | */ |
| 534 | -#ifndef CONFIG_DISCONTIGMEM | |
| 534 | +#ifndef CONFIG_NEED_MULTIPLE_NODES | |
| 535 | 535 | void __init do_init_bootmem(void) |
| 536 | 536 | { |
| 537 | 537 | unsigned long i; |
| 538 | 538 | |
| 539 | 539 | |
| ... | ... | @@ -553,12 +553,20 @@ |
| 553 | 553 | |
| 554 | 554 | max_pfn = max_low_pfn; |
| 555 | 555 | |
| 556 | - /* add all physical memory to the bootmem map. Also find the first */ | |
| 556 | + /* Add all physical memory to the bootmem map, mark each area | |
| 557 | + * present. | |
| 558 | + */ | |
| 557 | 559 | for (i=0; i < lmb.memory.cnt; i++) { |
| 558 | 560 | unsigned long physbase, size; |
| 561 | + unsigned long start_pfn, end_pfn; | |
| 559 | 562 | |
| 560 | 563 | physbase = lmb.memory.region[i].physbase; |
| 561 | 564 | size = lmb.memory.region[i].size; |
| 565 | + | |
| 566 | + start_pfn = physbase >> PAGE_SHIFT; | |
| 567 | + end_pfn = start_pfn + (size >> PAGE_SHIFT); | |
| 568 | + memory_present(0, start_pfn, end_pfn); | |
| 569 | + | |
| 562 | 570 | free_bootmem(physbase, size); |
| 563 | 571 | } |
| 564 | 572 | |
| ... | ... | @@ -597,7 +605,7 @@ |
| 597 | 605 | free_area_init_node(0, NODE_DATA(0), zones_size, |
| 598 | 606 | __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); |
| 599 | 607 | } |
| 600 | -#endif /* CONFIG_DISCONTIGMEM */ | |
| 608 | +#endif /* ! CONFIG_NEED_MULTIPLE_NODES */ | |
| 601 | 609 | |
| 602 | 610 | static struct kcore_list kcore_vmem; |
| 603 | 611 | |
| ... | ... | @@ -628,7 +636,7 @@ |
| 628 | 636 | |
| 629 | 637 | void __init mem_init(void) |
| 630 | 638 | { |
| 631 | -#ifdef CONFIG_DISCONTIGMEM | |
| 639 | +#ifdef CONFIG_NEED_MULTIPLE_NODES | |
| 632 | 640 | int nid; |
| 633 | 641 | #endif |
| 634 | 642 | pg_data_t *pgdat; |
| ... | ... | @@ -639,7 +647,7 @@ |
| 639 | 647 | num_physpages = max_low_pfn; /* RAM is assumed contiguous */ |
| 640 | 648 | high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); |
| 641 | 649 | |
| 642 | -#ifdef CONFIG_DISCONTIGMEM | |
| 650 | +#ifdef CONFIG_NEED_MULTIPLE_NODES | |
| 643 | 651 | for_each_online_node(nid) { |
| 644 | 652 | if (NODE_DATA(nid)->node_spanned_pages != 0) { |
| 645 | 653 | printk("freeing bootmem node %x\n", nid); |
include/asm-ppc64/mmzone.h
| ... | ... | @@ -10,9 +10,20 @@ |
| 10 | 10 | #include <linux/config.h> |
| 11 | 11 | #include <asm/smp.h> |
| 12 | 12 | |
| 13 | -#ifdef CONFIG_DISCONTIGMEM | |
| 13 | +/* generic non-linear memory support: | |
| 14 | + * | |
| 15 | + * 1) we will not split memory into more chunks than will fit into the | |
| 16 | + * flags field of the struct page | |
| 17 | + */ | |
| 14 | 18 | |
| 19 | + | |
| 20 | +#ifdef CONFIG_NEED_MULTIPLE_NODES | |
| 21 | + | |
| 15 | 22 | extern struct pglist_data *node_data[]; |
| 23 | +/* | |
| 24 | + * Return a pointer to the node data for node n. | |
| 25 | + */ | |
| 26 | +#define NODE_DATA(nid) (node_data[nid]) | |
| 16 | 27 | |
| 17 | 28 | /* |
| 18 | 29 | * Following are specific to this numa platform. |
| 19 | 30 | |
| 20 | 31 | |
| ... | ... | @@ -47,30 +58,27 @@ |
| 47 | 58 | return nid; |
| 48 | 59 | } |
| 49 | 60 | |
| 50 | -#define pfn_to_nid(pfn) pa_to_nid((pfn) << PAGE_SHIFT) | |
| 51 | - | |
| 52 | -/* | |
| 53 | - * Return a pointer to the node data for node n. | |
| 54 | - */ | |
| 55 | -#define NODE_DATA(nid) (node_data[nid]) | |
| 56 | - | |
| 57 | 61 | #define node_localnr(pfn, nid) ((pfn) - NODE_DATA(nid)->node_start_pfn) |
| 58 | 62 | |
| 59 | 63 | /* |
| 60 | 64 | * Following are macros that each numa implmentation must define. |
| 61 | 65 | */ |
| 62 | 66 | |
| 63 | -/* | |
| 64 | - * Given a kernel address, find the home node of the underlying memory. | |
| 65 | - */ | |
| 66 | -#define kvaddr_to_nid(kaddr) pa_to_nid(__pa(kaddr)) | |
| 67 | - | |
| 68 | 67 | #define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn) |
| 69 | 68 | #define node_end_pfn(nid) (NODE_DATA(nid)->node_end_pfn) |
| 70 | 69 | |
| 71 | 70 | #define local_mapnr(kvaddr) \ |
| 72 | 71 | ( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)) |
| 73 | 72 | |
| 73 | +#ifdef CONFIG_DISCONTIGMEM | |
| 74 | + | |
| 75 | +/* | |
| 76 | + * Given a kernel address, find the home node of the underlying memory. | |
| 77 | + */ | |
| 78 | +#define kvaddr_to_nid(kaddr) pa_to_nid(__pa(kaddr)) | |
| 79 | + | |
| 80 | +#define pfn_to_nid(pfn) pa_to_nid((unsigned long)(pfn) << PAGE_SHIFT) | |
| 81 | + | |
| 74 | 82 | /* Written this way to avoid evaluating arguments twice */ |
| 75 | 83 | #define discontigmem_pfn_to_page(pfn) \ |
| 76 | 84 | ({ \ |
| ... | ... | @@ -90,6 +98,8 @@ |
| 90 | 98 | #define discontigmem_pfn_valid(pfn) ((pfn) < num_physpages) |
| 91 | 99 | |
| 92 | 100 | #endif /* CONFIG_DISCONTIGMEM */ |
| 101 | + | |
| 102 | +#endif /* CONFIG_NEED_MULTIPLE_NODES */ | |
| 93 | 103 | |
| 94 | 104 | #ifdef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID |
| 95 | 105 | #define early_pfn_to_nid(pfn) pa_to_nid(((unsigned long)pfn) << PAGE_SHIFT) |
include/asm-ppc64/page.h
| ... | ... | @@ -217,7 +217,8 @@ |
| 217 | 217 | #define page_to_pfn(page) discontigmem_page_to_pfn(page) |
| 218 | 218 | #define pfn_to_page(pfn) discontigmem_pfn_to_page(pfn) |
| 219 | 219 | #define pfn_valid(pfn) discontigmem_pfn_valid(pfn) |
| 220 | -#else | |
| 220 | +#endif | |
| 221 | +#ifdef CONFIG_FLATMEM | |
| 221 | 222 | #define pfn_to_page(pfn) (mem_map + (pfn)) |
| 222 | 223 | #define page_to_pfn(page) ((unsigned long)((page) - mem_map)) |
| 223 | 224 | #define pfn_valid(pfn) ((pfn) < max_mapnr) |
include/asm-ppc64/sparsemem.h
| 1 | +#ifndef _ASM_PPC64_SPARSEMEM_H | |
| 2 | +#define _ASM_PPC64_SPARSEMEM_H 1 | |
| 3 | + | |
| 4 | +#ifdef CONFIG_SPARSEMEM | |
| 5 | +/* | |
| 6 | + * SECTION_SIZE_BITS 2^N: how big each section will be | |
| 7 | + * MAX_PHYSADDR_BITS 2^N: how much physical address space we have | |
| 8 | + * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space | |
| 9 | + */ | |
| 10 | +#define SECTION_SIZE_BITS 24 | |
| 11 | +#define MAX_PHYSADDR_BITS 38 | |
| 12 | +#define MAX_PHYSMEM_BITS 36 | |
| 13 | + | |
| 14 | +#endif /* CONFIG_SPARSEMEM */ | |
| 15 | + | |
| 16 | +#endif /* _ASM_PPC64_SPARSEMEM_H */ |