discontig update for linux-ia64-2.5 bk tree
Subsystems (3)
This patch rewrites part of the discontig code in 2.5 (based on Jack and Kimi's work) to achieve a few things:
o fix bugs so that sn2 will work
o allow the virtual mem map to be used along with discontigmem
o allow generic kernels to work across all platforms
There are a few hunks that remove #ifdef CONFIG_VIRTUAL_MEMMAP lines, but maybe that config option should be removed altogether and made the default? It would be nice to do that for CONFIG_DISCONTIGMEM too, but that would mean touching other architectures, so is less likely to happen. There's also still an issue with CONFIG_FORCE_MAX_ZONEORDER.
I'd appreciate any feedback (testing, comments) that you can provide.
Here's the diffstat:
arch/ia64/Kconfig | 40 ----- arch/ia64/kernel/setup.c | 35 ++--- arch/ia64/mm/discontig.c | 297 +++++++++++++++++++------------------------ arch/ia64/mm/init.c | 183 ++++++++++++-------------- include/asm-ia64/mmzone.h | 144 +++----------------- include/asm-ia64/nodedata.h | 39 +---- include/asm-ia64/numa.h | 16 ++ include/asm-ia64/page.h | 14 -- include/asm-ia64/pgtable.h | 4 include/asm-ia64/processor.h | 2 include/linux/mm.h | 4 mm/bootmem.c | 36 +++-- mm/memory.c | 2 mm/page_alloc.c | 9 - 14 files changed, 327 insertions(+), 498 deletions(-)
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.1143 -> 1.1144 # include/linux/mm.h 1.118 -> 1.119 # mm/page_alloc.c 1.154 -> 1.155
# include/asm-ia64/page.h 1.19 -> 1.20
# arch/ia64/kernel/setup.c 1.51 -> 1.52
# include/asm-ia64/pgtable.h 1.26 -> 1.27
# mm/bootmem.c 1.15 -> 1.16
# include/asm-ia64/numa.h 1.5 -> 1.6
# include/asm-ia64/processor.h 1.46 -> 1.47
# arch/ia64/mm/init.c 1.42 -> 1.43
# mm/memory.c 1.127 -> 1.128
# include/asm-ia64/nodedata.h 1.3 -> 1.4
# arch/ia64/mm/discontig.c 1.4 -> 1.5
# arch/ia64/Kconfig 1.28 -> 1.29
# include/asm-ia64/mmzone.h 1.4 -> 1.5
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/06/17 [email protected] 1.1144
# allow discontig to work in a generic way along with virtual memmap # -------------------------------------------- # diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig --- a/arch/ia64/Kconfig Tue Jun 17 14:45:16 2003 +++ b/arch/ia64/Kconfig Tue Jun 17 14:45:16 2003 @@ -245,8 +245,7 @@
config VIRTUAL_MEM_MAP
bool "Enable Virtual Mem Map"
- depends on !NUMA
- default y if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 + default y if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 || IA64_SGI_SN2
help
Say Y to compile the kernel with support for a virtual mem map. This is an alternate method of supporting large holes in the
@@ -259,8 +258,8 @@
are unsure, say Y.
config IA64_MCA
- bool "Enable IA-64 Machine Check Abort" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
- default y if IA64_SGI_SN2
+ bool "Enable IA-64 Machine Check Abort"
+ default y if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 || IA64_SGI_SN2
help
Say Y here to enable machine check support for IA-64. If you're unsure, answer Y.
@@ -292,14 +291,6 @@
depends on IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 || IA64_SGI_SN2 default y
-config IA64_SGI_SN_DEBUG
- bool "Enable extra debugging code"
- depends on IA64_SGI_SN2
- help
- Turns on extra debugging code in the SGI SN (Scalable NUMA) platform - for IA-64. Unless you are debugging problems on an SGI SN IA-64 box, - say N.
-
config IA64_SGI_SN_SIM
bool "Enable SGI Medusa Simulator Support"
depends on IA64_SGI_SN2
@@ -307,29 +298,6 @@
If you are compiling a kernel that will run under SGI's IA-64 simulator (Medusa) then say Y, otherwise say N.
-config IA64_SGI_AUTOTEST
- bool "Enable autotest (llsc). Option to run cache test instead of booting"
- depends on IA64_SGI_SN2
- help
- Build a kernel used for hardware validation. If you include the - keyword "autotest" on the boot command line, the kernel does NOT boot. - Instead, it starts all cpus and runs cache coherency tests instead.
-
- If unsure, say N.
-
-config SERIAL_SGI_L1_PROTOCOL
- bool "Enable protocol mode for the L1 console"
- depends on IA64_SGI_SN2
- help
- Uses protocol mode instead of raw mode for the level 1 console on the - SGI SN (Scalable NUMA) platform for IA-64. If you are compiling for - an SGI SN box then Y is the recommended value, otherwise say N.
-
-config PERCPU_IRQ
- bool
- depends on IA64_SGI_SN2
- default y
-
# On IA-64, we always want an ELF /proc/kcore.
config KCORE_ELF
bool
@@ -355,7 +323,7 @@
config FORCE_MAX_ZONEORDER
int
- default "18"
+ default "11"
config HUGETLB_PAGE
bool "IA-64 Huge TLB Page Support"
arch/ia64/kernel/setup.c +18 -17
@@ -137,7 +137,7 @@ call_pernode_memory (unsigned long start, unsigned long end, void *arg) {unsigned long rs, re; -void (*func)(unsigned long ,unsigned long ,int ,int ); +void (*func)(unsigned long ,unsigned long ,int );int i; start =PAGE_ALIGN (start);
@@ -148,22 +148,21 @@ func = arg;if (!num_memblks) { -/* -* This machine doesn't have SRAT, so call func with -* nid=0, bank=0. -*/ +/* No SRAT table, to assume one node (node 0) */ if (start < end) - (*func)(start, end - start,0 ,0 ); + (*func)(start, end,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); + rs =max (__pa (start), node_memblk[i].start_paddr); + re =min (__pa (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); + (*func)((unsigned long )__va (rs), (unsigned long )__va (re), node_memblk[i].nid); + +if ((unsigned long )__va (re) == end) +break ; } }
@@ -179,7 +178,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 +200,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, func);#else - (*func)(__pa (range_start), range_end - range_start); + (*func)(range_start, range_end,0 );#endif /* nothing more available in this segment */
@@ -703,24 +702,26 @@* 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(). */ +#ifndef CONFIG_DISCONTIGMEM 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 ; } +for (cpu =0 ; cpu <NR_CPUS ; cpu++) { + cpu_data = __per_cpu_offset[cpu] + __per_cpu_start; +memcpy (cpu_data, __phys_per_cpu_start, __per_cpu_end - __per_cpu_start); + } } +#endif cpu_data = __per_cpu_start + __per_cpu_offset[smp_processor_id ()];#else /* !CONFIG_SMP */ cpu_data = __phys_per_cpu_start;#endif /* !CONFIG_SMP */ cpu_info = cpu_data + ((char *) &__get_cpu_var (cpu_info) - __per_cpu_start); -#ifdef CONFIG_NUMA - cpu_info->node_data =get_node_data_ptr (); -#endif get_max_cacheline_size ();
arch/ia64/mm/discontig.c +133 -164
404 lines not on this page · raw message
arch/ia64/mm/init.c +85 -98
278 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 +6 -8
@@ -93,18 +93,16 @@#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 +#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))#define pfn_to_page (pfn) (mem_map + (pfn))#define page_to_phys (page) (page_to_pfn(page) << PAGE_SHIFT) -#endif typedef union ia64_va { struct {
include/asm-ia64/pgtable.h +0 -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
@@ -237,10 +235,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)))
include/asm-ia64/processor.h +2 -0
@@ -185,6 +185,8 @@#endif #ifdef CONFIG_NUMA struct ia64_node_data *node_data; +int nodeid; +struct cpuinfo_ia64 *cpu_data[NR_CPUS ];#endif };
include/linux/mm.h +0 -4
@@ -13,9 +13,7 @@#include <linux/rbtree.h> #include <linux/fs.h> -#ifndef CONFIG_DISCONTIGMEM /* Don't use mapnrs, do it properly */ extern unsigned long max_mapnr; -#endif extern unsigned long num_physpages;extern void * high_memory;
@@ -391,10 +389,8 @@#define VM_FAULT_MINOR 1#define VM_FAULT_MAJOR 2 -#ifndef CONFIG_DISCONTIGMEM /* The array of struct pages - for discontigmem use pgdat->lmem_map */ extern struct page *mem_map; -#endif extern void show_free_areas (void );
mm/bootmem.c +27 -9
@@ -48,8 +48,24 @@bootmem_data_t *bdata = pgdat->bdata;unsigned long mapsize = ((end - start)+7 )/8 ; - pgdat->pgdat_next = pgdat_list; - pgdat_list = pgdat; + +/* +* sort pgdat_list so that the lowest one comes first, +* which makes alloc_bootmem_low_pages work as desired. +*/ +if (!pgdat_list || pgdat_list->node_start_pfn > pgdat->node_start_pfn) { + pgdat->pgdat_next = pgdat_list; + pgdat_list = pgdat; + }else { +pg_data_t *tmp = pgdat_list; +while (tmp->pgdat_next) { +if (tmp->pgdat_next->node_start_pfn > pgdat->node_start_pfn) +break ; + tmp = tmp->pgdat_next; + } + pgdat->pgdat_next = tmp->pgdat_next; + tmp->pgdat_next = pgdat; + } mapsize = (mapsize + (sizeof (long ) -1UL )) & ~(sizeof (long ) -1UL ); bdata->node_bootmem_map =phys_to_virt (mapstart <<PAGE_SHIFT );
@@ -115,6 +131,7 @@if (end > bdata->node_low_pfn)BUG (); +/* Record last successful free */ if (addr < bdata->last_success) bdata->last_success = addr;
@@ -251,32 +268,33 @@static unsigned long __init free_all_bootmem_core (pg_data_t *pgdat) { -struct page *page = pgdat->node_mem_map; +struct page *page;bootmem_data_t *bdata = pgdat->bdata;unsigned long i, count, total =0 ;unsigned long idx; -unsigned long *map; +unsigned long *map;if (!bdata->node_bootmem_map)BUG (); count =0 ; + page =virt_to_page (phys_to_virt (bdata->node_boot_start)); idx = bdata->node_low_pfn - (bdata->node_boot_start >>PAGE_SHIFT ); + map = bdata->node_bootmem_map;for (i =0 ; i < idx; ) {unsigned long v = ~map[i /BITS_PER_LONG ];if (v) {unsigned long m; -for (m =1 ; m && i < idx; m<<=1 , page++, i++) { +for (m =1 ; m && i < idx; m<<=1 , i++) {if (v & m) { count++; -ClearPageReserved (page); -set_page_count (page,1 ); -__free_page (page); +ClearPageReserved (page+i); +set_page_count (page+i,1 ); +__free_page (page+i); } } }else { i+=BITS_PER_LONG ; - page +=BITS_PER_LONG ; } } total += count;
mm/memory.c +0 -2
@@ -55,11 +55,9 @@#include <linux/swapops.h> -#ifndef CONFIG_DISCONTIGMEM /* use the per-pgdat data instead for discontigmem - mbligh */ unsigned long max_mapnr;struct page *mem_map; -#endif unsigned long num_physpages;void * high_memory;
mm/page_alloc.c +6 -3
@@ -57,12 +57,15 @@*/ static int bad_range (struct zone *zone,struct page *page) { -if (page_to_pfn (page) >= zone->zone_start_pfn + zone->spanned_pages) +if (page_to_pfn (page) >= zone->zone_start_pfn + zone->spanned_pages) {return 1 ; -if (page_to_pfn (page) < zone->zone_start_pfn) + } +if (page_to_pfn (page) < zone->zone_start_pfn) {return 1 ; -if (zone !=page_zone (page)) + } +if (zone !=page_zone (page)) {return 1 ; + }return 0 ; }
Jesse,
Jesse> There are a few hunks that remove #ifdef CONFIG_VIRTUAL_MEMMAP lines, Jesse> but maybe that config option should be removed altogether and made the Jesse> default?
Why? I want the CONFIG_VIRTUAL_MEMMAP there, because it clearly identifies the code and if we ever have any doubts about its performance effects, we can easily try without virtual mem_map.
- default y if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 + default y if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 || IA64_SGI_SN2
Looks like this should be changed to:
+ default y if !IA64_HP_SIM
Ditto for the other places.
Please declare as "extern":
+int filter_rsvd_memory(unsigned long start, unsigned long end, void *arg);
THanks,
--david
Quoted 9 lines · David Mosberger
Jesse,
Jesse> There are a few hunks that remove #ifdef
CONFIG_VIRTUAL_MEMMAPlines, Jesse> but maybe that config option should be removed altogether and made the Jesse> default?Why? I want the
CONFIG_VIRTUAL_MEMMAPthere, because it clearly identifies the code and if we ever have any doubts about its performance effects, we can easily try without virtualmem_map.
That's a good point, but I just figured that if it worked for everyone maybe we should make it unconditional. I don't mind either way though.
Quoted 8 lines
(quoted diff) +1
-1- default y if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 + default y if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 || IA64_SGI_SN2Looks like this should be changed to:
(quoted diff) +1
-0+ default y if !IA64_HP_SIMDitto for the other places.
Ok.
Quoted 5 lines
Please declare as "extern":
+int
filter_rsvd_memory(unsigned long start, unsigned long end, void *arg);THanks,
Ok. Thanks for looking at it.
Jesse
Quoted 7 lines · David Mosberger
(quoted diff) +1
-1- default y if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 + default y if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 || IA64_SGI_SN2Looks like this should be changed to:
(quoted diff) +1
-0+ default y if !IA64_HP_SIM
Quoted 7 lines
Ditto for the other places.
Please declare as "extern":
+int
filter_rsvd_memory(unsigned long start, unsigned long end, void *arg);THanks,
Ok, here's another one that addresses those issues (and gets rid of the superfluous page_alloc.c change). We still need to fix the alignment of each node to conform to CONFIG_FORCE_MAX_ZONEORDER and simplify it so that we don't have to export max_mapnr and mem_map from memory.c and mm.h, but other than that, it's in good shape.
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.1149 -> 1.1151
# include/linux/mm.h 1.118 -> 1.119
# include/asm-ia64/page.h 1.19 -> 1.20
# arch/ia64/kernel/setup.c 1.51 -> 1.52
# include/asm-ia64/pgtable.h 1.26 -> 1.27
# mm/bootmem.c 1.15 -> 1.16
# include/asm-ia64/numa.h 1.5 -> 1.6
# include/asm-ia64/processor.h 1.46 -> 1.47
# arch/ia64/mm/init.c 1.42 -> 1.43
# mm/memory.c 1.127 -> 1.128
# include/asm-ia64/nodedata.h 1.3 -> 1.4
# arch/ia64/mm/discontig.c 1.4 -> 1.5
# arch/ia64/Kconfig 1.29 -> 1.30
# include/asm-ia64/mmzone.h 1.4 -> 1.5
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/06/18 [email protected] 1.1150
# discontig update # -------------------------------------------- # 03/06/18 [email protected] 1.1151 # export mem_map and max_mapnr for ia64 # -------------------------------------------- # diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig --- a/arch/ia64/Kconfig Wed Jun 18 16:53:13 2003 +++ b/arch/ia64/Kconfig Wed Jun 18 16:53:13 2003 @@ -245,8 +245,7 @@
config VIRTUAL_MEM_MAP
bool "Enable Virtual Mem Map"
- depends on !NUMA
- default y if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
+ default y if !IA64_HP_SIM
help
Say Y to compile the kernel with support for a virtual mem map. This is an alternate method of supporting large holes in the
@@ -259,8 +258,8 @@
are unsure, say Y.
config IA64_MCA
- bool "Enable IA-64 Machine Check Abort" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
- default y if IA64_SGI_SN2
+ bool "Enable IA-64 Machine Check Abort"
+ default y if !IA64_HP_SIM
help
Say Y here to enable machine check support for IA-64. If you're unsure, answer Y.
@@ -292,43 +291,12 @@
depends on IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 || IA64_SGI_SN2 default y
-config IA64_SGI_SN_DEBUG
- bool "Enable extra debugging code"
- depends on IA64_SGI_SN2
- help
- Turns on extra debugging code in the SGI SN (Scalable NUMA) platform - for IA-64. Unless you are debugging problems on an SGI SN IA-64 box, - say N.
-
config IA64_SGI_SN_SIM
bool "Enable SGI Medusa Simulator Support"
depends on IA64_SGI_SN2
help
If you are compiling a kernel that will run under SGI's IA-64 simulator (Medusa) then say Y, otherwise say N.
-
-config IA64_SGI_AUTOTEST
- bool "Enable autotest (llsc). Option to run cache test instead of booting"
- depends on IA64_SGI_SN2
- help
- Build a kernel used for hardware validation. If you include the - keyword "autotest" on the boot command line, the kernel does NOT boot. - Instead, it starts all cpus and runs cache coherency tests instead.
-
- If unsure, say N.
-
-config SERIAL_SGI_L1_PROTOCOL
- bool "Enable protocol mode for the L1 console"
- depends on IA64_SGI_SN2
- help
- Uses protocol mode instead of raw mode for the level 1 console on the - SGI SN (Scalable NUMA) platform for IA-64. If you are compiling for - an SGI SN box then Y is the recommended value, otherwise say N.
-
-config PERCPU_IRQ
- bool
- depends on IA64_SGI_SN2
- default y
# On IA-64, we always want an ELF /proc/kcore.
config KCORE_ELF
arch/ia64/kernel/setup.c +18 -17
@@ -137,7 +137,7 @@ call_pernode_memory (unsigned long start, unsigned long end, void *arg) {unsigned long rs, re; -void (*func)(unsigned long ,unsigned long ,int ,int ); +void (*func)(unsigned long ,unsigned long ,int );int i; start =PAGE_ALIGN (start);
@@ -148,22 +148,21 @@ func = arg;if (!num_memblks) { -/* -* This machine doesn't have SRAT, so call func with -* nid=0, bank=0. -*/ +/* No SRAT table, to assume one node (node 0) */ if (start < end) - (*func)(start, end - start,0 ,0 ); + (*func)(start, end,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); + rs =max (__pa (start), node_memblk[i].start_paddr); + re =min (__pa (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); + (*func)((unsigned long )__va (rs), (unsigned long )__va (re), node_memblk[i].nid); + +if ((unsigned long )__va (re) == end) +break ; } }
@@ -179,7 +178,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 +200,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, func);#else - (*func)(__pa (range_start), range_end - range_start); + (*func)(range_start, range_end,0 );#endif /* nothing more available in this segment */
@@ -703,24 +702,26 @@* 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(). */ +#ifndef CONFIG_DISCONTIGMEM 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 ; } +for (cpu =0 ; cpu <NR_CPUS ; cpu++) { + cpu_data = __per_cpu_offset[cpu] + __per_cpu_start; +memcpy (cpu_data, __phys_per_cpu_start, __per_cpu_end - __per_cpu_start); + } } +#endif cpu_data = __per_cpu_start + __per_cpu_offset[smp_processor_id ()];#else /* !CONFIG_SMP */ cpu_data = __phys_per_cpu_start;#endif /* !CONFIG_SMP */ cpu_info = cpu_data + ((char *) &__get_cpu_var (cpu_info) - __per_cpu_start); -#ifdef CONFIG_NUMA - cpu_info->node_data =get_node_data_ptr (); -#endif get_max_cacheline_size ();
arch/ia64/mm/discontig.c +133 -164
404 lines not on this page · raw message
arch/ia64/mm/init.c +85 -98
278 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 +6 -8
@@ -93,18 +93,16 @@#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 +#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))#define pfn_to_page (pfn) (mem_map + (pfn))#define page_to_phys (page) (page_to_pfn(page) << PAGE_SHIFT) -#endif typedef union ia64_va { struct {
include/asm-ia64/pgtable.h +0 -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
@@ -237,10 +235,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)))
include/asm-ia64/processor.h +2 -0
@@ -185,6 +185,8 @@#endif #ifdef CONFIG_NUMA struct ia64_node_data *node_data; +int nodeid; +struct cpuinfo_ia64 *cpu_data[NR_CPUS ];#endif };
include/linux/mm.h +2 -2
@@ -13,7 +13,7 @@#include <linux/rbtree.h> #include <linux/fs.h> -#ifndef CONFIG_DISCONTIGMEM /* Don't use mapnrs, do it properly */ +#if !defined(CONFIG_DISCONTIGMEM ) || defined(CONFIG_IA64 )/* Don't use mapnrs, do it properly */ extern unsigned long max_mapnr;#endif
@@ -391,7 +391,7 @@#define VM_FAULT_MINOR 1#define VM_FAULT_MAJOR 2 -#ifndef CONFIG_DISCONTIGMEM +#if !defined(CONFIG_DISCONTIGMEM ) || defined(CONFIG_IA64 )/* The array of struct pages - for discontigmem use pgdat->lmem_map */ extern struct page *mem_map;#endif
mm/bootmem.c +27 -9
@@ -48,8 +48,24 @@bootmem_data_t *bdata = pgdat->bdata;unsigned long mapsize = ((end - start)+7 )/8 ; - pgdat->pgdat_next = pgdat_list; - pgdat_list = pgdat; + +/* +* sort pgdat_list so that the lowest one comes first, +* which makes alloc_bootmem_low_pages work as desired. +*/ +if (!pgdat_list || pgdat_list->node_start_pfn > pgdat->node_start_pfn) { + pgdat->pgdat_next = pgdat_list; + pgdat_list = pgdat; + }else { +pg_data_t *tmp = pgdat_list; +while (tmp->pgdat_next) { +if (tmp->pgdat_next->node_start_pfn > pgdat->node_start_pfn) +break ; + tmp = tmp->pgdat_next; + } + pgdat->pgdat_next = tmp->pgdat_next; + tmp->pgdat_next = pgdat; + } mapsize = (mapsize + (sizeof (long ) -1UL )) & ~(sizeof (long ) -1UL ); bdata->node_bootmem_map =phys_to_virt (mapstart <<PAGE_SHIFT );
@@ -115,6 +131,7 @@if (end > bdata->node_low_pfn)BUG (); +/* Record last successful free */ if (addr < bdata->last_success) bdata->last_success = addr;
@@ -251,32 +268,33 @@static unsigned long __init free_all_bootmem_core (pg_data_t *pgdat) { -struct page *page = pgdat->node_mem_map; +struct page *page;bootmem_data_t *bdata = pgdat->bdata;unsigned long i, count, total =0 ;unsigned long idx; -unsigned long *map; +unsigned long *map;if (!bdata->node_bootmem_map)BUG (); count =0 ; + page =virt_to_page (phys_to_virt (bdata->node_boot_start)); idx = bdata->node_low_pfn - (bdata->node_boot_start >>PAGE_SHIFT ); + map = bdata->node_bootmem_map;for (i =0 ; i < idx; ) {unsigned long v = ~map[i /BITS_PER_LONG ];if (v) {unsigned long m; -for (m =1 ; m && i < idx; m<<=1 , page++, i++) { +for (m =1 ; m && i < idx; m<<=1 , i++) {if (v & m) { count++; -ClearPageReserved (page); -set_page_count (page,1 ); -__free_page (page); +ClearPageReserved (page+i); +set_page_count (page+i,1 ); +__free_page (page+i); } } }else { i+=BITS_PER_LONG ; - page +=BITS_PER_LONG ; } } total += count;
mm/memory.c +1 -1
@@ -55,7 +55,7 @@#include <linux/swapops.h> -#ifndef CONFIG_DISCONTIGMEM +#if !defined(CONFIG_DISCONTIGMEM ) || defined(CONFIG_IA64 )/* ia64 needs them for now - jbarnes */ /* use the per-pgdat data instead for discontigmem - mbligh */ unsigned long max_mapnr;struct page *mem_map;
I missed this on first reading:
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;
}
+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
+ cpu_data = __per_cpu_offset[cpu] + __per_cpu_start;
+ memcpy(cpu_data, __phys_per_cpu_start, __per_cpu_end - __per_cpu_start);
+ }
What's the point of this?
The patch still removes CONFIG_VIRTUAL_MEM_MAP.
Also, please note that I don't want to add any ia64 patches that create additional dependencies on core code (I'm trying to sync things such that ia64 builds out of the box). So before submitting ia64-specific changes, please make sure the core-code is ready for it.
--david
Quoted 12 lines · David Mosberger
I missed this on first reading:
arch/ia64/kernel/setup.c +4
-1for (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 ; } +for (cpu =0 ; cpu <NR_CPUS ; cpu++) { + cpu_data = __per_cpu_offset[cpu] + __per_cpu_start; +memcpy (cpu_data, __phys_per_cpu_start, __per_cpu_end - __per_cpu_start); + }
Quoted 1 line
What's the point of this?
Arg, I saw that when I got my copy back (along with a couple of other things). I'll fix them up.
Quoted 1 line
The patch still removes
CONFIG_VIRTUAL_MEM_MAP.
...
Quoted 4 lines
Also, please note that I don't want to add any ia64 patches that create additional dependencies on core code (I'm trying to sync things such that ia64 builds out of the box). So before submitting ia64-specific changes, please make sure the core-code is ready for it.
Ok. I'll try to get the bootmem changes in first.
Thanks,
Jesse