Commit 145e664231648121026d470094c200851a446a73

Authored by Andy Whitcroft
Committed by Linus Torvalds
1 parent 74b30be2e1

[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

... ... @@ -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
... ... @@ -1055,6 +1055,7 @@
1055 1055  
1056 1056 /* set up the bootmem stuff with available memory */
1057 1057 do_init_bootmem();
  1058 + sparse_init();
1058 1059  
1059 1060 /* initialize the syscall map in systemcfg */
1060 1061 setup_syscall_map();
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 */