another discontig patch
PATCH 1/1 another discontig patch
Here's another one. It still has the bootmem allocator change, but I'll push that seperately on lkml, I think it makes sense. This version is a bit different from the last:
o added back in the #ifndef CONFIG_DISCONTIGMEM in memory.c and mm.h for max_mapnr and mem_map
o added an ugly hack in asm-ia64/page.h to use different vars since max_mapnr and mem_map aren't available in the discontig case
o added back some more CONFIG_VIRTUAL_MEM_MAP #ifdefs
Turning off CONFIG_VIRTUAL_MEM_MAP still doesn't work--need to fix mm/init.c to accomodate that case.
Any other comments?
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.1155
# include/linux/mm.h 1.118 -> 1.123
# include/asm-ia64/page.h 1.19 -> 1.21
# arch/ia64/kernel/setup.c 1.51 -> 1.53
# 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.44
# mm/memory.c 1.127 -> 1.129
# 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 # -------------------------------------------- # 03/06/19 [email protected] 1.1152 # discontig fixes # -------------------------------------------- # 03/06/19 [email protected] 1.1153 # revert to stock code # -------------------------------------------- # 03/06/19 [email protected] 1.1154 # revert # -------------------------------------------- # 03/06/19 [email protected] 1.1155 # revert # -------------------------------------------- # diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig --- a/arch/ia64/Kconfig Thu Jun 19 14:57:32 2003 +++ b/arch/ia64/Kconfig Thu Jun 19 14:57:32 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 +15 -16
@@ -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,6 +702,8 @@* 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 +/* for discontig machines, we do this in discontig.c */ if (smp_processor_id () ==0 ) { cpu_data =__alloc_bootmem (PERCPU_PAGE_SIZE *NR_CPUS ,PERCPU_PAGE_SIZE ,__pa (MAX_DMA_ADDRESS ));
@@ -712,15 +713,13 @@ cpu_data +=PERCPU_PAGE_SIZE ; } } +#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 +87 -86
256 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 +20 -10
@@ -93,18 +93,28 @@#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 +#if defined(CONFIG_VIRTUAL_MEM_MAP ) && !defined(CONFIG_DISCONTIGMEM ) +extern int ia64_pfn_valid (unsigned long pfn); +# define pfn_valid (pfn) (((pfn) < max_mapnr) && ia64_pfn_valid(pfn)) +#elif defined(CONFIG_VIRTUAL_MEM_MAP ) && defined(CONFIG_DISCONTIGMEM ) +extern int ia64_pfn_valid (unsigned long pfn); +extern unsigned long max_low_pfn; +# define pfn_valid (pfn) (((pfn) < max_low_pfn) && ia64_pfn_valid(pfn)) +#else +# define pfn_valid (pfn) ((pfn) < max_mapnr) +#endif + +#if defined(CONFIG_DISCONTIGMEM ) && 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_pfn (page) ((unsigned long) (page - mem_map)) +#endif /* CONFIG_DISCONTIGMEM && CONFIG_VIRTUAL_MEM_MAP */ +#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 };
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;
Forgot to mention that this also addresses the problem with MAXORDER.
Quoted 17 lines · Jesse Barnes
Here's another one. It still has the bootmem allocator change, but I'll push that seperately on lkml, I think it makes sense. This version is a bit different from the last:
o added back in the #ifndef
CONFIG_DISCONTIGMEMinmemory.candmm.hformax_mapnrandmem_map
o added an ugly hack inasm-ia64/page.hto use different vars sincemax_mapnrandmem_maparen't available in the discontig case
o added back some moreCONFIG_VIRTUAL_MEM_MAP#ifdefsTurning off
CONFIG_VIRTUAL_MEM_MAPstill doesn't work--need to fixmm/init.cto accomodate that case.Any other comments?
Thanks,
Jesse