latest discontig
PATCH 1/1 latest discontig
It still needs a lot of cleanup and some bugfixes, but I'm going out on sabbatical for the next three weeks, so I thought I'd post this patch in case anyone's interested in running 2.6 on an Altix box.
You'll need to apply this patch and the headless node patch I just sent out, along with a few others that have already been merged into various trees but aren't in Linus' tree yet.
This patch is against Linus' bitkeeper tree as of a few hours ago.
Thanks,
Jesse
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas:
# ChangeSet 1.1124 -> 1.1125
# include/asm-ia64/page.h 1.19 -> 1.20
# arch/ia64/kernel/setup.c 1.55 -> 1.56
# include/asm-ia64/pgtable.h 1.28 -> 1.29
# arch/ia64/mm/Makefile 1.7 -> 1.8
# include/asm-ia64/numa.h 1.5 -> 1.6
# include/asm-ia64/processor.h 1.48 -> 1.49
# arch/ia64/mm/init.c 1.47 -> 1.48
# include/asm-ia64/nodedata.h 1.3 -> 1.4
# include/asm-ia64/percpu.h 1.12 -> 1.13
# arch/ia64/mm/discontig.c 1.4 -> 1.5
# include/asm-ia64/mmzone.h 1.4 -> 1.5
# (new) -> 1.1 arch/ia64/mm/contig.c
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/08/08 [email protected] 1.1125
# discontig # -------------------------------------------- # diff -Nru a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c --- a/arch/ia64/kernel/setup.c Fri Aug 8 14:57:24 2003 +++ b/arch/ia64/kernel/setup.c Fri Aug 8 14:57:24 2003 @@ -83,91 +83,10 @@
char saved_command_line[COMMAND_LINE_SIZE]; /* used in proc filesystem */
-/*
- * Entries defined so far:
- * - boot param structure itself
- * - memory map
- * - initrd (optional)
- * - command line string
- * - kernel code & data
- *
- * More could be added if necessary
- */
-#define IA64_MAX_RSVD_REGIONS 5
-
-struct rsvd_region {
- unsigned long start; /* virtual address of beginning of element */
- unsigned long end; /* virtual address of end of element + 1 */
-};
-
-/*
- * We use a special marker for the end of memory and it uses the extra (+1) slot
- */
-static struct rsvd_region rsvd_region[IA64_MAX_RSVD_REGIONS + 1]; -static int num_rsvd_regions;
-
#define IGNORE_PFN0 1 /* XXX fix me: ignore pfn 0 until TLB miss handler is updated... */
-#ifndef CONFIG_DISCONTIGMEM
-
-static unsigned long bootmap_start; /* physical address where the bootmem map is located */ -
-static int
-find_max_pfn (unsigned long start, unsigned long end, void *arg)
-{
- unsigned long *max_pfnp = arg, pfn;
-
- pfn = (PAGE_ALIGN(end - 1) - PAGE_OFFSET) >> PAGE_SHIFT;
- if (pfn > *max_pfnp)
- *max_pfnp = pfn;
- return 0;
-}
-
-#else /* CONFIG_DISCONTIGMEM */
-
-/*
- * efi_memmap_walk() knows nothing about layout of memory across nodes. Find
- * out to which node a block of memory belongs. Ignore memory that we cannot
- * identify, and split blocks that run across multiple nodes.
- *
- * Take this opportunity to round the start address up and the end address
- * down to page boundaries.
- */
-void
-call_pernode_memory (unsigned long start, unsigned long end, void *arg)
-{
- unsigned long rs, re;
- void (*func)(unsigned long, unsigned long, int, int);
- int i;
-
- start = PAGE_ALIGN(start);
- end &= PAGE_MASK;
- if (start >= end)
- return;
-
- func = arg;
-
- if (!num_memblks) {
- /*
- * This machine doesn't have SRAT, so call func with
- * nid=0, bank=0.
- */
- if (start < end)
- (*func)(start, end - start, 0, 0);
- return;
- }
-
- for (i = 0; i < num_memblks; i++) {
- rs = max(start, node_memblk[i].start_paddr);
- re = min(end, node_memblk[i].start_paddr+node_memblk[i].size);
-
- if (rs < re)
- (*func)(rs, re-rs, node_memblk[i].nid,
- node_memblk[i].bank);
- }
-}
-
-#endif /* CONFIG_DISCONTIGMEM */
+struct rsvd_region rsvd_region[IA64_MAX_RSVD_REGIONS + 1];
+int num_rsvd_regions;
/*
* Filter incoming memory segments based on the primitive map created from the boot
@@ -179,7 +98,7 @@
filter_rsvd_memory (unsigned long start, unsigned long end, void *arg) {
unsigned long range_start, range_end, prev_start;
- void (*func)(unsigned long, unsigned long);
+ void (*func)(unsigned long, unsigned long, int);
int i;
#if IGNORE_PFN0
@@ -201,9 +120,9 @@
if (range_start < range_end)
#ifdef CONFIG_DISCONTIGMEM
- call_pernode_memory(__pa(range_start), __pa(range_end), func);
+ call_pernode_memory(range_start, range_end, arg);
#else
- (*func)(__pa(range_start), range_end - range_start);
+ (*func)(range_start, range_end, 0);
#endif
/* nothing more available in this segment */
@@ -215,48 +134,6 @@
return 0;
}
-
-#ifndef CONFIG_DISCONTIGMEM
-/*
- * Find a place to put the bootmap and return its starting address in bootmap_start.
- * This address must be page-aligned.
- */
-static int
-find_bootmap_location (unsigned long start, unsigned long end, void *arg) -{
- unsigned long needed = *(unsigned long *)arg;
- unsigned long range_start, range_end, free_start;
- int i;
-
-#if IGNORE_PFN0
- if (start == PAGE_OFFSET) {
- start += PAGE_SIZE;
- if (start >= end) return 0;
- }
-#endif
-
- free_start = PAGE_OFFSET;
-
- for (i = 0; i < num_rsvd_regions; i++) {
- range_start = max(start, free_start);
- range_end = min(end, rsvd_region[i].start & PAGE_MASK);
-
- if (range_end <= range_start) continue; /* skip over empty range */
-
- if (range_end - range_start >= needed) {
- bootmap_start = __pa(range_start);
- return 1; /* done */
- }
-
- /* nothing more available in this segment */
- if (range_end == end) return 0;
-
- free_start = PAGE_ALIGN(rsvd_region[i].end);
- }
- return 0;
-}
-#endif /* !CONFIG_DISCONTIGMEM */
-
static void
sort_regions (struct rsvd_region *rsvd_region, int max)
{
@@ -319,12 +196,8 @@
sort_regions(rsvd_region, num_rsvd_regions);
#ifdef CONFIG_DISCONTIGMEM
- {
- extern void discontig_mem_init (void);
-
- bootmap_size = max_pfn = 0; /* stop gcc warnings */
- discontig_mem_init();
- }
+ bootmap_size = 0;
+ discontig_mem_init();
#else /* !CONFIG_DISCONTIGMEM */
/* first find highest page frame number */
@@ -372,7 +245,6 @@
strlcpy(saved_command_line, *cmdline_p, sizeof(saved_command_line));
efi_init();
- find_memory();
#ifdef CONFIG_ACPI_BOOT
/* Initialize the ACPI boot-time table parser */
@@ -386,6 +258,8 @@
# endif #endif /* CONFIG_APCI_BOOT */
+ find_memory();
+
/* process SAL system table: */
ia64_sal_init(efi.sal_systab);
@@ -677,28 +551,7 @@
struct cpuinfo_ia64 *cpu_info;
void *cpu_data;
-#ifdef CONFIG_SMP
- int cpu;
-
- /*
- * get_free_pages() cannot be used before cpu_init() done. BSP allocates
- * "NR_CPUS" pages for all CPUs to avoid that AP calls get_zeroed_page().
- */
- if (smp_processor_id() == 0) {
- cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * NR_CPUS, PERCPU_PAGE_SIZE,
- __pa(MAX_DMA_ADDRESS));
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
- memcpy(cpu_data, __phys_per_cpu_start, __per_cpu_end - __per_cpu_start);
- __per_cpu_offset[cpu] = (char *) cpu_data - __per_cpu_start;
- cpu_data += PERCPU_PAGE_SIZE;
-
- per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu];
- }
- }
- cpu_data = __per_cpu_start + __per_cpu_offset[smp_processor_id()];
-#else /* !CONFIG_SMP */
- cpu_data = __phys_per_cpu_start;
-#endif /* !CONFIG_SMP */
+ cpu_data = per_cpu_init();
get_max_cacheline_size();
arch/ia64/mm/Makefile +3 -0
@@ -7,3 +7,6 @@ obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_NUMA) += numa.o obj-$(CONFIG_DISCONTIGMEM) += discontig.o +ifndef CONFIG_DISCONTIGMEM +obj-y += contig.o +endif
arch/ia64/mm/contig.c new file +131 -0
131 lines not on this page · raw message
arch/ia64/mm/discontig.c +219 -156
490 lines not on this page · raw message
arch/ia64/mm/init.c +86 -137
300 lines not on this page · raw message
include/asm-ia64/mmzone.h +22 -122
179 lines not on this page · raw message
include/asm-ia64/nodedata.h +9 -30
@@ -13,7 +13,7 @@#ifndef _ASM_IA64_NODEDATA_H#define _ASM_IA64_NODEDATA_H - +#include <asm/percpu.h> #include <asm/mmzone.h> /*
@@ -22,15 +22,17 @@struct pglist_data ;struct ia64_node_data { -short active_cpu_count;short node; +short active_cpu_count; +/* +* The fields are read-only (after boot). They contain pointers +* to various structures located on other nodes. Ths data is +* replicated on each node in order to reduce off-node references. +*/ struct pglist_data *pg_data_ptrs[NR_NODES ]; -struct page *bank_mem_map_base[NR_BANKS ];struct ia64_node_data *node_data_ptrs[NR_NODES ]; -short node_id_map[NR_BANKS ]; }; -/* * Return a pointer to the node_data structure for the executing cpu. */
@@ -40,7 +42,8 @@/* * Return a pointer to the node_data structure for the specified node. */ -#define node_data (node) (local_node_data->node_data_ptrs[node]) +#define node_data (node) (local_node_data->node_data_ptrs[node]) +#define NODE_DATA (nid) (local_node_data->pg_data_ptrs[nid])/* * Get a pointer to the node_id/node_data for the current cpu.
@@ -48,29 +51,5 @@*/ extern int boot_get_local_nodeid (void );extern struct ia64_node_data *get_node_data_ptr (void ); - -/* -* Given a node id, return a pointer to the pg_data_t for the node. -* The following 2 macros are similar. -* -* NODE_DATA - should be used in all code not related to system -* initialization. It uses pernode data structures to minimize -* offnode memory references. However, these structure are not -* present during boot. This macro can be used once cpu_init -* completes. -* -* BOOT_NODE_DATA -* - should be used during system initialization -* prior to freeing __initdata. It does not depend on the percpu -* area being present. -* -* NOTE: The names of these macros are misleading but are difficult to change -* since they are used in generic linux & on other architecures. -*/ -#define NODE_DATA (nid) (local_node_data->pg_data_ptrs[nid]) -#define BOOT_NODE_DATA (nid) boot_get_pg_data_ptr((long)(nid)) - -struct pglist_data ; -extern struct pglist_data *__init boot_get_pg_data_ptr (long );#endif /* _ASM_IA64_NODEDATA_H */
include/asm-ia64/numa.h +15 -1
@@ -15,13 +15,21 @@#ifdef CONFIG_DISCONTIGMEM # include <asm/mmzone.h> -# define NR_MEMBLKS (NR_BANKS)#else # define NR_NODES (8)# define NR_MEMBLKS (NR_NODES * 8)#endif #include <linux/cache.h> +#include <linux/threads.h> +#include <linux/smp.h> + +#define NODEMASK_WORDCOUNT ((NR_NODES+(BITS_PER_LONG-1))/BITS_PER_LONG) + +#define NODE_MASK_NONE { [0 ... ((NR_NODES+BITS_PER_LONG-1)/BITS_PER_LONG)-1] = 0 } + +typedef unsigned long nodemask_t [NODEMASK_WORDCOUNT ]; + extern volatile char cpu_to_node_map[NR_CPUS] __cacheline_aligned; extern volatile unsigned long node_to_cpu_mask[NR_NODES] __cacheline_aligned;
@@ -63,6 +71,12 @@extern int paddr_to_nid (unsigned long paddr);#define local_nodeid (cpu_to_node_map[smp_processor_id()]) + +#else /* !CONFIG_NUMA */ + +#define node_distance (from,to) 10 +#define paddr_to_nid (x) 0 +#define local_nodeid 0#endif /* CONFIG_NUMA */
include/asm-ia64/page.h +18 -10
@@ -93,18 +93,26 @@#define virt_addr_valid (kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) -#ifndef CONFIG_DISCONTIGMEM -# ifdef CONFIG_VIRTUAL_MEM_MAP -extern int ia64_pfn_valid (unsigned long pfn); -# define pfn_valid (pfn) (((pfn) < max_mapnr) && ia64_pfn_valid(pfn)) -# else -# define pfn_valid (pfn) ((pfn) < max_mapnr) -# endif -#define virt_to_page (kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) -#define page_to_pfn (page) ((unsigned long) (page - mem_map)) +#ifdef CONFIG_VIRTUAL_MEM_MAP +extern int ia64_pfn_valid (unsigned long pfn); +#else +#define ia64_pfn_valid (pfn) (1) +#endif + +extern unsigned long max_low_pfn; +#define pfn_valid (pfn) (((pfn) < max_low_pfn) && ia64_pfn_valid(pfn)) + +#if defined(CONFIG_VIRTUAL_MEM_MAP ) +extern struct page *vmem_map; +#define pfn_to_page (pfn) (vmem_map + (pfn)) +#define page_to_pfn (page) ((unsigned long) (page - vmem_map)) +#else #define pfn_to_page (pfn) (mem_map + (pfn)) -#define page_to_phys (page) (page_to_pfn(page) << PAGE_SHIFT) +#define page_to_pfn (page) ((unsigned long) (page - mem_map))#endif + +#define virt_to_page (kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)) +#define page_to_phys (page) (page_to_pfn(page) << PAGE_SHIFT) typedef union ia64_va { struct {
include/asm-ia64/percpu.h +1 -0
@@ -46,6 +46,7 @@extern void percpu_modcopy (void *pcpudst,const void *src,unsigned long size);extern void setup_per_cpu_areas (void ); +extern void *per_cpu_init (void );#else /* ! SMP */
include/asm-ia64/pgtable.h +28 -4
@@ -174,7 +174,6 @@return (addr & (local_cpu_data->unimpl_pa_mask)) ==0 ; } -#ifndef CONFIG_DISCONTIGMEM /* * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel * memory. For the return value to be meaningful, ADDR must be >=
@@ -190,7 +189,6 @@*/ #define kern_addr_valid (addr) (1) -#endif /* * Now come the defines and routines to manage and access the three-level
@@ -241,10 +239,8 @@#define pte_none (pte) (!pte_val(pte))#define pte_present (pte) (pte_val(pte) & (_PAGE_P | _PAGE_PROTNONE))#define pte_clear (pte) (pte_val(*(pte)) = 0UL) -#ifndef CONFIG_DISCONTIGMEM /* pte_page() returns the "struct page *" corresponding to the PTE: */ #define pte_page (pte) virt_to_page(((pte_val(pte) & _PFN_MASK) + PAGE_OFFSET)) -#endif #define pmd_none (pmd) (!pmd_val(pmd))#define pmd_bad (pmd) (!ia64_phys_addr_valid(pmd_val(pmd)))
@@ -415,7 +411,35 @@ }extern pgd_t swapper_pg_dir[PTRS_PER_PGD ]; +extern unsigned long MAX_DMA_ADDRESS ; + +/* +* Entries defined so far: +* - boot param structure itself +* - memory map +* - initrd (optional) +* - command line string +* - kernel code & data +* +* More could be added if necessary +*/ +struct rsvd_region { +unsigned long start;/* virtual address of beginning of element */ +unsigned long end;/* virtual address of end of element + 1 */ +}; +#define IA64_MAX_RSVD_REGIONS 5 +extern struct rsvd_region rsvd_region[IA64_MAX_RSVD_REGIONS +1 ]; +extern int num_rsvd_regions;extern void paging_init (void ); +extern int filter_rsvd_memory (unsigned long start,unsigned long end,void *arg); +#ifdef CONFIG_DISCONTIGMEM +extern void discontig_mem_init (void ); +extern void call_pernode_memory (unsigned long start,unsigned long end,void *arg); +#else +extern unsigned long bootmap_start; +extern int find_max_pfn (unsigned long start,unsigned long end,void *arg); +extern int find_bootmap_location (unsigned long start,unsigned long end,void *arg); +#endif /* * Note: The macros below rely on the fact that MAX_SWAPFILES_SHIFT <= number of
include/asm-ia64/processor.h +2 -0
@@ -185,6 +185,8 @@#endif #ifdef CONFIG_NUMA struct ia64_node_data *node_data; +struct cpuinfo_ia64 *cpu_data[NR_CPUS ]; +int nodeid;#endif };