Skip to content

Commit

Permalink
[PATCH] add x86-64 specific support for sparsemem
Browse files Browse the repository at this point in the history
This patch adds in the necessary support for sparsemem such that x86-64
kernels may use sparsemem as an alternative to discontigmem for NUMA
kernels.  Note that this does no preclude one from continuing to build NUMA
kernels using discontigmem, but merely allows the option to build NUMA
kernels with sparsemem.

Interestingly, the use of sparsemem in lieu of discontigmem in NUMA kernels
results in reduced text size for otherwise equivalent kernels as shown in
the example builds below:

   text	   data	    bss	    dec	    hex	filename
2371036	 765884	1237108	4374028	 42be0c	vmlinux.discontig
2366549	 776484	1302772	4445805	 43d66d	vmlinux.sparse

Signed-off-by: Matt Tolentino <matthew.e.tolentino@intel.com>
Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Matt Tolentino authored and Linus Torvalds committed Jun 23, 2005
1 parent 2b97690 commit bbfceef
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 12 deletions.
27 changes: 17 additions & 10 deletions arch/x86_64/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
#include <linux/acpi.h>
#include <linux/kallsyms.h>
#include <linux/edd.h>
#include <linux/mmzone.h>

#include <asm/mtrr.h>
#include <asm/uaccess.h>
#include <asm/system.h>
Expand Down Expand Up @@ -378,16 +380,19 @@ static __init void parse_cmdline_early (char ** cmdline_p)
}

#ifndef CONFIG_NUMA
static void __init contig_initmem_init(void)
static void __init
contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
{
unsigned long bootmap_size, bootmap;
bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;
bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size);
if (bootmap == -1L)
panic("Cannot find bootmem map of size %ld\n",bootmap_size);
bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
e820_bootmem_free(NODE_DATA(0), 0, end_pfn << PAGE_SHIFT);
reserve_bootmem(bootmap, bootmap_size);
unsigned long bootmap_size, bootmap;

memory_present(0, start_pfn, end_pfn);
bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;
bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size);
if (bootmap == -1L)
panic("Cannot find bootmem map of size %ld\n",bootmap_size);
bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
e820_bootmem_free(NODE_DATA(0), 0, end_pfn << PAGE_SHIFT);
reserve_bootmem(bootmap, bootmap_size);
}
#endif

Expand Down Expand Up @@ -557,7 +562,7 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_NUMA
numa_initmem_init(0, end_pfn);
#else
contig_initmem_init();
contig_initmem_init(0, end_pfn);
#endif

/* Reserve direct mapping */
Expand Down Expand Up @@ -618,6 +623,8 @@ void __init setup_arch(char **cmdline_p)
}
}
#endif

sparse_init();
paging_init();

check_ioapic();
Expand Down
8 changes: 8 additions & 0 deletions arch/x86_64/mm/numa.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ int __init compute_hash_shift(struct node *nodes, int numnodes)
return -1;
}

#ifdef CONFIG_SPARSEMEM
int early_pfn_to_nid(unsigned long pfn)
{
return phys_to_nid(pfn << PAGE_SHIFT);
}
#endif

/* Initialize bootmem allocator for a node */
void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end)
{
Expand All @@ -80,6 +87,7 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en
start_pfn = start >> PAGE_SHIFT;
end_pfn = end >> PAGE_SHIFT;

memory_present(nodeid, start_pfn, end_pfn);
nodedata_phys = find_e820_area(start, end, pgdat_size);
if (nodedata_phys == -1L)
panic("Cannot find memory pgdat in node %d\n", nodeid);
Expand Down
2 changes: 0 additions & 2 deletions include/asm-x86_64/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,8 +411,6 @@ static __inline__ int ffs(int x)
/* find last set bit */
#define fls(x) generic_fls(x)

#define ARCH_HAS_ATOMIC_UNSIGNED 1

#endif /* __KERNEL__ */

#endif /* _X86_64_BITOPS_H */
26 changes: 26 additions & 0 deletions include/asm-x86_64/sparsemem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef _ASM_X86_64_SPARSEMEM_H
#define _ASM_X86_64_SPARSEMEM_H 1

#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: size of each section
* MAX_PHYSADDR_BITS 2^n: max size of physical address space
* MAX_PHYSMEM_BITS 2^n: how much memory we can have in that space
*
*/

#define SECTION_SIZE_BITS 27 /* matt - 128 is convenient right now */
#define MAX_PHYSADDR_BITS 40
#define MAX_PHYSMEM_BITS 40

extern int early_pfn_to_nid(unsigned long pfn);

#endif /* CONFIG_SPARSEMEM */

#endif /* _ASM_X86_64_SPARSEMEM_H */

0 comments on commit bbfceef

Please sign in to comment.