discontig patch (still ugly)
PATCH 1/1 discontig patch (still ugly)
Ok, here's a new patch that addresses the problems below, just for reference. I'll split out the contig.c stuff and send that seperately in a minute.
Quoted 2 lines · David Mosberger
- in
acpi.c, it looks like there is no reason formin_hole_sizeanymore, yet the patch doesn't clean up this variable
I had just removed that printk at Xavier's request and missed that it wasn't being used anymore. Fixed.
Quoted 2 lines
-
MAX_RSVD_REGIONSet al got moved topgtable.h; why in the world would that be the right place? Just because "it compiled"??
No, because that was necessary for the contig.c/discontig.c seperation. Which header file would be better?
Quoted 1 line
- why is there both
vmem_mapandmem_mapin the NUMA case?
You mean for the discontig case? mem_map isn't there. It only exists (mm/memory.c) if CONFIG_DISCONTIGMEM is off, otherwise we just use vmem_map and pgdata_t->node_mem_map for everything.
Right now (and even without this patch) the config options are kind of a mess. CONFIG_DISCONTIGMEM doesn't make sense without CONFIG_NUMA and CONFIG_VIRTUAL_MEMMAP even though they should all be independent. I'll try to clean that up too.
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.1245 -> 1.1246
# arch/ia64/Makefile 1.60 -> 1.61
# include/asm-ia64/page.h 1.21 -> 1.22
# arch/ia64/kernel/setup.c 1.57 -> 1.58
# include/asm-ia64/pgtable.h 1.28 -> 1.29
# arch/ia64/mm/Makefile 1.7 -> 1.8
# include/asm-ia64/numa.h 1.6 -> 1.7
# include/asm-ia64/processor.h 1.50 -> 1.51
# arch/ia64/mm/init.c 1.47 -> 1.48
# arch/ia64/kernel/acpi.c 1.50 -> 1.51
# 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
# arch/ia64/Kconfig 1.43 -> 1.44
# 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/09/22 [email protected] 1.1246
# discontig # -------------------------------------------- # diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig --- a/arch/ia64/Kconfig Mon Sep 22 15:18:18 2003 +++ b/arch/ia64/Kconfig Mon Sep 22 15:18:18 2003 @@ -220,22 +220,6 @@ Access). This option is for configuring high-end multiprocessor server systems. If in doubt, say N.
-choice
- prompt "Maximum Memory per NUMA Node" if NUMA && IA64_DIG
- depends on NUMA && IA64_DIG
- default IA64_NODESIZE_16GB
-
-config IA64_NODESIZE_16GB
- bool "16GB"
-
-config IA64_NODESIZE_64GB
- bool "64GB"
-
-config IA64_NODESIZE_256GB
- bool "256GB"
-
-endchoice
-
config DISCONTIGMEM
bool "Discontiguous memory support" if (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC) && NUMA default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA
arch/ia64/Makefile +1 -1
@@ -64,7 +64,7 @@ drivers-$(CONFIG_PCI) += arch/ia64/pci/ drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/ drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ -drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ +drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ arch/ia64/sn/ drivers-$(CONFIG_OPROFILE) += arch/ia64/oprofile/ boot := arch/ia64/hp/sim/boot
arch/ia64/kernel/acpi.c +1 -29
@@ -379,7 +379,7 @@void __init acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma) { -unsigned long paddr, size, hole_size, min_hole_size; +unsigned long paddr, size;u8 pxm;struct node_memblk_s *p, *q, *pend;
@@ -400,34 +400,6 @@/* Ignore disabled entries */ if (!ma->flags.enabled)return ; - -/* -* When the chunk is not the first one in the node, check distance -* from the other chunks. When the hole is too huge ignore the chunk. -* This restriction should be removed when multiple chunks per node -* is supported. -*/ - pend = &node_memblk[num_memblks]; - min_hole_size =0 ; -for (p = &node_memblk[0 ]; p < pend; p++) { -if (p->nid != pxm) -continue ; -if (p->start_paddr < paddr) - hole_size = paddr - (p->start_paddr + p->size); -else - hole_size = p->start_paddr - (paddr + size); - -if (!min_hole_size || hole_size < min_hole_size) - min_hole_size = hole_size; - } - -if (min_hole_size) { -if (min_hole_size > size) { -printk (KERN_ERR "Too huge memory hole. Ignoring %ld MBytes at %lx\n" , - size/(1024 *1024 ), paddr); -return ; - } - }/* record this node in proximity bitmap */ pxm_bit_set (pxm);
arch/ia64/kernel/setup.c +10 -157
218 lines not on this page · raw message
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 +88 -137
302 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 cpumask_t 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
@@ -94,18 +94,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
@@ -186,6 +186,8 @@#endif #ifdef CONFIG_NUMA struct ia64_node_data *node_data; +struct cpuinfo_ia64 *cpu_data[NR_CPUS ]; +int nodeid;#endif };
Quoted 3 lines
Quoted 3 lines
-
MAX_RSVD_REGIONSet al got moved topgtable.h; why in the world would that be the right place? Just because "it compiled"??
Jesse> No, because that was necessary for the contig.c/discontig.c Jesse> seperation. Which header file would be better?
I think it could be just a local header file in arch/ia64/kernel/.
Quoted 1 line
Quoted 1 line
- why is there both
vmem_mapandmem_mapin the NUMA case?
Jesse> You mean for the discontig case? mem_map isn't there. It Jesse> only exists (mm/memory.c) if CONFIG_DISCONTIGMEM is off, Jesse> otherwise we just use vmem_map and pgdata_t->node_mem_map for Jesse> everything.
Then fix mm/memory.c to define mem_map if CONFIG_VIRTUAL_MEMMAP is on.
--david