050 bootmem use NODE_DATA
Subsystems (4)
A message that is not in the archive (sent off-list or not yet received): 1098973549.shadowen.org
PATCH 1/7 050 bootmem use NODE_DATA
Convert the default non-node based bootmem routines to use NODE_DATA(0). This is semantically and functionally identical in any non-node configuration as NODE_DATA(x) is defined as below.
#define NODE_DATA(nid) (&contig_page_data)
For the node cases (CONFIG_NUMA and CONFIG_DISCONTIG_MEM) we can use these non-node forms where all boot memory is defined on node 0.
Revision: $Rev: 732 $
diffstat 050-bootmem-use-NODE_DATA
--- bootmem.c | 10 ++++------ 1 files changed, 4 insertions(+), 6 deletions(-)
mm/bootmem.c +4 -6
@@ -343,31 +343,29 @@ unsigned long __init free_all_bootmem_noreturn (free_all_bootmem_core (pgdat)); } -#ifndef CONFIG_DISCONTIGMEM unsigned long __init init_bootmem (unsigned long start,unsigned long pages) { max_low_pfn = pages; min_low_pfn = start; -return (init_bootmem_core (&contig_page_data, start,0 , pages)); +return (init_bootmem_core (NODE_DATA (0 ), start,0 , pages)); }#ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE void __init reserve_bootmem (unsigned long addr,unsigned long size) { -reserve_bootmem_core (contig_page_data.bdata, addr, size); +reserve_bootmem_core (NODE_DATA (0 )->bdata, addr, size); }#endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */ void __init free_bootmem (unsigned long addr,unsigned long size) { -free_bootmem_core (contig_page_data.bdata, addr, size); +free_bootmem_core (NODE_DATA (0 )->bdata, addr, size); }unsigned long __init free_all_bootmem (void ) { -return (free_all_bootmem_core (&contig_page_data)); +return (free_all_bootmem_core (NODE_DATA (0 ))); } -#endif /* !CONFIG_DISCONTIGMEM */ void *__init __alloc_bootmem (unsigned long size,unsigned long align,unsigned long goal) {
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 2/7 060 refactor setup_memory i386
In reply to a message not in the archiveRefactor the i386 default and CONFIG_DISCONTIG_MEM setup_memory() functions to share the common bootmem initialisation code. This code is intended to be identical, but there are currently some fixes applied to one and not the other. This patch extracts this common initialisation code.
Revision: $Rev$
diffstat 060-refactor-setup_memory-i386
--- kernel/setup.c | 25 ++++++------ mm/discontig.c | 117 +-------------------------------------------------------- 2 files changed, 18 insertions(+), 124 deletions(-)
arch/i386/kernel/setup.c +14 -11
@@ -941,8 +941,6 @@ unsigned long __init find_max_low_pfn(voreturn max_low_pfn; } -#ifndef CONFIG_DISCONTIGMEM -/* * Free all available memory for boot time allocation. Used * as a callback function by efi_memory_walk()
@@ -1016,15 +1014,15 @@ static void __init reserve_ebda_region(vreserve_bootmem (addr,PAGE_SIZE ); } +#ifndef CONFIG_DISCONTIGMEM +void __init setup_bootmem_allocator (void );static unsigned long __init setup_memory (void ) { -unsigned long bootmap_size, start_pfn, max_low_pfn; -/* * partially used pages are not usable - thus * we are rounding upwards: */ - start_pfn =PFN_UP (init_pg_tables_end); + min_low_pfn =PFN_UP (init_pg_tables_end);find_max_pfn ();
@@ -1040,10 +1038,19 @@ static unsigned long __init setup_memory#endif printk (KERN_NOTICE "%ldMB LOWMEM available.\n" ,pages_to_mb (max_low_pfn)); + +setup_bootmem_allocator (); + return max_low_pfn; +} +#endif /* !CONFIG_DISCONTIGMEM */ + +void __init setup_bootmem_allocator (void ) +{ +unsigned long bootmap_size;/* * Initialize the boot-time allocator (with low memory only): */ - bootmap_size =init_bootmem (start_pfn, max_low_pfn); + bootmap_size =init_bootmem (min_low_pfn, max_low_pfn);register_bootmem_low_pages (max_low_pfn);
@@ -1053,7 +1060,7 @@ static unsigned long __init setup_memory* the (very unlikely) case of us accidentally initializing the * bootmem allocator with an invalid RAM area. */ -reserve_bootmem (HIGH_MEMORY , (PFN_PHYS (start_pfn) + +reserve_bootmem (HIGH_MEMORY , (PFN_PHYS (min_low_pfn) + bootmap_size +PAGE_SIZE -1 ) - (HIGH_MEMORY ));/*
@@ -1110,11 +1117,7 @@ static unsigned long __init setup_memory } }#endif -return max_low_pfn; } -#else -extern unsigned long setup_memory (void ); -#endif /* !CONFIG_DISCONTIGMEM */ /* * Request address space for all standard RAM and ROM resources
arch/i386/mm/discontig.c +4 -113
139 lines not on this page · raw message
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [Lhms-devel] [2/7] 060 refactor setup_memory i386
Quoted 4 lines · Andy Whitcroft
arch/i386/kernel/setup.c +2
-0+#ifndef CONFIG_DISCONTIGMEM +void __init setup_bootmem_allocator (void );static unsigned long __init setup_memory (void ) {
...
arch/i386/kernel/setup.c static unsigned long __init setup_memory · line 1048
Quoted 4 lines
arch/i386/kernel/setup.c +4
-0+#endif /* !CONFIG_DISCONTIGMEM */ + +void __init setup_bootmem_allocator (void ) +{
Won't this double define setup_bootmem_allocator() when CONFIG_DISCONTIGMEM is disabled? --
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [Lhms-devel] [2/7] 060 refactor setup_memory i386
Quoted 9 lines · Dave Hansen
Quoted 4 lines · Andy Whitcroft
arch/i386/kernel/setup.c +2
-0+#ifndef CONFIG_DISCONTIGMEM +void __init setup_bootmem_allocator (void );static unsigned long __init setup_memory (void ) {...
Quoted 7 lines
arch/i386/kernel/setup.c static unsigned long __init setup_memory · line 1048
Quoted 4 lines
arch/i386/kernel/setup.c +4
-0+#endif /* !CONFIG_DISCONTIGMEM */ + +void __init setup_bootmem_allocator (void ) +{Won't this double define
setup_bootmem_allocator()whenCONFIG_DISCONTIGMEMis disabled?
That is a pre-declaration. There is only one copy of setup_bootmem_allocator() which is either used 'here' in the flatmem case, or from discontig.c in the DISCONTIGMEM case. The order is backwards to minimise the overall diff; so I needed to declare it.
-apw
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [Lhms-devel] [2/7] 060 refactor setup_memory i386
Quoted 1 line · Andy Whitcroft
That is a pre-declaration. There is only one copy of
setup_bootmem_allocator()which is either used 'here' in the flatmem case, or fromdiscontig.cin the DISCONTIGMEM case. The order is backwards to minimise the overall diff; so I needed to declare it.
Ahhh, I just parsed that wrong. Silly me.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [Lhms-devel] [2/7] 060 refactor setup_memory i386
In reply to Andy WhitcroftThere's no reason not to just move setup_bootmem_allocator() above the first call to it, except for code churn. This saves a predeclaration.
---
sparsemem-dave/arch/i386/kernel/setup.c | 59 +++++++++++++++----------------- 1 files changed, 29 insertions(+), 30 deletions(-)
arch/i386/kernel/setup.c renamed from arch/i386/kernel/setup.c~2_7_060_refactor_setup_memory_i386-cleanup +29 -30
@@ -1014,36 +1014,6 @@ static void __init reserve_ebda_region(vreserve_bootmem (addr,PAGE_SIZE ); } -#ifndef CONFIG_DISCONTIGMEM -void __init setup_bootmem_allocator (void ); -static unsigned long __init setup_memory (void ) -{ -/* -* partially used pages are not usable - thus -* we are rounding upwards: -*/ - min_low_pfn =PFN_UP (init_pg_tables_end); - -find_max_pfn (); - - max_low_pfn =find_max_low_pfn (); - -#ifdef CONFIG_HIGHMEM - highstart_pfn = highend_pfn = max_pfn; -if (max_pfn > max_low_pfn) { - highstart_pfn = max_low_pfn; - } -printk (KERN_NOTICE "%ldMB HIGHMEM available.\n" , -pages_to_mb (highend_pfn - highstart_pfn)); -#endif -printk (KERN_NOTICE "%ldMB LOWMEM available.\n" , -pages_to_mb (max_low_pfn)); - -setup_bootmem_allocator (); -return max_low_pfn; -} -#endif /* !CONFIG_DISCONTIGMEM */ -void __init setup_bootmem_allocator (void ) {unsigned long bootmap_size;
@@ -1119,6 +1089,35 @@ void __init setup_bootmem_allocator(void#endif } +#ifndef CONFIG_DISCONTIGMEM +static unsigned long __init setup_memory (void ) +{ +/* +* partially used pages are not usable - thus +* we are rounding upwards: +*/ + min_low_pfn =PFN_UP (init_pg_tables_end); + +find_max_pfn (); + + max_low_pfn =find_max_low_pfn (); + +#ifdef CONFIG_HIGHMEM + highstart_pfn = highend_pfn = max_pfn; +if (max_pfn > max_low_pfn) { + highstart_pfn = max_low_pfn; + } +printk (KERN_NOTICE "%ldMB HIGHMEM available.\n" , +pages_to_mb (highend_pfn - highstart_pfn)); +#endif +printk (KERN_NOTICE "%ldMB LOWMEM available.\n" , +pages_to_mb (max_low_pfn)); + +setup_bootmem_allocator (); +return max_low_pfn; +} +#endif /* !CONFIG_DISCONTIGMEM */ +/* * Request address space for all standard RAM and ROM resources * and also for regions reported as reserved by the e820.
_
PATCH 3/7 080 alloc_remap i386
In reply to a message not in the archiveIntroduce a new allocator for the NUMA the scares remap space.
Revision: $Rev$
diffstat 080-alloc_remap-i386
--- arch/i386/mm/discontig.c | 55 ++++++++++++++++++++++++++++++++++++++++------ include/asm-i386/mmzone.h | 2 + mm/page_alloc.c | 35 ++++++++++++++++++++++++++--- 3 files changed, 83 insertions(+), 9 deletions(-)
arch/i386/mm/discontig.c +49 -6
@@ -81,6 +81,9 @@ unsigned long node_remap_offset[MAX_NUMNvoid *node_remap_start_vaddr[MAX_NUMNODES ];void set_pmd_pfn (unsigned long vaddr,unsigned long pfn,pgprot_t flags); +void *node_remap_end_vaddr[MAX_NUMNODES ]; +void *node_remap_alloc_vaddr[MAX_NUMNODES ]; +/* * FLAT - support for basic PC memory model with discontig enabled, essentially * a single node with all available processors in it with a flat
@@ -136,13 +139,36 @@ static void __init allocate_pgdat(int ni } } +void *alloc_remap (int nid,unsigned long size) +{ +void *allocation = node_remap_alloc_vaddr[nid]; + +printk (KERN_WARNING "APW: alloc_remap(%d, %08lx)\n" , nid, size); + + size =ALIGN (size,L1_CACHE_BYTES ); + +if (!allocation) +return 0 ; +if ((allocation + size) >= node_remap_end_vaddr[nid]) +return 0 ; + + node_remap_alloc_vaddr[nid] += size; + +memset (allocation,0 , size); + +printk (KERN_WARNING "APW: alloc_remap(%d, %08lx) = %p\n" , nid, size, + allocation); + +return allocation; +} +void __init remap_numa_kva (void ) {void *vaddr;unsigned long pfn;int node; -for (node =1 ; node < numnodes; ++node) { +for (node =0 ; node < numnodes; ++node) {for (pfn=0 ; pfn < node_remap_size[node]; pfn +=PTRS_PER_PTE ) { vaddr = node_remap_start_vaddr[node]+(pfn<<PAGE_SHIFT ); set_pmd_pfn((ulong) vaddr,
@@ -152,15 +178,21 @@ void __init remap_numa_kva(void) } } +/* APW/XXX: not here .. */ +unsigned long zone_bitmap_calculate (unsigned long nr_pages);static unsigned long calculate_numa_remap_pages (void ) {int nid;unsigned long size, reserve_pages =0 ; -for (nid =1 ; nid < numnodes; nid++) { +for (nid =0 ; nid < numnodes; nid++) {/* calculate the size of the mem_map needed in bytes */ size = (node_end_pfn[nid] - node_start_pfn[nid] +1 ) *sizeof (struct page ) +sizeof (pg_data_t); + +/* Allow for the bitmaps. */ + size +=zone_bitmap_calculate (node_end_pfn[nid] - node_start_pfn[nid] +1 ); +/* convert size to large (pmd size) pages, rounding up */ size = (size +LARGE_PAGE_BYTES -1 ) /LARGE_PAGE_BYTES ;/* now the roundup is correct, convert to PAGE_SIZE pages */
@@ -168,8 +200,8 @@ static unsigned long calculate_numa_remaprintk ("Reserving %ld pages of KVA for lmem_map of node %d\n" , size, nid); node_remap_size[nid] = size; - reserve_pages += size; node_remap_offset[nid] = reserve_pages; + reserve_pages += size;printk ("Shrinking node %d from %ld pages to %ld pages\n" , nid, node_end_pfn[nid], node_end_pfn[nid] - size); node_end_pfn[nid] -= size;
@@ -236,12 +268,18 @@ unsigned long __init setup_memory(void) (ulong) pfn_to_kaddr(max_low_pfn));for (nid =0 ; nid < numnodes; nid++) { node_remap_start_vaddr[nid] =pfn_to_kaddr ( - (highstart_pfn + reserve_pages) - node_remap_offset[nid]); + highstart_pfn + node_remap_offset[nid]); +/* Init the node remap allocator */ + node_remap_end_vaddr[nid] = node_remap_start_vaddr[nid] + + (node_remap_size[nid] *PAGE_SIZE ); + node_remap_alloc_vaddr[nid] = node_remap_start_vaddr[nid] + +ALIGN (sizeof (pg_data_t),PAGE_SIZE ); +allocate_pgdat (nid);printk ("node %d will remap to vaddr %08lx - %08lx\n" , nid, (ulong ) node_remap_start_vaddr[nid], - (ulong )pfn_to_kaddr (highstart_pfn + reserve_pages - - node_remap_offset[nid] + node_remap_size[nid])); + (ulong )pfn_to_kaddr (highstart_pfn + + node_remap_offset[nid] + node_remap_size[nid])); }printk ("High memory starts at vaddr %08lx\n" , (ulong )pfn_to_kaddr (highstart_pfn));
@@ -307,6 +345,10 @@ void __init zone_sizes_init(void)* normal bootmem allocator, but other nodes come from the * remapped KVA area - mbligh */ +free_area_init_node (nid,NODE_DATA (nid), + zones_size, start, zholes_size); + +#if 0 if (!nid)free_area_init_node (nid,NODE_DATA (nid), zones_size, start, zholes_size);
@@ -319,6 +361,7 @@ void __init zone_sizes_init(void)free_area_init_node (nid,NODE_DATA (nid), zones_size, start, zholes_size); } +#endif }return ; }
include/asm-i386/mmzone.h +2 -0
@@ -16,6 +16,8 @@#else /* summit or generic arch */ #include <asm/srat.h> #endif +#define HAVE_ARCH_ALLOC_REMAP 1 +#else /* !CONFIG_NUMA */ #define get_memcfg_numa get_memcfg_numa_flat#define get_zholes_size (n) (0)
mm/page_alloc.c +32 -3
@@ -94,6 +94,9 @@ static void bad_page(const char *functio page->mapping =NULL ; } +/* APW/XXX: not here. */ +void *alloc_remap (int nid,unsigned long size); +#ifndef CONFIG_HUGETLB_PAGE #define prep_compound_page (page, order) do { } while (0)#define destroy_compound_page (page, order) do { } while (0)
@@ -1442,11 +1445,23 @@ unsigned long pages_to_bitmap_size(unsigreturn bitmap_size; } +unsigned long zone_bitmap_calculate (unsigned long nr_pages) +{ +unsigned long overall_size =0 ; +int order; + +for (order =0 ; order <MAX_ORDER -1 ; order++) + overall_size +=pages_to_bitmap_size (order, nr_pages); + +return overall_size; +} +void zone_init_free_lists (struct pglist_data *pgdat,struct zone *zone,unsigned long size) {int order;for (order =0 ; ; order++) {unsigned long bitmap_size; +unsigned long *map;INIT_LIST_HEAD (&zone->free_area[order].free_list);if (order ==MAX_ORDER -1 ) {
@@ -1455,8 +1470,15 @@ void zone_init_free_lists(struct pglist_ } bitmap_size =pages_to_bitmap_size (order, size); - zone->free_area[order].map = - (unsigned long *)alloc_bootmem_node (pgdat, bitmap_size); + +#ifdef HAVE_ARCH_ALLOC_REMAP + map = (unsigned long *)alloc_remap (pgdat->node_id, + bitmap_size); + if (!map) +#endif + map = (unsigned long *)alloc_bootmem_node (pgdat, + bitmap_size); + zone->free_area[order].map = map; } }
@@ -1581,9 +1603,16 @@ static void __init free_area_init_core(svoid __init node_alloc_mem_map (struct pglist_data *pgdat) {unsigned long size; +void *map; size = (pgdat->node_spanned_pages +1 ) *sizeof (struct page ); - pgdat->node_mem_map =alloc_bootmem_node (pgdat, size); + +#ifdef HAVE_ARCH_ALLOC_REMAP + map = (unsigned long *)alloc_remap (pgdat->node_id, size); + if (!map) +#endif + map =alloc_bootmem_node (pgdat, size); + pgdat->node_mem_map = map;#ifndef CONFIG_DISCONTIGMEM mem_map = contig_page_data.node_mem_map;#endif
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [3/7] 080 alloc_remap i386
Removes whitespace damage.
---
sparsemem-dave/arch/i386/mm/discontig.c | 2 +- sparsemem-dave/mm/page_alloc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
arch/i386/mm/discontig.c renamed from arch/i386/mm/discontig.c~3_7_080_alloc_remap_i386-whitespace +1 -1
@@ -278,7 +278,7 @@ unsigned long __init setup_memory(void)allocate_pgdat (nid);printk ("node %d will remap to vaddr %08lx - %08lx\n" , nid, (ulong ) node_remap_start_vaddr[nid], - (ulong )pfn_to_kaddr (highstart_pfn + (ulong )pfn_to_kaddr (highstart_pfn + node_remap_offset[nid] + node_remap_size[nid])); } printk("High memory starts at vaddr %08lx\n",
diff -puN include/asm-i386/mmzone.h~3_7_080_alloc_remap_i386-whitespace include/asm-i386/mmzone.h
mm/page_alloc.c renamed from mm/page_alloc.c~3_7_080_alloc_remap_i386-whitespace +1 -1
@@ -1474,7 +1474,7 @@ void zone_init_free_lists(struct pglist_#ifdef HAVE_ARCH_ALLOC_REMAP map = (unsigned long *)alloc_remap (pgdat->node_id, bitmap_size); - if (!map) + if (!map)#endif map = (unsigned long *)alloc_bootmem_node (pgdat, bitmap_size);
_
Re: [3/7] 080 alloc_remap i386
In reply to Andy WhitcroftThis should get rid of the #ifdefs surround the alloc_remap() calls. Compiles on non-discontig i386.
---
sparsemem-dave/include/linux/bootmem.h | 9 +++++++++ 1 files changed, 9 insertions(+)
diff -puN arch/i386/mm/discontig.c~3_7_080_alloc_remap_i386-removeifdefs arch/i386/mm/discontig.c diff -puN include/asm-i386/mmzone.h~3_7_080_alloc_remap_i386-removeifdefs include/asm-i386/mmzone.h diff -puN mm/page_alloc.c~3_7_080_alloc_remap_i386-removeifdefs mm/page_alloc.c diff -puN include/linux/mmzone.h~3_7_080_alloc_remap_i386-removeifdefs include/linux/mmzone.h diff -L linux/bootmem.h -puN /dev/null /dev/null
include/linux/bootmem.h renamed from include/linux/bootmem.h~3_7_080_alloc_remap_i386-removeifdefs +9 -0
@@ -67,6 +67,15 @@ extern void * __init __alloc_bootmem_nod __alloc_bootmem_node((pgdat), (x), PAGE_SIZE, 0)#endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */ +#ifdef HAVE_ARCH_ALLOC_REMAP +extern void *alloc_remap (int nid,unsigned long size); +#else +static inline void *alloc_remap (int nid,unsigned long size) +{ +return NULL ; +} +#endif +extern unsigned long __initdata nr_kernel_pages;extern unsigned long __initdata nr_all_pages;
_
PATCH 4/7 100 cleanup node zone
In reply to a message not in the archivediffstat 100-cleanup-node-zone
--- mm.h | 43 ++++++++++++++++++++++++++++++++++++------- mmzone.h | 16 +++------------- 2 files changed, 39 insertions(+), 20 deletions(-)
include/linux/mm.h +36 -7
@@ -376,16 +376,41 @@ static inline void put_page(struct page* We'll have up to (MAX_NUMNODES * MAX_NR_ZONES) zones total, * so we use (MAX_NODES_SHIFT + MAX_ZONES_SHIFT) here to get enough bits. */ -#define NODEZONE_SHIFT (sizeof(page_flags_t)*8 - MAX_NODES_SHIFT - MAX_ZONES_SHIFT) -#define NODEZONE (node, zone) ((node << ZONES_SHIFT) | zone) + +#define FLAGS_SHIFT (sizeof(page_flags_t)*8) + +/* 32bit: NODE:ZONE */ +#define PGFLAGS_NODES_SHIFT (FLAGS_SHIFT - NODES_SHIFT) +#define PGFLAGS_ZONES_SHIFT (PGFLAGS_NODES_SHIFT - ZONES_SHIFT) + +#define ZONETABLE_SHIFT (NODES_SHIFT + ZONES_SHIFT) +#define PGFLAGS_ZONETABLE_SHIFT (FLAGS_SHIFT - ZONETABLE_SHIFT) + +#if NODES_SHIFT +ZONES_SHIFT >FLAGS_TOTAL_SHIFT +#error NODES_SHIFT+ZONES_SHIFT > FLAGS_TOTAL_SHIFT +#endif + +#define NODEZONE (node, zone) ((node << ZONES_SHIFT) | zone) + +#define ZONES_MASK (~((~0UL) << ZONES_SHIFT)) +#define NODES_MASK (~((~0UL) << NODES_SHIFT)) +#define ZONETABLE_MASK (~((~0UL) << ZONETABLE_SHIFT)) + +#define PGFLAGS_MASK (~((~0UL) << PGFLAGS_ZONETABLE_SHIFT)static inline unsigned long page_zonenum (struct page *page) { -return (page->flags >>NODEZONE_SHIFT ) & (~(~0UL <<ZONES_SHIFT )); +if (FLAGS_SHIFT == (PGFLAGS_ZONES_SHIFT +ZONES_SHIFT )) +return (page->flags >>PGFLAGS_ZONES_SHIFT ); +else +return (page->flags >>PGFLAGS_ZONES_SHIFT ) &ZONES_MASK ; }static inline unsigned long page_to_nid (struct page *page) { -return (page->flags >> (NODEZONE_SHIFT +ZONES_SHIFT )); +if (FLAGS_SHIFT == (PGFLAGS_NODES_SHIFT +NODES_SHIFT )) +return (page->flags >>PGFLAGS_NODES_SHIFT ); +else +return (page->flags >>PGFLAGS_NODES_SHIFT ) &NODES_MASK ; }struct zone ;
@@ -393,13 +418,17 @@ extern struct zone *zone_table[];static inline struct zone *page_zone (struct page *page) { -return zone_table[page->flags >>NODEZONE_SHIFT ]; +if (FLAGS_SHIFT == (PGFLAGS_ZONETABLE_SHIFT +ZONETABLE_SHIFT )) +return zone_table[page->flags >>PGFLAGS_ZONETABLE_SHIFT ]; +else +return zone_table[page->flags >>PGFLAGS_ZONETABLE_SHIFT & +ZONETABLE_MASK ]; }static inline void set_page_zone (struct page *page,unsigned long nodezone_num) { - page->flags &= ~(~0UL <<NODEZONE_SHIFT ); - page->flags |= nodezone_num <<NODEZONE_SHIFT ; + page->flags &=PGFLAGS_MASK ; + page->flags |= nodezone_num <<PGFLAGS_ZONETABLE_SHIFT ; }#ifndef CONFIG_DISCONTIGMEM
include/linux/mmzone.h +3 -13
@@ -389,27 +389,17 @@ extern struct pglist_data contig_page_da* with 32 bit page->flags field, we reserve 8 bits for node/zone info. * there are 3 zones (2 bits) and this leaves 8-2=6 bits for nodes. */ -#define MAX_NODES_SHIFT 6 +#define FLAGS_TOTAL_SHIFT 8 +#elif BITS_PER_LONG ==64 /* * with 64 bit flags field, there's plenty of room. */ -#define MAX_NODES_SHIFT 10 +#define FLAGS_TOTAL_SHIFT 12#endif #endif /* !CONFIG_DISCONTIGMEM */ -#if NODES_SHIFT >MAX_NODES_SHIFT -#error NODES_SHIFT > MAX_NODES_SHIFT -#endif - -/* There are currently 3 zones: DMA, Normal & Highmem, thus we need 2 bits */ -#define MAX_ZONES_SHIFT 2 - -#if ZONES_SHIFT >MAX_ZONES_SHIFT -#error ZONES_SHIFT > MAX_ZONES_SHIFT -#endif - extern DECLARE_BITMAP(node_online_map, MAX_NUMNODES);#if defined(CONFIG_DISCONTIGMEM ) || defined(CONFIG_NUMA )
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 5/7 150 sparsemem
In reply to a message not in the archiveCONFIG_NONLINEAR memory model.
Revision: $Rev$
diffstat 150-sparsemem
--- include/linux/mm.h | 103 +++++++++++++++++++++++++++++++++--- include/linux/mmzone.h | 140 +++++++++++++++++++++++++++++++++++++++++++++++-- include/linux/numa.h | 2 init/main.c | 1 mm/Makefile | 2 mm/bootmem.c | 15 ++++- mm/memory.c | 2 mm/page_alloc.c | 87 +++++++++++++++++++++++++++++- mm/sparse.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 469 insertions(+), 20 deletions(-)
include/linux/mm.h +95 -8
@@ -379,24 +379,76 @@ static inline void put_page(struct page#define FLAGS_SHIFT (sizeof(page_flags_t)*8) -/* 32bit: NODE:ZONE */ +/* +* CONFIG_SPARSEMEM: +* If there is room for SECTIONS, NODES AND ZONES then: +* NODE:ZONE:SECTION +* else: +* SECTION:ZONE +* +* Otherwise: +* NODE:ZONE +*/ +#ifdef CONFIG_SPARSEMEM + +#if FLAGS_TOTAL_SHIFT >=SECTIONS_SHIFT +NODES_SHIFT +ZONES_SHIFT + +/* NODE:ZONE:SECTION */ #define PGFLAGS_NODES_SHIFT (FLAGS_SHIFT - NODES_SHIFT)#define PGFLAGS_ZONES_SHIFT (PGFLAGS_NODES_SHIFT - ZONES_SHIFT) +#define PGFLAGS_SECTIONS_SHIFT (PGFLAGS_ZONES_SHIFT - SECTIONS_SHIFT) + +#define FLAGS_USED_SHIFT (NODES_SHIFT + ZONES_SHIFT + SECTIONS_SHIFT)#define ZONETABLE_SHIFT (NODES_SHIFT + ZONES_SHIFT)#define PGFLAGS_ZONETABLE_SHIFT (FLAGS_SHIFT - ZONETABLE_SHIFT) -#if NODES_SHIFT +ZONES_SHIFT >FLAGS_TOTAL_SHIFT -#error NODES_SHIFT+ZONES_SHIFT > FLAGS_TOTAL_SHIFT +#define ZONETABLE (section, node, zone) \ + ((node << ZONES_SHIFT) | zone) + +#else + +/* SECTION:ZONE */ +#define PGFLAGS_SECTIONS_SHIFT (FLAGS_SHIFT - SECTIONS_SHIFT) +#define PGFLAGS_ZONES_SHIFT (PGFLAGS_SECTIONS_SHIFT - ZONES_SHIFT) + +#define FLAGS_USED_SHIFT (SECTIONS_SHIFT + ZONES_SHIFT) + +#define ZONETABLE_SHIFT (SECTIONS_SHIFT + ZONES_SHIFT) +#define PGFLAGS_ZONETABLE_SHIFT (FLAGS_SHIFT - ZONETABLE_SHIFT) + +#define ZONETABLE (section, node, zone) \ + ((section << ZONES_SHIFT) | zone) + +#endif + +#else /* !CONFIG_SPARSEMEM */ + +/* NODE:ZONE */ +#define PGFLAGS_NODES_SHIFT (FLAGS_SHIFT - NODES_SHIFT) +#define PGFLAGS_ZONES_SHIFT (PGFLAGS_NODES_SHIFT - ZONES_SHIFT) + +#define ZONETABLE_SHIFT (NODES_SHIFT + ZONES_SHIFT) +#define PGFLAGS_ZONETABLE_SHIFT (FLAGS_SHIFT - ZONETABLE_SHIFT) + +#define FLAGS_USED_SHIFT (NODES_SHIFT + ZONES_SHIFT) + +#endif /* !CONFIG_SPARSEMEM */ + +#if FLAGS_USED_SHIFT >FLAGS_TOTAL_SHIFT +#error SECTIONS_SHIFT+NODES_SHIFT+ZONES_SHIFT > FLAGS_TOTAL_SHIFT#endif #define NODEZONE (node, zone) ((node << ZONES_SHIFT) | zone)#define ZONES_MASK (~((~0UL) << ZONES_SHIFT))#define NODES_MASK (~((~0UL) << NODES_SHIFT)) +#define SECTIONS_MASK (~((~0UL) << SECTIONS_SHIFT))#define ZONETABLE_MASK (~((~0UL) << ZONETABLE_SHIFT)) -#define PGFLAGS_MASK (~((~0UL) << PGFLAGS_ZONETABLE_SHIFT) +#define ZONETABLE_SIZE (1 << ZONETABLE_SHIFT) + +#define PGFLAGS_MASK (~((~0UL) << PGFLAGS_ZONETABLE_SHIFT))static inline unsigned long page_zonenum (struct page *page) {
@@ -405,13 +457,34 @@ static inline unsigned long page_zonenumelse return (page->flags >>PGFLAGS_ZONES_SHIFT ) &ZONES_MASK ; } +#ifdef PGFLAGS_NODES_SHIFT static inline unsigned long page_to_nid (struct page *page) { +#if NODES_SHIFT ==0 +return 0 ; +#else if (FLAGS_SHIFT == (PGFLAGS_NODES_SHIFT +NODES_SHIFT ))return (page->flags >>PGFLAGS_NODES_SHIFT );else return (page->flags >>PGFLAGS_NODES_SHIFT ) &NODES_MASK ; +#endif } +#else +static inline struct zone *page_zone (struct page *page); +static inline unsigned long page_to_nid (struct page *page) +{ +return page_zone (page)->zone_pgdat->node_id; +} +#endif +#ifdef PGFLAGS_SECTIONS_SHIFT +static inline unsigned long page_to_section (struct page *page) +{ +if (FLAGS_SHIFT == (PGFLAGS_SECTIONS_SHIFT +SECTIONS_SHIFT )) +return (page->flags >>PGFLAGS_SECTIONS_SHIFT ); +else +return (page->flags >>PGFLAGS_SECTIONS_SHIFT ) &SECTIONS_MASK ; +} +#endif struct zone ;extern struct zone *zone_table[];
@@ -425,13 +498,27 @@ static inline struct zone *page_zone(str ZONETABLE_MASK]; } -static inline void set_page_zone (struct page *page,unsigned long nodezone_num) +static inline void set_page_zone (struct page *page,unsigned long zone) +{ + page->flags &= ~(ZONES_MASK <<PGFLAGS_ZONES_SHIFT ); + page->flags |= zone <<PGFLAGS_ZONES_SHIFT ; +} +static inline void set_page_node (struct page *page,unsigned long node) { - page->flags &=PGFLAGS_MASK ; - page->flags |= nodezone_num <<PGFLAGS_ZONETABLE_SHIFT ; +#if defined(PGFLAGS_NODES_SHIFT ) &&NODES_SHIFT !=0 + page->flags &= ~(NODES_MASK <<PGFLAGS_NODES_SHIFT ); + page->flags |= node <<PGFLAGS_NODES_SHIFT ; +#endif +} +static inline void set_page_section (struct page *page,unsigned long section) +{ +#ifdef PGFLAGS_SECTIONS_SHIFT + page->flags &= ~(SECTIONS_MASK <<PGFLAGS_SECTIONS_SHIFT ); + page->flags |= section <<PGFLAGS_SECTIONS_SHIFT ; +#endif } -#ifndef CONFIG_DISCONTIGMEM +#ifdef CONFIG_FLATMEM /* The array of struct pages - for discontigmem use pgdat->lmem_map */ extern struct page *mem_map;#endif
include/linux/mmzone.h +136 -4
165 lines not on this page · raw message
include/linux/numa.h +1 -1
@@ -3,7 +3,7 @@#include <linux/config.h> -#ifdef CONFIG_DISCONTIGMEM +#ifndef CONFIG_FLATMEM #include <asm/numnodes.h> #endif
init/main.c +1 -0
@@ -480,6 +480,7 @@ asmlinkage void __init start_kernel(void {char * command_line;extern struct kernel_param __start___param[], __stop___param[]; +/* * Interrupts are still disabled. Do necessary setups, then * enable them
mm/bootmem.c +14 -1
@@ -255,6 +255,7 @@ found:static unsigned long __init free_all_bootmem_core (pg_data_t *pgdat) {struct page *page; +unsigned long pfn;bootmem_data_t *bdata = pgdat->bdata;unsigned long i, count, total =0 ;unsigned long idx;
@@ -265,15 +266,26 @@ static unsigned long __init free_all_boo count =0 ;/* first extant page of the node */ - page =virt_to_page (phys_to_virt (bdata->node_boot_start)); + pfn = bdata->node_boot_start >>PAGE_SHIFT ; idx = bdata->node_low_pfn - (bdata->node_boot_start >>PAGE_SHIFT ); map = bdata->node_bootmem_map;/* Check physaddr is O(LOG2(BITS_PER_LONG)) page aligned */ if (bdata->node_boot_start ==0 ||ffs (bdata->node_boot_start) -PAGE_SHIFT >ffs (BITS_PER_LONG )) gofast =1 ; + page =pfn_to_page (pfn);for (i =0 ; i < idx; ) {unsigned long v = ~map[i /BITS_PER_LONG ]; + +/* +* Makes use of the guarentee that *_mem_map will be +* contigious in sections aligned at MAX_ORDER. +* APW/XXX: we are making an assumption that our node_boot_start +* is aligned to BITS_PER_LONG ... is this valid/enforced. +*/ +if ((pfn & ((1 <<MAX_ORDER ) -1 )) ==0 ) + page =pfn_to_page (pfn); +if (gofast && v == ~0UL ) {int j;
@@ -302,6 +314,7 @@ static unsigned long __init free_all_boo i+=BITS_PER_LONG ; page +=BITS_PER_LONG ; } + pfn +=BITS_PER_LONG ; } total += count;
mm/Makefile +1 -1
@@ -15,6 +15,6 @@ obj-y := bootmem.o filemap.o mempool.o obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o thrash.o obj-$(CONFIG_HUGETLBFS) += hugetlb.o obj-$(CONFIG_NUMA) += mempolicy.o +obj-$(CONFIG_SPARSEMEM) += sparse.o obj-$(CONFIG_SHMEM) += shmem.o obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o -
mm/memory.c +1 -1
@@ -56,7 +56,7 @@#include <linux/swapops.h> #include <linux/elf.h> -#ifndef CONFIG_DISCONTIGMEM +#ifdef CONFIG_FLATMEM /* use the per-pgdat data instead for discontigmem - mbligh */ unsigned long max_mapnr;struct page *mem_map;
mm/sparse.c +137 -0
137 lines not on this page · raw message
mm/page_alloc.c +83 -4
163 lines not on this page · raw message
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 6/7 160 sparsemem i386
In reply to a message not in the archiveCONFIG_NONLINEAR for i386
Revision: $Rev$
diffstat 160-sparsemem-i386
--- arch/i386/Kconfig | 22 ++++++-- arch/i386/kernel/numaq.c | 5 + arch/i386/kernel/setup.c | 7 +- arch/i386/kernel/srat.c | 5 + arch/i386/mm/Makefile | 2 arch/i386/mm/discontig.c | 97 ++++++++++++++++++++++--------------- arch/i386/mm/init.c | 19 ++++--- include/asm-i386/mmzone.h | 115 ++++++++++++++++++++++++++++++++++----------- include/asm-i386/page.h | 4 - include/asm-i386/pgtable.h | 4 - 10 files changed, 193 insertions(+), 87 deletions(-)
arch/i386/Kconfig +17 -5
@@ -68,7 +68,7 @@ config X86_VOYAGER config X86_NUMAQ bool "NUMAQ (IBM/Sequent)" - select DISCONTIGMEM + #select DISCONTIGMEM select NUMA help This option is used for getting Linux to run on a (IBM/Sequent) NUMA
@@ -738,16 +738,28 @@ comment "NUMA (NUMA-Q) requires SMP, 64G comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI" depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI) -config DISCONTIGMEM - bool - depends on NUMA - default y config HAVE_ARCH_BOOTMEM_NODE bool depends on NUMA default y +choice + prompt "Memory model" + default SPARSEMEM if (X86_NUMAQ || X86_SUMMIT) + default FLATMEM + +config DISCONTIGMEM + bool "Discontigious Memory" + +config SPARSEMEM + bool "Sparse Memory" + +config FLATMEM + bool "Flat Memory" + +endchoice + config HIGHPTE bool "Allocate 3rd-level pagetables from highmem" depends on HIGHMEM4G || HIGHMEM64G
arch/i386/kernel/numaq.c +5 -0
@@ -60,6 +60,11 @@ static void __init smp_dump_qct(void) eq->hi_shrd_mem_start - eq->priv_mem_size); node_end_pfn[node] =MB_TO_PAGES ( eq->hi_shrd_mem_start + eq->hi_shrd_mem_size); +#ifdef CONFIG_SPARSEMEM +sparse_add (node, node_start_pfn[node], + node_end_pfn[node]); +#endif + } } }
arch/i386/kernel/setup.c +5 -2
@@ -39,6 +39,7 @@#include <linux/efi.h> #include <linux/init.h> #include <linux/edd.h> +#include <linux/mmzone.h> #include <video/edid.h> #include <asm/e820.h> #include <asm/mpspec.h>
@@ -1014,7 +1015,7 @@ static void __init reserve_ebda_region(vreserve_bootmem (addr,PAGE_SIZE ); } -#ifndef CONFIG_DISCONTIGMEM +#ifdef CONFIG_FLATMEM void __init setup_bootmem_allocator (void );static unsigned long __init setup_memory (void ) {
@@ -1042,7 +1043,9 @@ static unsigned long __init setup_memorysetup_bootmem_allocator (); return max_low_pfn; } -#endif /* !CONFIG_DISCONTIGMEM */ +#else +unsigned long __init setup_memory (void ); +#endif /* CONFIG_FLATMEM */ void __init setup_bootmem_allocator (void ) {
arch/i386/kernel/srat.c +5 -0
@@ -261,6 +261,11 @@ static int __init acpi20_parse_srat(stru j, node_memory_chunk[j].nid, node_memory_chunk[j].start_pfn, node_memory_chunk[j].end_pfn); +#ifdef CONFIG_SPARSEMEM +sparse_add (node_memory_chunk[j].nid, + node_memory_chunk[j].start_pfn, + node_memory_chunk[j].end_pfn); +#endif /* CONFIG_SPARSEMEM */ }/*calculate node_start_pfn/node_end_pfn arrays*/
arch/i386/mm/discontig.c +57 -40
165 lines not on this page · raw message
arch/i386/mm/init.c +11 -8
@@ -274,7 +274,7 @@ void __init one_highpage_init(struct pagSetPageReserved (page); } -#ifndef CONFIG_DISCONTIGMEM +#ifdef CONFIG_FLATMEM void __init set_highmem_pages_init (int bad_ppro) {int pfn;
@@ -284,7 +284,7 @@ void __init set_highmem_pages_init(int b }#else extern void set_highmem_pages_init (int ); -#endif /* !CONFIG_DISCONTIGMEM */ +#endif /* CONFIG_FLATMEM */ #else #define kmap_init () do { } while (0)
@@ -295,7 +295,7 @@ extern void set_highmem_pages_init(int);unsigned long long __PAGE_KERNEL = _PAGE_KERNEL;unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC; -#ifndef CONFIG_DISCONTIGMEM +#ifdef CONFIG_FLATMEM #define remap_numa_kva () do {} while (0)#else extern void __init remap_numa_kva (void );
@@ -388,7 +388,7 @@ void zap_low_mappings (void)flush_tlb_all (); } -#ifndef CONFIG_DISCONTIGMEM +#ifdef CONFIG_FLATMEM void __init zone_sizes_init (void ) {unsigned long zones_size[MAX_NR_ZONES ] = {0 ,0 ,0 };
@@ -411,7 +411,7 @@ void __init zone_sizes_init(void) }#else extern void zone_sizes_init (void ); -#endif /* !CONFIG_DISCONTIGMEM */ +#endif /* CONFIG_FLATMEM */ static int disable_nx__initdata =0 ;u64 __supported_pte_mask = ~_PAGE_NX;
@@ -516,6 +516,9 @@ void __init paging_init(void)__flush_tlb_all ();kmap_init (); +#ifdef CONFIG_SPARSEMEM +sparse_allocate (); +#endif zone_sizes_init (); }
@@ -545,7 +548,7 @@ void __init test_wp_bit(void) } } -#ifndef CONFIG_DISCONTIGMEM +#ifdef CONFIG_FLATMEM static void __init set_max_mapnr_init (void ) {#ifdef CONFIG_HIGHMEM
@@ -559,7 +562,7 @@ static void __init set_max_mapnr_init(vo#else #define __free_all_bootmem () free_all_bootmem_node(NODE_DATA(0))extern void set_max_mapnr_init (void ); -#endif /* !CONFIG_DISCONTIGMEM */ +#endif /* CONFIG_FLATMEM */ static struct kcore_list kcore_mem, kcore_vmalloc;
@@ -570,7 +573,7 @@ void __init mem_init(void)int tmp;int bad_ppro; -#ifndef CONFIG_DISCONTIGMEM +#ifdef CONFIG_FLATMEM if (!mem_map)BUG ();#endif
arch/i386/mm/Makefile +1 -1
@@ -4,7 +4,7 @@ obj-y := init.o pgtable.o fault.o ioremap.o extable.o pageattr.o mmap.o -obj-$(CONFIG_DISCONTIGMEM) += discontig.o +obj-$(CONFIG_NUMA) += discontig.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_HIGHMEM) += highmem.o obj-$(CONFIG_BOOT_IOREMAP) += boot_ioremap.o
include/asm-i386/mmzone.h +88 -27
149 lines not on this page · raw message
include/asm-i386/page.h +2 -2
@@ -133,11 +133,11 @@ extern int sysctl_legacy_va_layout;#define __pa (x) ((unsigned long)(x)-PAGE_OFFSET)#define __va (x) ((void *)((unsigned long)(x)+PAGE_OFFSET))#define pfn_to_kaddr (pfn) __va((pfn) << PAGE_SHIFT) -#ifndef CONFIG_DISCONTIGMEM +#ifdef CONFIG_FLATMEM #define pfn_to_page (pfn) (mem_map + (pfn))#define page_to_pfn (page) ((unsigned long)((page) - mem_map))#define pfn_valid (pfn) ((pfn) < max_mapnr) -#endif /* !CONFIG_DISCONTIGMEM */ +#endif /* CONFIG_FLATMEM */ #define virt_to_page (kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)#define virt_addr_valid (kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
include/asm-i386/pgtable.h +2 -2
@@ -400,9 +400,9 @@ extern pte_t *lookup_address(unsigned lo#endif /* !__ASSEMBLY__ */ -#ifndef CONFIG_DISCONTIGMEM +#ifdef CONFIG_FLATMEM #define kern_addr_valid (addr) (1) -#endif /* !CONFIG_DISCONTIGMEM */ +#endif /* CONFIG_FLATMEM */ #define io_remap_page_range remap_page_range
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 7/7 170 sparsemem ppc64
In reply to a message not in the archiveCONFIG_NONLINEAR for ppc64.
Revision: $Rev$
diffstat 170-sparsemem-ppc64
--- arch/ppc64/Kconfig | 19 +++++++++++++++++-- arch/ppc64/mm/Makefile | 2 +- arch/ppc64/mm/init.c | 8 ++++---- arch/ppc64/mm/numa.c | 13 +++++++++++++ include/asm-ppc64/mmzone.h | 40 ++++++++++++++++++++++++++++++++++------ include/asm-ppc64/page.h | 4 +++- 6 files changed, 72 insertions(+), 14 deletions(-)
arch/ppc64/Kconfig +17 -2
@@ -180,13 +180,28 @@ config HMT bool "Hardware multithreading" depends on SMP && PPC_PSERIES + +choice + prompt "Memory model" + default SPARSEMEM if (PPC_PSERIES) + default FLATMEM + config DISCONTIGMEM - bool "Discontiguous Memory Support" + bool "Discontigious Memory" + depends on SMP && PPC_PSERIES + +config SPARSEMEM + bool "Nonlinear Memory" depends on SMP && PPC_PSERIES +config FLATMEM + bool "Flat Memory" + +endchoice + config NUMA bool "NUMA support" - depends on DISCONTIGMEM + #depends on DISCONTIGMEM config SCHED_SMT bool "SMT (Hyperthreading) scheduler support"
arch/ppc64/mm/init.c +4 -4
@@ -597,7 +597,7 @@ EXPORT_SYMBOL(page_is_ram);* Initialize the bootmem system and give it all the memory we * have available. */ -#ifndef CONFIG_DISCONTIGMEM +#ifdef CONFIG_FLATMEM void __init do_init_bootmem (void ) {unsigned long i;
@@ -695,7 +695,7 @@ module_init(setup_kcore);void __init mem_init (void ) { -#ifdef CONFIG_DISCONTIGMEM +#if defined(CONFIG_DISCONTIGMEM ) || defined(CONFIG_SPARSEMEM )int nid;#endif pg_data_t *pgdat;
@@ -706,7 +706,7 @@ void __init mem_init(void) num_physpages = max_low_pfn;/* RAM is assumed contiguous */ high_memory = (void *)__va (max_low_pfn *PAGE_SIZE ); -#ifdef CONFIG_DISCONTIGMEM +#if defined(CONFIG_DISCONTIGMEM ) || defined(CONFIG_SPARSEMEM )for (nid =0 ; nid < numnodes; nid++) {if (NODE_DATA (nid)->node_spanned_pages !=0 ) {printk ("freeing bootmem node %x\n" , nid);
@@ -721,7 +721,7 @@ void __init mem_init(void)for_each_pgdat (pgdat) {for (i =0 ; i < pgdat->node_spanned_pages; i++) { - page = pgdat->node_mem_map + i; + page =pfn_to_page (i);if (PageReserved (page)) reservedpages++; }
arch/ppc64/mm/Makefile +1 -1
@@ -6,6 +6,6 @@ EXTRA_CFLAGS += -mno-minimal-toc obj-y := fault.o init.o imalloc.o hash_utils.o hash_low.o tlb.o \ slb_low.o slb.o stab.o mmap.o -obj-$(CONFIG_DISCONTIGMEM) += numa.o +obj-$(CONFIG_NUMA) += numa.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_PPC_MULTIPLATFORM) += hash_native.o
arch/ppc64/mm/numa.c +13 -0
@@ -304,9 +304,13 @@ new_range: size /PAGE_SIZE ; } +/* XXX: think this is discontig ... */ for (i = start ; i < (start+size); i +=MEMORY_INCREMENT ) numa_memory_lookup_table[i >>MEMORY_INCREMENT_SHIFT ] = numa_domain; +#ifdef CONFIG_SPARSEMEM +sparse_add (numa_domain, start, start + size); +#endif ranges--;if (ranges)
@@ -346,10 +350,15 @@ static void __init setup_nonnuma(void) init_node_data[0 ].node_start_pfn =0 ; init_node_data[0 ].node_spanned_pages =lmb_end_of_DRAM () /PAGE_SIZE ; +/* APW: this is discontig? */ for (i =0 ; i < top_of_ram; i +=MEMORY_INCREMENT ) numa_memory_lookup_table[i >>MEMORY_INCREMENT_SHIFT ] =0 ; node0_io_hole_size = top_of_ram - total_ram; + +#ifdef CONFIG_SPARSEMEM +sparse_add (0 ,0 , init_node_data[0 ].node_spanned_pages); +#endif }static void __init dump_numa_topology (void )
@@ -567,6 +576,10 @@ void __init paging_init(void)memset (zones_size,0 ,sizeof (zones_size));memset (zholes_size,0 ,sizeof (zholes_size)); +#ifdef CONFIG_SPARSEMEM +sparse_allocate (); +#endif +for (nid =0 ; nid < numnodes; nid++) {unsigned long start_pfn;unsigned long end_pfn;
include/asm-ppc64/mmzone.h +34 -6
@@ -10,9 +10,13 @@#include <linux/config.h> #include <asm/smp.h> -#ifdef CONFIG_DISCONTIGMEM +#if defined(CONFIG_DISCONTIGMEM ) || defined(CONFIG_SPARSEMEM )extern struct pglist_data *node_data[]; +/* +* Return a pointer to the node data for node n. +*/ +#define NODE_DATA (nid) (node_data[nid])/* * Following are specific to this numa platform.
@@ -27,6 +31,10 @@ extern int nr_cpus_in_node[];#define MEMORY_INCREMENT_SHIFT 24#define MEMORY_INCREMENT (1UL << MEMORY_INCREMENT_SHIFT) +#endif /* !CONFIG_DISCONTIGMEM || !CONFIG_SPARSEMEM */ + +#ifdef CONFIG_DISCONTIGMEM +/* NUMA debugging, will not work on a DLPAR machine */ #undef DEBUG_NUMA
@@ -49,11 +57,6 @@ static inline int pa_to_nid(unsigned lon#define pfn_to_nid (pfn) pa_to_nid((pfn) << PAGE_SHIFT) -/* -* Return a pointer to the node data for node n. -*/ -#define NODE_DATA (nid) (node_data[nid]) -#define node_localnr (pfn, nid) ((pfn) - NODE_DATA(nid)->node_start_pfn)/*
@@ -91,4 +94,29 @@ static inline int pa_to_nid(unsigned lon#define discontigmem_pfn_valid (pfn) ((pfn) < num_physpages)#endif /* CONFIG_DISCONTIGMEM */ + +#ifdef CONFIG_SPARSEMEM + +/* generic non-linear memory support: +* +* 1) we will not split memory into more chunks than will fit into the +* flags field of the struct page +*/ + +/* +* SECTION_SIZE_BITS 2^N: how big each section will be +* MAX_PHYSADDR_BITS 2^N: how much physical address space we have +* MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space +*/ +#define SECTION_SIZE_BITS 24 +#define MAX_PHYSADDR_BITS 38 +#define MAX_PHYSMEM_BITS 36 + +#define pa_to_nid (pa) \ +({ \ + pfn_to_nid(pa >> PAGE_SHIFT); \ +}) + +#endif /* CONFIG_SPARSEMEM */ +#endif /* _ASM_MMZONE_H_ */
include/asm-ppc64/page.h +3 -1
@@ -222,7 +222,9 @@ extern int page_is_ram(unsigned long pfn#define page_to_pfn (page) discontigmem_page_to_pfn(page)#define pfn_to_page (pfn) discontigmem_pfn_to_page(pfn)#define pfn_valid (pfn) discontigmem_pfn_valid(pfn) -#else +#endif +/* XXX/APW: why is SPARSEMEM not here */ +#ifdef CONFIG_FLATMEM #define pfn_to_page (pfn) (mem_map + (pfn))#define page_to_pfn (page) ((unsigned long)((page) - mem_map))#define pfn_valid (pfn) ((pfn) < max_mapnr)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>