Skip to contentSkip to conversation

discontig patch (work in progress)

PATCH In review Jesse Barnes 2 participants 8 messages Sep 23, 2003 – Sep 26, 2003

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 discontig patch (work in progress)

I spent some time trying to make things a little clearer, eliminate some redundancy, conform to coding style, and generally cleanup the patch. The contig/discontig split patch I posted still hasn't made its way to lia64.bkbits.net, so this patch is against a tree with my patch applied. I still plan on splitting things out quite a bit more and cleaning more stuff up, but I thought I'd post this so people can look at it.

 arch/ia64/Kconfig           |   30 --
 arch/ia64/Makefile          |    2 
 arch/ia64/kernel/acpi.c     |   30 --
 arch/ia64/kernel/setup.c    |   34 ---
 arch/ia64/mm/contig.c       |   33 +++
 arch/ia64/mm/discontig.c    |  471 +++++++++++++++++++++++---------------------
 arch/ia64/mm/init.c         |  167 +++++++--------
 include/asm-ia64/meminit.h  |    8 
 include/asm-ia64/mmzone.h   |  144 ++-----------
 include/asm-ia64/nodedata.h |   29 --
 include/asm-ia64/numa.h     |   19 +
 include/asm-ia64/page.h     |    8 
 include/asm-ia64/percpu.h   |    1 
 include/asm-ia64/pgtable.h  |    4 
 include/linux/mm.h          |    5 
 kernel/ksyms.c              |    2 
 mm/memory.c                 |    2 

One thing that immediately springs to mind is the per-cpu stuff. That should probably be split into contig and discontig versions and put in the appropriate files, and obviously the non-ia64 stuff (!CONFIG_DISCONTIGMEM -> CONFIG_VIRTUAL_MEM_MAP || !CONFIG_DISCONTIGMEM) will be split out and sent seperately. I could probably also seperate the patch that changes the arguments to the callback functions to be more consistent. And of course there's other cleanup that needs to be done, like removing the shouting from GRANULEROUND* and naming nodeid() something better (maybe numa_node_id()?).

Thanks,
Jesse

arch/ia64/Kconfig +5 -25
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/arch/ia64/Kconfig linux-ia64-2.5-sn/arch/ia64/Kconfig
@@ -220,24 +220,8 @@
 	  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
+	bool "Discontiguous memory support" if (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC) && NUMA && VIRTUAL_MEM_MAP
 	default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA
 	help
 	  Say Y to support efficient handling of discontiguous physical memory,
@@ -250,14 +234,10 @@
 	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
-	  physical address space on non NUMA machines. Since the DISCONTIGMEM
-	  option is not supported on machines with the ZX1 chipset, this is
-	  the only way of supporting more than 1 Gb of memory on those
-	  machines. This code also only takes effect if a memory hole of
-	  greater than 1 Gb is found during boot, so it is safe to enable
-	  unless you require the DISCONTIGMEM option for your machine. If you
-	  are unsure, say Y.
+	  This code also only takes effect if a memory hole of greater than
+	  1 Gb is found during boot.  You must turn this option on if you
+	  require the DISCONTIGMEM option for your machine. If you are
+	  unsure, say Y.
 
 config IA64_MCA
 	bool "Enable IA-64 Machine Check Abort"
arch/ia64/Makefile +1 -1
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/arch/ia64/Makefile linux-ia64-2.5-sn/arch/ia64/Makefile
@@ -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
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/arch/ia64/kernel/acpi.c linux-ia64-2.5-sn/arch/ia64/kernel/acpi.c
@@ -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;
 
@@ -401,34 +401,6 @@
 	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 +7 -27
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/arch/ia64/kernel/setup.c linux-ia64-2.5-sn/arch/ia64/kernel/setup.c
@@ -101,7 +101,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
@@ -123,9 +123,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 */
@@ -237,7 +237,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 */
@@ -251,6 +250,8 @@
 # endif
 #endif /* CONFIG_APCI_BOOT */
 
+	find_memory();
+
 	/* process SAL system table: */
 	ia64_sal_init(efi.sal_systab);
 
@@ -542,28 +543,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();
 
@@ -575,7 +555,7 @@
 	 */
 	cpu_info = cpu_data + ((char *) &__ia64_per_cpu_var(cpu_info) - __per_cpu_start);
 #ifdef CONFIG_NUMA
-	cpu_info->node_data = get_node_data_ptr();
+	cpu_info->node_data = early_get_node_data();
 #endif
 	identify_cpu(cpu_info);
 
arch/ia64/mm/contig.c +33 -0
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/arch/ia64/mm/contig.c linux-ia64-2.5-sn/arch/ia64/mm/contig.c
@@ -155,3 +155,36 @@
 
 	find_initrd();
 }
+
+/**
+ * per_cpu_init - setup per-cpu variables
+ *
+ * Allocate and setup per-cpu data areas.
+ */
+void *per_cpu_init(void)
+{
+	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];
+		}
+	}
+	return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
+#else /* !CONFIG_SMP */
+	return __phys_per_cpu_start;
+#endif /* !CONFIG_SMP */
+}
arch/ia64/mm/discontig.c +250 -220

593 lines not on this page · raw message

arch/ia64/mm/init.c +81 -86

241 lines not on this page · raw message

include/asm-ia64/meminit.h +8 -0
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/include/asm-ia64/meminit.h linux-ia64-2.5-sn/include/asm-ia64/meminit.h
@@ -31,6 +31,14 @@
 extern void find_initrd(void);
 extern int filter_rsvd_memory(unsigned long start, unsigned long end,
 			      void *arg);
+extern void paging_init(void);
+
+/*
+ * For rounding an address to the next IA64_GRANULE_SIZE or order
+ */
+#define GRANULEROUNDDOWN(n) ((n) & ~(IA64_GRANULE_SIZE-1))
+#define GRANULEROUNDUP(n) (((n)+IA64_GRANULE_SIZE-1) & ~(IA64_GRANULE_SIZE-1))
+#define ORDERROUNDDOWN(n) ((n) & ~((PAGE_SIZE<<MAX_ORDER)-1))
 
 #ifdef CONFIG_DISCONTIGMEM
 extern void call_pernode_memory(unsigned long start, unsigned long end, void *arg);
include/asm-ia64/mmzone.h +22 -122

179 lines not on this page · raw message

include/asm-ia64/nodedata.h +3 -26
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/include/asm-ia64/nodedata.h linux-ia64-2.5-sn/include/asm-ia64/nodedata.h
@@ -13,7 +13,7 @@
 #ifndef _ASM_IA64_NODEDATA_H
 #define _ASM_IA64_NODEDATA_H
 
-
+#include <asm/percpu.h>
 #include <asm/mmzone.h>
 
 /*
@@ -24,10 +24,7 @@
 struct ia64_node_data {
 	short			active_cpu_count;
 	short			node;
-        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];
+	struct pglist_data	*pg_data_ptrs[NR_NODES];
 };
 
 
@@ -36,41 +33,21 @@
  */
 #define local_node_data		(local_cpu_data->node_data)
 
-
-/*
- * Return a pointer to the node_data structure for the specified node.
- */
-#define node_data(node)	(local_node_data->node_data_ptrs[node])
-
 /*
  * Get a pointer to the node_id/node_data for the current cpu.
  *    (boot time only)
  */
-extern int boot_get_local_nodeid(void);
-extern struct ia64_node_data *get_node_data_ptr(void);
+extern struct ia64_node_data *early_get_node_data(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 +16 -3
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/include/asm-ia64/numa.h linux-ia64-2.5-sn/include/asm-ia64/numa.h
@@ -13,18 +13,25 @@
 
 #include <linux/config.h>
 #include <linux/cpumask.h>
+#include <linux/cache.h>
+#include <linux/threads.h>
+#include <linux/smp.h>
 
 #ifdef CONFIG_NUMA
 
 #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>
+#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;
 
@@ -65,7 +72,13 @@
 
 extern int paddr_to_nid(unsigned long paddr);
 
-#define local_nodeid (cpu_to_node_map[smp_processor_id()])
+#define nodeid() ((int)cpu_to_node_map[smp_processor_id()])
+
+#else /* !CONFIG_NUMA */
+
+#define node_distance(from,to) 10
+#define paddr_to_nid(x) 0
+#define nodeid() 0
 
 #endif /* CONFIG_NUMA */
 
include/asm-ia64/page.h +3 -5
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/include/asm-ia64/page.h linux-ia64-2.5-sn/include/asm-ia64/page.h
@@ -94,18 +94,16 @@
 
 #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 
-#ifndef CONFIG_DISCONTIGMEM
-# ifdef CONFIG_VIRTUAL_MEM_MAP
+#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
+#else
 #  define pfn_valid(pfn)	((pfn) < max_mapnr)
-# endif
+#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/percpu.h +1 -0
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/include/asm-ia64/percpu.h linux-ia64-2.5-sn/include/asm-ia64/percpu.h
@@ -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 +0 -1
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/include/asm-ia64/pgtable.h linux-ia64-2.5-sn/include/asm-ia64/pgtable.h
@@ -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)))

include/linux/mm.h +3 -2
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/include/linux/mm.h linux-ia64-2.5-sn/include/linux/mm.h
@@ -13,7 +13,8 @@
 #include <linux/rbtree.h>
 #include <linux/fs.h>
 
-#ifndef CONFIG_DISCONTIGMEM          /* Don't use mapnrs, do it properly */
+#if defined(CONFIG_VIRTUAL_MEM_MAP) || !defined(CONFIG_DISCONTIGMEM)
+/* Don't use mapnrs, do it properly */
 extern unsigned long max_mapnr;
 #endif
 
@@ -340,7 +341,7 @@
 	page->flags |= zone_num << ZONE_SHIFT;
 }
 
-#ifndef CONFIG_DISCONTIGMEM
+#if defined(CONFIG_VIRTUAL_MEM_MAP) || !defined(CONFIG_DISCONTIGMEM)
 /* The array of struct pages - for discontigmem use pgdat->lmem_map */
 extern struct page *mem_map;
 #endif
kernel/ksyms.c +1 -1
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/kernel/ksyms.c linux-ia64-2.5-sn/kernel/ksyms.c
@@ -114,7 +114,7 @@
 EXPORT_SYMBOL(vunmap);
 EXPORT_SYMBOL(vmalloc_to_page);
 EXPORT_SYMBOL(remap_page_range);
-#ifndef CONFIG_DISCONTIGMEM
+#if defined(CONFIG_VIRTUAL_MEM_MAP) || !defined(CONFIG_DISCONTIGMEM)
 EXPORT_SYMBOL(contig_page_data);
 EXPORT_SYMBOL(mem_map);
 EXPORT_SYMBOL(max_mapnr);
mm/memory.c +1 -1
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/mm/memory.c linux-ia64-2.5-sn/mm/memory.c
@@ -55,7 +55,7 @@
 
 #include <linux/swapops.h>
 
-#ifndef CONFIG_DISCONTIGMEM
+#if defined(CONFIG_VIRTUAL_MEM_MAP) || !defined(CONFIG_DISCONTIGMEM)
 /* use the per-pgdat data instead for discontigmem - mbligh */
 unsigned long max_mapnr;
 struct page *mem_map;
#1 lore raw
Quoted 2 lines · Jesse Barnes

done, like removing the shouting from GRANULEROUND* and naming nodeid() something better (maybe numa_node_id()?).

How about I just nuke it since numa_node_id() is already defined in include/linux/mmzone.h? Here's an updated version. And even though CONFIG_DISCONTIGMEM depends on CONFIG_VIRTUAL_MEM_MAP with this patch, I've left the #if defined(VIRTUAL_MEM_MAP) || !defined(DISCONTIGMEM) in the ia64 files as opposed to removing them altogether since (1) it's more consistent with the rest of the tree that way and (2) I'd like to remove that dependency so we can measure the perf. impact of virtual memmap on discontig machines like David said he wanted to do for zx1.

Thanks,
Jesse

arch/ia64/Kconfig +5 -25
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/arch/ia64/Kconfig linux-ia64-2.5-sn/arch/ia64/Kconfig
@@ -220,24 +220,8 @@
 	  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
+	bool "Discontiguous memory support" if (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC) && NUMA && VIRTUAL_MEM_MAP
 	default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA
 	help
 	  Say Y to support efficient handling of discontiguous physical memory,
@@ -250,14 +234,10 @@
 	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
-	  physical address space on non NUMA machines. Since the DISCONTIGMEM
-	  option is not supported on machines with the ZX1 chipset, this is
-	  the only way of supporting more than 1 Gb of memory on those
-	  machines. This code also only takes effect if a memory hole of
-	  greater than 1 Gb is found during boot, so it is safe to enable
-	  unless you require the DISCONTIGMEM option for your machine. If you
-	  are unsure, say Y.
+	  This code also only takes effect if a memory hole of greater than
+	  1 Gb is found during boot.  You must turn this option on if you
+	  require the DISCONTIGMEM option for your machine. If you are
+	  unsure, say Y.
 
 config IA64_MCA
 	bool "Enable IA-64 Machine Check Abort"
arch/ia64/Makefile +1 -1
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/arch/ia64/Makefile linux-ia64-2.5-sn/arch/ia64/Makefile
@@ -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
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/arch/ia64/kernel/acpi.c linux-ia64-2.5-sn/arch/ia64/kernel/acpi.c
@@ -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;
 
@@ -401,34 +401,6 @@
 	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 +7 -27
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/arch/ia64/kernel/setup.c linux-ia64-2.5-sn/arch/ia64/kernel/setup.c
@@ -101,7 +101,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
@@ -123,9 +123,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 */
@@ -237,7 +237,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 */
@@ -251,6 +250,8 @@
 # endif
 #endif /* CONFIG_APCI_BOOT */
 
+	find_memory();
+
 	/* process SAL system table: */
 	ia64_sal_init(efi.sal_systab);
 
@@ -542,28 +543,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();
 
@@ -575,7 +555,7 @@
 	 */
 	cpu_info = cpu_data + ((char *) &__ia64_per_cpu_var(cpu_info) - __per_cpu_start);
 #ifdef CONFIG_NUMA
-	cpu_info->node_data = get_node_data_ptr();
+	cpu_info->node_data = early_get_node_data();
 #endif
 	identify_cpu(cpu_info);
 
arch/ia64/mm/contig.c +33 -0
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/arch/ia64/mm/contig.c linux-ia64-2.5-sn/arch/ia64/mm/contig.c
@@ -155,3 +155,36 @@
 
 	find_initrd();
 }
+
+/**
+ * per_cpu_init - setup per-cpu variables
+ *
+ * Allocate and setup per-cpu data areas.
+ */
+void *per_cpu_init(void)
+{
+	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];
+		}
+	}
+	return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
+#else /* !CONFIG_SMP */
+	return __phys_per_cpu_start;
+#endif /* !CONFIG_SMP */
+}
arch/ia64/mm/discontig.c +250 -220

593 lines not on this page · raw message

arch/ia64/mm/init.c +83 -86

243 lines not on this page · raw message

include/asm-ia64/meminit.h +8 -0
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/include/asm-ia64/meminit.h linux-ia64-2.5-sn/include/asm-ia64/meminit.h
@@ -31,6 +31,14 @@
 extern void find_initrd(void);
 extern int filter_rsvd_memory(unsigned long start, unsigned long end,
 			      void *arg);
+extern void paging_init(void);
+
+/*
+ * For rounding an address to the next IA64_GRANULE_SIZE or order
+ */
+#define GRANULEROUNDDOWN(n) ((n) & ~(IA64_GRANULE_SIZE-1))
+#define GRANULEROUNDUP(n) (((n)+IA64_GRANULE_SIZE-1) & ~(IA64_GRANULE_SIZE-1))
+#define ORDERROUNDDOWN(n) ((n) & ~((PAGE_SIZE<<MAX_ORDER)-1))
 
 #ifdef CONFIG_DISCONTIGMEM
 extern void call_pernode_memory(unsigned long start, unsigned long end, void *arg);
include/asm-ia64/mmzone.h +26 -129

185 lines not on this page · raw message

include/asm-ia64/nodedata.h +3 -26
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/include/asm-ia64/nodedata.h linux-ia64-2.5-sn/include/asm-ia64/nodedata.h
@@ -13,7 +13,7 @@
 #ifndef _ASM_IA64_NODEDATA_H
 #define _ASM_IA64_NODEDATA_H
 
-
+#include <asm/percpu.h>
 #include <asm/mmzone.h>
 
 /*
@@ -24,10 +24,7 @@
 struct ia64_node_data {
 	short			active_cpu_count;
 	short			node;
-        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];
+	struct pglist_data	*pg_data_ptrs[NR_NODES];
 };
 
 
@@ -36,41 +33,21 @@
  */
 #define local_node_data		(local_cpu_data->node_data)
 
-
-/*
- * Return a pointer to the node_data structure for the specified node.
- */
-#define node_data(node)	(local_node_data->node_data_ptrs[node])
-
 /*
  * Get a pointer to the node_id/node_data for the current cpu.
  *    (boot time only)
  */
-extern int boot_get_local_nodeid(void);
-extern struct ia64_node_data *get_node_data_ptr(void);
+extern struct ia64_node_data *early_get_node_data(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 +8 -10
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/include/asm-ia64/numa.h linux-ia64-2.5-sn/include/asm-ia64/numa.h
@@ -13,18 +13,13 @@
 
 #include <linux/config.h>
 #include <linux/cpumask.h>
+#include <linux/cache.h>
+#include <linux/threads.h>
+#include <linux/smp.h>
+#include <asm/mmzone.h>
 
 #ifdef CONFIG_NUMA
 
-#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>
 extern volatile char cpu_to_node_map[NR_CPUS] __cacheline_aligned;
 extern volatile cpumask_t node_to_cpu_mask[NR_NODES] __cacheline_aligned;
 
@@ -65,7 +60,10 @@
 
 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
 
 #endif /* CONFIG_NUMA */
 
include/asm-ia64/page.h +3 -5
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/include/asm-ia64/page.h linux-ia64-2.5-sn/include/asm-ia64/page.h
@@ -94,18 +94,16 @@
 
 #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 
-#ifndef CONFIG_DISCONTIGMEM
-# ifdef CONFIG_VIRTUAL_MEM_MAP
+#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
+#else
 #  define pfn_valid(pfn)	((pfn) < max_mapnr)
-# endif
+#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/percpu.h +1 -0
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/include/asm-ia64/percpu.h linux-ia64-2.5-sn/include/asm-ia64/percpu.h
@@ -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 +1 -1
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/include/asm-ia64/pgtable.h linux-ia64-2.5-sn/include/asm-ia64/pgtable.h
@@ -174,7 +174,7 @@
 	return (addr & (local_cpu_data->unimpl_pa_mask)) = 0;
 }
 
-#ifndef CONFIG_DISCONTIGMEM
+#if defined(CONFIG_VIRTUAL_MEM_MAP) || !defined(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 +190,7 @@

*/
#define kern_addr_valid(addr) (1)

-#endif
+#endif /* CONFIG_VIRTUAL_MEM_MAP || !CONFIG_DISCONTIGMEM */

/*
* Now come the defines and routines to manage and access the three-level
@@ -241,10 +241,10 @@
#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
+#if defined(CONFIG_VIRTUAL_MEM_MAP) || !defined(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
+#endif /* CONFIG_VIRTUAL_MEM_MAP || !CONFIG_DISCONTIGMEM */

#define pmd_none(pmd) (!pmd_val(pmd))
#define pmd_bad(pmd) (!ia64_phys_addr_valid(pmd_val(pmd)))

include/linux/mm.h +3 -2
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/include/linux/mm.h linux-ia64-2.5-sn/include/linux/mm.h
@@ -13,7 +13,8 @@
 #include <linux/rbtree.h>
 #include <linux/fs.h>
 
-#ifndef CONFIG_DISCONTIGMEM          /* Don't use mapnrs, do it properly */
+#if defined(CONFIG_VIRTUAL_MEM_MAP) || !defined(CONFIG_DISCONTIGMEM)
+/* Don't use mapnrs, do it properly */
 extern unsigned long max_mapnr;
 #endif
 
@@ -340,7 +341,7 @@
 	page->flags |= zone_num << ZONE_SHIFT;
 }
 
-#ifndef CONFIG_DISCONTIGMEM
+#if defined(CONFIG_VIRTUAL_MEM_MAP) || !defined(CONFIG_DISCONTIGMEM)
 /* The array of struct pages - for discontigmem use pgdat->lmem_map */
 extern struct page *mem_map;
 #endif
kernel/ksyms.c +1 -1
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/kernel/ksyms.c linux-ia64-2.5-sn/kernel/ksyms.c
@@ -114,7 +114,7 @@
 EXPORT_SYMBOL(vunmap);
 EXPORT_SYMBOL(vmalloc_to_page);
 EXPORT_SYMBOL(remap_page_range);
-#ifndef CONFIG_DISCONTIGMEM
+#if defined(CONFIG_VIRTUAL_MEM_MAP) || !defined(CONFIG_DISCONTIGMEM)
 EXPORT_SYMBOL(contig_page_data);
 EXPORT_SYMBOL(mem_map);
 EXPORT_SYMBOL(max_mapnr);
mm/memory.c +1 -1
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-contig/mm/memory.c linux-ia64-2.5-sn/mm/memory.c
@@ -55,7 +55,7 @@
 
 #include <linux/swapops.h>
 
-#ifndef CONFIG_DISCONTIGMEM
+#if defined(CONFIG_VIRTUAL_MEM_MAP) || !defined(CONFIG_DISCONTIGMEM)
 /* use the per-pgdat data instead for discontigmem - mbligh */
 unsigned long max_mapnr;
 struct page *mem_map;
#2 lore raw
In reply to Jesse Barnes
Quoted 4 lines · Jesse Barnes
Quoted 2 lines · Jesse Barnes

done, like removing the shouting from GRANULEROUND* and naming nodeid() something better (maybe numa_node_id()?).

Quoted 8 lines

How about I just nuke it since numa_node_id() is already defined in include/linux/mmzone.h? Here's an updated version. And even though CONFIG_DISCONTIGMEM depends on CONFIG_VIRTUAL_MEM_MAP with this patch, I've left the #if defined(VIRTUAL_MEM_MAP) || !defined(DISCONTIGMEM) in the ia64 files as opposed to removing them altogether since (1) it's more consistent with the rest of the tree that way and (2) I'd like to remove that dependency so we can measure the perf. impact of virtual memmap on discontig machines like David said he wanted to do for zx1.

The #if defined(VIRTUAL_MEM_MAP) || !defined(DISCONTIGMEM) in generic code have to go away. All this mem_map/contig_page_data/etc crap has should probably go away some day, but for now let's not make it even messier.

Also in the discontig + vmem_map case you don't want them - always use the per-node mem_maps even if it's just to avoid the pagetable lookups and to be more similar to the other arches numa code.

More comments:

#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

What's the point of passing arg directly here if we just casted it to func? Also the ifdef is horrible. Please add a call_pernode_memory wrapper for !CONFIG_DISCONTIGMEM ala

#define call_pernode_memory(start, end, func) (*func)(start, end, 0)

What about moving call_pernode_memory to discontig.c?

--------

count_cpus() seems to reimplemement nr_cpus_node() from topology.h badly, or is it just me?

--------

per_cpu_init looks strange, in the !SMP case both implementations are identical and have an unused variable..

What about just having

#ifdef CONFIG_SMP
extern void *per_cpu_init(void);
#else

# define per_cpu_init()	(__phys_per_cpu_start)
#endif

into percpu.h?

This whole per-cpu thing looks like a candidate for the next small patch.

--------

+ if (numnodes = 1 && max_gap < LARGE_GAP) {
+ /* Just one node with no big holes... */
+ vmem_map = (struct page *)0;
+ zones_size[ZONE_DMA] += cdata.min_pfn;
+ zholes_size[ZONE_DMA] += cdata.min_pfn;
+ free_area_init_node(0, NODE_DATA(node), NODE_DATA(node)->node_mem_map,
+ zones_size, 0, zholes_size);
+ }
+ else {
+ /* allocate virtual mem_map */
+ if (node = 0) {
+ unsigned long map_size;
+ map_size = PAGE_ALIGN(max_low_pfn*sizeof(struct page));
+ vmalloc_end -= map_size;
+ vmem_map = (struct page *) vmalloc_end;
+ efi_memmap_walk(create_mem_map_page_table, 0);
+ printk("Virtual mem_map starts at 0x%p\n", vmem_map);
+ mem_map = vmem_map;
+ }
+ free_area_init_node(node, NODE_DATA(node), vmem_map + cdata.min_pfn,
+ zones_size, cdata.min_pfn, zholes_size);
+ }
}

Should look something like

		/* Just one node with no big holes... */
		if (numnodes = 1 && max_gap < LARGE_GAP) {
			zones_size[ZONE_DMA] += cdata.min_pfn;
			zholes_size[ZONE_DMA] += cdata.min_pfn;

			/* XXX: probably already done somewhere else? */
			mem_map = NODE_DATA(node)->node_mem_map; 
			pfn_offset = 0;
	
		/* allocate virtual mem_map */
		} else if (node = 0) {
			vmalloc_end -				PAGE_ALIGN(max_low_pfn * sizeof(struct page));
			mem_map = vmem_map = (struct page *)vmalloc_end;

			efi_memmap_walk(create_mem_map_page_table, 0);
			pfn_offset = cdata.min_pfn;
		}

		free_area_init_node(node, NODE_DATA(node), mem_map + pfn_offset,
				zones_size, pfn_offset, zholes_size);

--------

- pgd_populate(&init_mm, pgd, alloc_bootmem_pages(PAGE_SIZE));
+ pgd_populate(&init_mm, pgd, alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE));

This could use some linewraps :) Also alloc_bootmem_pages_node probably wants a nid argument instead of of a pgdat, but that's not really in scope for this series..

--------

asm/mmzone.h looks a bit fishy. The SN2 and generic cases are the same, why not merge them. Also the £error is ugly - it if works for the generic kernel it'll surely work for a newly added arch, too, no?

What about something like:

/* DIG systems only support rather small configurations for now */ #ifdef CONFIG_IA64_DIG
#define MAX_PHYSNODE_ID 8
#define NR_NODES 8
#define NR_MEMBLKS (NR_NODES * 32) /* interleaved, contiguous memory */
#else
/* Currently SN2 marks the maximum. Should work for everyone else, too */
#define MAX_PHYSNODE_ID 2048
#define NR_NODES 256
#define NR_MEMBLKS (NR_NODES)
#endif

And as asm/mmzone.h is only included for CONFIG_DISCONTIGMEM and ia64 couples DISCONTIG and NUMA tighly you should just scrap the non-numa case in this file

--------

-#ifndef CONFIG_DISCONTIGMEM
-# ifdef CONFIG_VIRTUAL_MEM_MAP
+#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
+#else
# define pfn_valid(pfn) ((pfn) < max_mapnr)
-# endif
+#endif

Didn't I tell you some time ago that the proper way to write this would be:

#ifdef CONFIG_VIRTUAL_MEM_MAP
extern int ia64_pfn_valid(unsigned long pfn);
#else

# define ia64_pfn_valid(pfn)	1
#endif

and then an unconditional

#define pfn_valid(pfn) (((pfn) < max_mapnr) && ia64_pfn_valid(pfn))

?

#3 lore raw
In reply to Jesse Barnes
Quoted 4 lines · Christoph Hellwig

The #if defined(VIRTUAL_MEM_MAP) || !defined(DISCONTIGMEM) in generic code have to go away. All this mem_map/contig_page_data/etc crap has should probably go away some day, but for now let's not make it even messier.

Sure, I'm all for them going away, any suggestions on how to get there?

Quoted 3 lines

Also in the discontig + vmem_map case you don't want them - always use the per-node mem_maps even if it's just to avoid the pagetable lookups and to be more similar to the other arches numa code.

The vmem_map is only used statically in arch/ia64/mm/init.c, but we use the global mem_map for the macros in include/asm-ia64/pgtable.h for convenience. There are a bunch of cases to deal with:
o CONFIG_VIRTUAL_MEM_MAP and !CONFIG_VIRTUAL_MEM_MAP
o CONFIG_DISCONTIGMEM and !CONFIG_DISCONTIGMEM
o any combination of the two above

We need CONFIG_VIRTUAL_MEM_MAP and CONFIG_DISCONTIGMEM work together at the very least so that ia64 generic kernels will work.

Quoted 11 lines

More comments:

#ifdef CONFIG_DISCONTIGMEM

arch/ia64/kernel/setup.c +1 -1
-                       call_pernode_memory(__pa(range_start), __pa(range_end), func);
+			call_pernode_memory(range_start, range_end, arg);

#else

arch/ia64/kernel/setup.c +1 -1
-                       (*func)(__pa(range_start), range_end - range_start);
+			(*func)(range_start, range_end, 0);

#endif

Quoted 3 lines

What's the point of passing arg directly here if we just casted it to func? Also the ifdef is horrible. Please add a call_pernode_memory wrapper for !CONFIG_DISCONTIGMEM ala

Ok, I was thinking of doing that anyway.

Quoted 3 lines

#define call_pernode_memory(start, end, func) (*func)(start, end, 0)

What about moving call_pernode_memory to discontig.c?

Yeah, this patch moves it there already.

Quoted 4 lines

--------

count_cpus() seems to reimplemement nr_cpus_node() from topology.h badly, or is it just me?

No, you're probably right. I'll double check and remove it (had to do the same for local_nodeid->nodeid()->numa_node_id()->NULL because it was in topology.h. I don't know where this stuff came from *sigh*).

Quoted 5 lines

per_cpu_init looks strange, in the !SMP case both implementations are identical and have an unused variable..

What about just having

Quoted 7 lines

#ifdef CONFIG_SMP
extern void *per_cpu_init(void);
#else

# define per_cpu_init()	(__phys_per_cpu_start)
#endif

into percpu.h?

Yeah, that's a good idea.

Quoted 1 line

This whole per-cpu thing looks like a candidate for the next small patch.

Sounds good.

Quoted 52 lines

--------

arch/ia64/mm/init.c +22 -0
+		if (numnodes = 1 && max_gap < LARGE_GAP) {
+			/* Just one node with no big holes... */
+			vmem_map = (struct page *)0;
+			zones_size[ZONE_DMA] += cdata.min_pfn;
+			zholes_size[ZONE_DMA] += cdata.min_pfn;
+			free_area_init_node(0, NODE_DATA(node), NODE_DATA(node)->node_mem_map,
+					    zones_size, 0, zholes_size);
+		}
+		else {
+			/* allocate virtual mem_map */
+			if (node = 0) {
+				unsigned long map_size;
+				map_size = PAGE_ALIGN(max_low_pfn*sizeof(struct page));
+				vmalloc_end -= map_size;
+				vmem_map = (struct page *) vmalloc_end;
+				efi_memmap_walk(create_mem_map_page_table, 0);
+				printk("Virtual mem_map starts at 0x%p\n", vmem_map);
+				mem_map = vmem_map;
+			}
+			free_area_init_node(node, NODE_DATA(node), vmem_map + cdata.min_pfn,
+					    zones_size, cdata.min_pfn, zholes_size);
+		}
 	}

Should look something like

		/* Just one node with no big holes... */
		if (numnodes = 1 && max_gap < LARGE_GAP) {
			zones_size[ZONE_DMA] += cdata.min_pfn;
			zholes_size[ZONE_DMA] += cdata.min_pfn;

			/* XXX: probably already done somewhere else? */
			mem_map = NODE_DATA(node)->node_mem_map; 
			pfn_offset = 0;
	
		/* allocate virtual mem_map */
		} else if (node = 0) {
			vmalloc_end -> 				PAGE_ALIGN(max_low_pfn * sizeof(struct page));
			mem_map = vmem_map = (struct page *)vmalloc_end;

			efi_memmap_walk(create_mem_map_page_table, 0);
			pfn_offset = cdata.min_pfn;
		}

		free_area_init_node(node, NODE_DATA(node), mem_map + pfn_offset,
				zones_size, pfn_offset, zholes_size);
Quoted 1 line

--------

Yep, much better.

Quoted 6 lines
arch/ia64/mm/init.c +1 -1
-                       pgd_populate(&init_mm, pgd, alloc_bootmem_pages(PAGE_SIZE));
+			pgd_populate(&init_mm, pgd, alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE));

This could use some linewraps :) Also alloc_bootmem_pages_node probably wants a nid argument instead of of a pgdat, but that's not really in scope for this series..

Sure, that's another small patch, s/alloc_bootmem_pages/alloc_bootmem_pages_node(NODE_DATA(node)/g.

Quoted 5 lines

--------

asm/mmzone.h looks a bit fishy. The SN2 and generic cases are the same, why not merge them. Also the ?error is ugly - it if works for the generic kernel it'll surely work for a newly added arch, too, no?

Probably, and making the worst case config and the generic config the same is a good idea.

Quoted 14 lines

What about something like:

/* DIG systems only support rather small configurations for now */ #ifdef CONFIG_IA64_DIG
#define MAX_PHYSNODE_ID 8
#define NR_NODES 8
#define NR_MEMBLKS (NR_NODES * 32) /* interleaved, contiguous memory */
#else
/* Currently SN2 marks the maximum. Should work for everyone else, too */
#define MAX_PHYSNODE_ID 2048
#define NR_NODES 256
#define NR_MEMBLKS (NR_NODES)
#endif

Quoted 3 lines

And as asm/mmzone.h is only included for CONFIG_DISCONTIGMEM and ia64 couples DISCONTIG and NUMA tighly you should just scrap the non-numa case in this file

Ok.

Quoted 20 lines

--------

include/asm-ia64/page.h +3 -4
-#ifndef CONFIG_DISCONTIGMEM
-# ifdef CONFIG_VIRTUAL_MEM_MAP
+#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
+#else
 #  define pfn_valid(pfn)       ((pfn) < max_mapnr)
-# endif
+#endif

Didn't I tell you some time ago that the proper way to write this would be:

#ifdef CONFIG_VIRTUAL_MEM_MAP
extern int ia64_pfn_valid(unsigned long pfn);
#else

Quoted 8 lines
# define ia64_pfn_valid(pfn)	1
#endif

and then an unconditional

#define pfn_valid(pfn) (((pfn) < max_mapnr) && ia64_pfn_valid(pfn))

?

Oops, I cleaned it up to remove a bunch of other stuff and lost that piece. I'll fix it.

Thanks,
Jesse

#4 lore raw
In reply to Jesse Barnes
Quoted 6 lines · Jesse Barnes
Quoted 4 lines

The #if defined(VIRTUAL_MEM_MAP) || !defined(DISCONTIGMEM) in generic code have to go away. All this mem_map/contig_page_data/etc crap has should probably go away some day, but for now let's not make it even messier.

Sure, I'm all for them going away, any suggestions on how to get there?

Always use the node-local mem_map, in the !DISCONTIG case we just have only one of them. But as said above this is in scope for this work (or 2.6 at all).

Quoted 11 lines
Quoted 3 lines

Also in the discontig + vmem_map case you don't want them - always use the per-node mem_maps even if it's just to avoid the pagetable lookups and to be more similar to the other arches numa code.

The vmem_map is only used statically in arch/ia64/mm/init.c, but we use the global mem_map for the macros in include/asm-ia64/pgtable.h for convenience. There are a bunch of cases to deal with:
o CONFIG_VIRTUAL_MEM_MAP and !CONFIG_VIRTUAL_MEM_MAP
o CONFIG_DISCONTIGMEM and !CONFIG_DISCONTIGMEM
o any combination of the two above

Quoted 2 lines

We need CONFIG_VIRTUAL_MEM_MAP and CONFIG_DISCONTIGMEM work together at the very least so that ia64 generic kernels will work.

Slightly less ugly hack than the ifdefs in generic code is a

#define mem_map vmem_map somewhere in a ia64 header. The right fix is to just always use the per-node mem_map. For SN2 you probably want a per-node virtual mem_map then.

#5 lore raw
In reply to Jesse Barnes
Quoted 11 lines · Christoph Hellwig
Quoted 6 lines · Jesse Barnes
Quoted 4 lines

The #if defined(VIRTUAL_MEM_MAP) || !defined(DISCONTIGMEM) in generic code have to go away. All this mem_map/contig_page_data/etc crap has should probably go away some day, but for now let's not make it even messier.

Sure, I'm all for them going away, any suggestions on how to get there?

Always use the node-local mem_map, in the !DISCONTIG case we just have only one of them. But as said above this is in scope for this work (or 2.6 at all).

Yeah, I agree, but ia64 discontig doesn't have pfn_to_nid for example, so all of that needs to be written. I'll try to tackle that next.

Quoted 5 lines

Slightly less ugly hack than the ifdefs in generic code is a

#define mem_map vmem_map somewhere in a ia64 header. The right fix is to just always use the per-node mem_map. For SN2 you probably want a per-node virtual mem_map then.

I'd rather avoid that if possible and do it correctly. Here's a new patch that incorporates almost all of your comments, as well as fixing (well, sort of) one of David's complaints about the callback data structure. I've re-seperated the discontig version of paging_init and put it in discontig.c, but I had to export a few things from init.c to do it. Please let me know what you think.

Thanks,
Jesse

arch/ia64/Kconfig +5 -25
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-bootmem/arch/ia64/Kconfig linux-ia64-2.5-discontig/arch/ia64/Kconfig
@@ -220,24 +220,8 @@
 	  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
+	bool "Discontiguous memory support" if (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC) && NUMA && VIRTUAL_MEM_MAP
 	default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA
 	help
 	  Say Y to support efficient handling of discontiguous physical memory,
@@ -250,14 +234,10 @@
 	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
-	  physical address space on non NUMA machines. Since the DISCONTIGMEM
-	  option is not supported on machines with the ZX1 chipset, this is
-	  the only way of supporting more than 1 Gb of memory on those
-	  machines. This code also only takes effect if a memory hole of
-	  greater than 1 Gb is found during boot, so it is safe to enable
-	  unless you require the DISCONTIGMEM option for your machine. If you
-	  are unsure, say Y.
+	  This code also only takes effect if a memory hole of greater than
+	  1 Gb is found during boot.  You must turn this option on if you
+	  require the DISCONTIGMEM option for your machine. If you are
+	  unsure, say Y.
 
 config IA64_MCA
 	bool "Enable IA-64 Machine Check Abort"
arch/ia64/Makefile +1 -1
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-bootmem/arch/ia64/Makefile linux-ia64-2.5-discontig/arch/ia64/Makefile
@@ -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/setup.c +6 -30
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-bootmem/arch/ia64/kernel/setup.c linux-ia64-2.5-discontig/arch/ia64/kernel/setup.c
@@ -101,7 +101,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
@@ -122,11 +122,7 @@
 		range_end   = min(end, rsvd_region[i].start);
 
 		if (range_start < range_end)
-#ifdef CONFIG_DISCONTIGMEM
-			call_pernode_memory(__pa(range_start), __pa(range_end), func);
-#else
-			(*func)(__pa(range_start), range_end - range_start);
-#endif
+			call_pernode_memory(range_start, range_end, arg);
 
 		/* nothing more available in this segment */
 		if (range_end = end) return 0;
@@ -239,7 +235,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 */
@@ -253,6 +248,8 @@
 # endif
 #endif /* CONFIG_APCI_BOOT */
 
+	find_memory();
+
 	/* process SAL system table: */
 	ia64_sal_init(efi.sal_systab);
 
@@ -544,28 +541,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();
 
@@ -577,7 +553,7 @@
 	 */
 	cpu_info = cpu_data + ((char *) &__ia64_per_cpu_var(cpu_info) - __per_cpu_start);
 #ifdef CONFIG_NUMA
-	cpu_info->node_data = get_node_data_ptr();
+	cpu_info->node_data = early_get_node_data();
 #endif
 	identify_cpu(cpu_info);
 
arch/ia64/mm/contig.c +31 -0
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-bootmem/arch/ia64/mm/contig.c linux-ia64-2.5-discontig/arch/ia64/mm/contig.c
@@ -161,3 +161,34 @@
 
 	find_initrd();
 }
+
+/**
+ * per_cpu_init - setup per-cpu variables
+ *
+ * Allocate and setup per-cpu data areas.
+ */
+void *per_cpu_init(void)
+{
+	void *cpu_data;
+	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];
+		}
+	}
+	return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
+}
arch/ia64/mm/discontig.c +387 -221

730 lines not on this page · raw message

arch/ia64/mm/init.c +8 -18
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-bootmem/arch/ia64/mm/init.c linux-ia64-2.5-discontig/arch/ia64/mm/init.c
@@ -24,7 +24,7 @@
 #include <asm/ia32.h>
 #include <asm/io.h>
 #include <asm/machvec.h>
-#include <asm/numa.h>
+#include <asm/meminit.h>
 #include <asm/patch.h>
 #include <asm/pgalloc.h>
 #include <asm/sal.h>
@@ -43,8 +43,8 @@
 #ifdef CONFIG_VIRTUAL_MEM_MAP
 # define LARGE_GAP	0x40000000	/* Use virtual mem map if hole is > than this */
   unsigned long vmalloc_end = VMALLOC_END_INIT;
-  static struct page *vmem_map;
-  static unsigned long num_dma_physpages;
+  struct page *vmem_map;
+  unsigned long num_dma_physpages;
 #endif
 
 static int pgt_cache_water[2] = { 25, 50 };
@@ -338,7 +338,7 @@
 
 #ifdef CONFIG_VIRTUAL_MEM_MAP
 
-static int
+int
 create_mem_map_page_table (u64 start, u64 end, void *arg)
 {
 	unsigned long address, start_page, end_page;
@@ -446,7 +446,7 @@
 	return 0;
 }
 
-static int
+int
 find_largest_hole (u64 start, u64 end, void *arg)
 {
 	u64 *max_gap = arg;
@@ -462,6 +462,7 @@
 }
 #endif /* CONFIG_VIRTUAL_MEM_MAP */
 
+#ifndef CONFIG_DISCONTIGMEM
 static int
 count_pages (u64 start, u64 end, void *arg)
 {
@@ -475,17 +476,6 @@
  * Set up the page tables.
  */
 
-#ifdef CONFIG_DISCONTIGMEM
-void
-paging_init (void)
-{
-	extern void discontig_paging_init(void);
-
-	discontig_paging_init();
-	efi_memmap_walk(count_pages, &num_physpages);
-	zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
-}
-#else /* !CONFIG_DISCONTIGMEM */
 void
 paging_init (void)
 {
@@ -609,11 +599,11 @@
 	platform_dma_init();
 #endif
 
-#ifndef CONFIG_DISCONTIGMEM
+#if defined(CONFIG_VIRTUAL_MEM_MAP) || !defined(CONFIG_DISCONTIGMEM)
 	if (!mem_map)
 		BUG();
 	max_mapnr = max_low_pfn;
-#endif
+#endif /* CONFIG_VIRTUAL_MEM_MAP || !CONFIG_DISCONTIGMEM */
 
 	high_memory = __va(max_low_pfn * PAGE_SIZE);
 
include/asm-ia64/meminit.h +20 -0
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-bootmem/include/asm-ia64/meminit.h linux-ia64-2.5-discontig/include/asm-ia64/meminit.h
@@ -31,11 +31,31 @@
 extern void reserve_memory (void);
 extern void find_initrd (void);
 extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg);
+extern void paging_init(void);
+ 
+/*
+ * For rounding an address to the next IA64_GRANULE_SIZE or order
+ */
+#define GRANULEROUNDDOWN(n) ((n) & ~(IA64_GRANULE_SIZE-1))
+#define GRANULEROUNDUP(n) (((n)+IA64_GRANULE_SIZE-1) & ~(IA64_GRANULE_SIZE-1))
+#define ORDERROUNDDOWN(n) ((n) & ~((PAGE_SIZE<<MAX_ORDER)-1))
 
 #ifdef CONFIG_DISCONTIGMEM
 extern void call_pernode_memory (unsigned long start, unsigned long end, void *arg);
+#else
+#define call_pernode_memory(start, end, func)	(*func)(start, end, 0)
 #endif
 
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+#define LARGE_GAP 0x40000000 /* Use virtual mem map if hole is > than this */
+extern unsigned long vmalloc_end;
+extern struct page *vmem_map;
+extern unsigned long num_dma_physpages;
+extern int find_largest_hole(u64 start, u64 end, void *arg);
+extern int create_mem_map_page_table(u64 start, u64 end, void *arg);
+#endif
+
+
 #define IGNORE_PFN0	1	/* XXX fix me: ignore pfn 0 until TLB miss handler is updated... */
 
 #endif /* meminit_h */
include/asm-ia64/mmzone.h +10 -145

169 lines not on this page · raw message

include/asm-ia64/nodedata.h +3 -26
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-bootmem/include/asm-ia64/nodedata.h linux-ia64-2.5-discontig/include/asm-ia64/nodedata.h
@@ -13,7 +13,7 @@
 #ifndef _ASM_IA64_NODEDATA_H
 #define _ASM_IA64_NODEDATA_H
 
-
+#include <asm/percpu.h>
 #include <asm/mmzone.h>
 
 /*
@@ -24,10 +24,7 @@
 struct ia64_node_data {
 	short			active_cpu_count;
 	short			node;
-        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];
+	struct pglist_data	*pg_data_ptrs[NR_NODES];
 };
 
 
@@ -36,41 +33,21 @@
  */
 #define local_node_data		(local_cpu_data->node_data)
 
-
-/*
- * Return a pointer to the node_data structure for the specified node.
- */
-#define node_data(node)	(local_node_data->node_data_ptrs[node])
-
 /*
  * Get a pointer to the node_id/node_data for the current cpu.
  *    (boot time only)
  */
-extern int boot_get_local_nodeid(void);
-extern struct ia64_node_data *get_node_data_ptr(void);
+extern struct ia64_node_data *early_get_node_data(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 +6 -14
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-bootmem/include/asm-ia64/numa.h linux-ia64-2.5-discontig/include/asm-ia64/numa.h
@@ -13,18 +13,13 @@
 
 #include <linux/config.h>
 #include <linux/cpumask.h>
+#include <linux/cache.h>
+#include <linux/threads.h>
+#include <linux/smp.h>
+#include <asm/mmzone.h>
 
 #ifdef CONFIG_NUMA
 
-#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>
 extern volatile char cpu_to_node_map[NR_CPUS] __cacheline_aligned;
 extern volatile cpumask_t node_to_cpu_mask[NR_NODES] __cacheline_aligned;
 
@@ -65,13 +60,10 @@
 
 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(addr)	0
-#define local_nodeid		0
+#define node_distance(from,to) 10
+#define paddr_to_nid(x) 0
 
 #endif /* CONFIG_NUMA */
 
include/asm-ia64/page.h +6 -7
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-bootmem/include/asm-ia64/page.h linux-ia64-2.5-discontig/include/asm-ia64/page.h
@@ -94,18 +94,17 @@
 
 #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 
-#ifndef CONFIG_DISCONTIGMEM
-# ifdef CONFIG_VIRTUAL_MEM_MAP
+#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
+#else
+#  define ia64_pfn_valid(pfn)	1
+#endif
+
+#define pfn_valid(pfn)		(((pfn) < max_mapnr) && ia64_pfn_valid(pfn))
 #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/percpu.h +2 -0
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-bootmem/include/asm-ia64/percpu.h linux-ia64-2.5-discontig/include/asm-ia64/percpu.h
@@ -46,11 +46,13 @@
 
 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 */
 
 #define per_cpu(var, cpu)			((void)cpu, per_cpu__##var)
 #define __get_cpu_var(var)			per_cpu__##var
+#define per_cpu_init()				(__phys_per_cpu_start)
 
 #endif	/* SMP */
 
include/asm-ia64/pgtable.h +0 -1
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-bootmem/include/asm-ia64/pgtable.h linux-ia64-2.5-discontig/include/asm-ia64/pgtable.h
@@ -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)))

include/linux/mm.h +3 -2
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-bootmem/include/linux/mm.h linux-ia64-2.5-discontig/include/linux/mm.h
@@ -13,7 +13,8 @@
 #include <linux/rbtree.h>
 #include <linux/fs.h>
 
-#ifndef CONFIG_DISCONTIGMEM          /* Don't use mapnrs, do it properly */
+#if defined(CONFIG_VIRTUAL_MEM_MAP) || !defined(CONFIG_DISCONTIGMEM)
+/* Don't use mapnrs, do it properly */
 extern unsigned long max_mapnr;
 #endif
 
@@ -340,7 +341,7 @@
 	page->flags |= zone_num << ZONE_SHIFT;
 }
 
-#ifndef CONFIG_DISCONTIGMEM
+#if defined(CONFIG_VIRTUAL_MEM_MAP) || !defined(CONFIG_DISCONTIGMEM)
 /* The array of struct pages - for discontigmem use pgdat->lmem_map */
 extern struct page *mem_map;
 #endif
kernel/ksyms.c +1 -1
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-bootmem/kernel/ksyms.c linux-ia64-2.5-discontig/kernel/ksyms.c
@@ -114,7 +114,7 @@
 EXPORT_SYMBOL(vunmap);
 EXPORT_SYMBOL(vmalloc_to_page);
 EXPORT_SYMBOL(remap_page_range);
-#ifndef CONFIG_DISCONTIGMEM
+#if defined(CONFIG_VIRTUAL_MEM_MAP) || !defined(CONFIG_DISCONTIGMEM)
 EXPORT_SYMBOL(contig_page_data);
 EXPORT_SYMBOL(mem_map);
 EXPORT_SYMBOL(max_mapnr);
mm/memory.c +1 -1
diff -Naur -X /home/jbarnes/dontdiff --exclude=MAINTAINERS --exclude=pci_irq.c --exclude=tables.c --exclude=qla1280.c --exclude=logo --exclude=char linux-ia64-2.5-bootmem/mm/memory.c linux-ia64-2.5-discontig/mm/memory.c
@@ -55,7 +55,7 @@
 
 #include <linux/swapops.h>
 
-#ifndef CONFIG_DISCONTIGMEM
+#if defined(CONFIG_VIRTUAL_MEM_MAP) || !defined(CONFIG_DISCONTIGMEM)
 /* use the per-pgdat data instead for discontigmem - mbligh */
 unsigned long max_mapnr;
 struct page *mem_map;
#6 lore raw
In reply to Jesse Barnes
Quoted 22 lines · Jesse Barnes
Quoted 11 lines · Christoph Hellwig
Quoted 6 lines · Jesse Barnes
Quoted 4 lines

The #if defined(VIRTUAL_MEM_MAP) || !defined(DISCONTIGMEM) in generic code have to go away. All this mem_map/contig_page_data/etc crap has should probably go away some day, but for now let's not make it even messier.

Sure, I'm all for them going away, any suggestions on how to get there?

Always use the node-local mem_map, in the !DISCONTIG case we just have only one of them. But as said above this is in scope for this work (or 2.6 at all).

Yeah, I agree, but ia64 discontig doesn't have pfn_to_nid for example, so all of that needs to be written. I'll try to tackle that next.

Quoted 5 lines

Slightly less ugly hack than the ifdefs in generic code is a

#define mem_map vmem_map somewhere in a ia64 header. The right fix is to just always use the per-node mem_map. For SN2 you probably want a per-node virtual mem_map then.

Quoted 6 lines

I'd rather avoid that if possible and do it correctly. Here's a new patch that incorporates almost all of your comments, as well as fixing (well, sort of) one of David's complaints about the callback data structure. I've re-seperated the discontig version of paging_init and put it in discontig.c, but I had to export a few things from init.c to do it. Please let me know what you think.

This patch fixes the last one by not changing around the callback args. All are physical addr, length pairs now.

Thanks,
Jesse

arch/ia64/Kconfig +5 -25
diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig
@@ -220,24 +220,8 @@
 	  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
+	bool "Discontiguous memory support" if (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC) && NUMA && VIRTUAL_MEM_MAP
 	default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA
 	help
 	  Say Y to support efficient handling of discontiguous physical memory,
@@ -250,14 +234,10 @@
 	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
-	  physical address space on non NUMA machines. Since the DISCONTIGMEM
-	  option is not supported on machines with the ZX1 chipset, this is
-	  the only way of supporting more than 1 Gb of memory on those
-	  machines. This code also only takes effect if a memory hole of
-	  greater than 1 Gb is found during boot, so it is safe to enable
-	  unless you require the DISCONTIGMEM option for your machine. If you
-	  are unsure, say Y.
+	  This code also only takes effect if a memory hole of greater than
+	  1 Gb is found during boot.  You must turn this option on if you
+	  require the DISCONTIGMEM option for your machine. If you are
+	  unsure, say Y.
 
 config IA64_MCA
 	bool "Enable IA-64 Machine Check Abort"
arch/ia64/Makefile +1 -1
diff -Nru a/arch/ia64/Makefile b/arch/ia64/Makefile
@@ -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/setup.c +7 -30
diff -Nru a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
@@ -101,7 +101,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
@@ -122,11 +122,8 @@
 		range_end   = min(end, rsvd_region[i].start);
 
 		if (range_start < range_end)
-#ifdef CONFIG_DISCONTIGMEM
-			call_pernode_memory(__pa(range_start), __pa(range_end), func);
-#else
-			(*func)(__pa(range_start), range_end - range_start);
-#endif
+			call_pernode_memory(__pa(range_start),
+					    range_end - range_start, func);
 
 		/* nothing more available in this segment */
 		if (range_end = end) return 0;
@@ -239,7 +236,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 */
@@ -253,6 +249,8 @@
 # endif
 #endif /* CONFIG_APCI_BOOT */
 
+	find_memory();
+
 	/* process SAL system table: */
 	ia64_sal_init(efi.sal_systab);
 
@@ -544,28 +542,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();
 
@@ -577,7 +554,7 @@
 	 */
 	cpu_info = cpu_data + ((char *) &__ia64_per_cpu_var(cpu_info) - __per_cpu_start);
 #ifdef CONFIG_NUMA
-	cpu_info->node_data = get_node_data_ptr();
+	cpu_info->node_data = early_get_node_data();
 #endif
 	identify_cpu(cpu_info);
 
arch/ia64/mm/contig.c +31 -0
diff -Nru a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c
@@ -161,3 +161,34 @@
 
 	find_initrd();
 }
+
+/**
+ * per_cpu_init - setup per-cpu variables
+ *
+ * Allocate and setup per-cpu data areas.
+ */
+void *per_cpu_init(void)
+{
+	void *cpu_data;
+	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];
+		}
+	}
+	return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
+}
arch/ia64/mm/discontig.c +387 -227

733 lines not on this page · raw message

arch/ia64/mm/init.c +8 -17
diff -Nru a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
@@ -24,6 +24,7 @@
 #include <asm/ia32.h>
 #include <asm/io.h>
 #include <asm/machvec.h>
+#include <asm/meminit.h>
 #include <asm/patch.h>
 #include <asm/pgalloc.h>
 #include <asm/sal.h>
@@ -42,8 +43,8 @@
 #ifdef CONFIG_VIRTUAL_MEM_MAP
 # define LARGE_GAP	0x40000000	/* Use virtual mem map if hole is > than this */
   unsigned long vmalloc_end = VMALLOC_END_INIT;
-  static struct page *vmem_map;
-  static unsigned long num_dma_physpages;
+  struct page *vmem_map;
+  unsigned long num_dma_physpages;
 #endif
 
 static int pgt_cache_water[2] = { 25, 50 };
@@ -337,11 +338,12 @@
 
 #ifdef CONFIG_VIRTUAL_MEM_MAP
 
-static int
+int
 create_mem_map_page_table (u64 start, u64 end, void *arg)
 {
 	unsigned long address, start_page, end_page;
@@ -443,7 +446,7 @@
 	return 0;
 }
 
-static int
+int
 find_largest_hole (u64 start, u64 end, void *arg)
 {
 	u64 *max_gap = arg;
@@ -459,6 +462,7 @@
 }
 #endif /* CONFIG_VIRTUAL_MEM_MAP */
 
+#ifndef CONFIG_DISCONTIGMEM
 static int
 count_pages (u64 start, u64 end, void *arg)
 {
@@ -472,17 +476,6 @@
  * Set up the page tables.
  */
 
-#ifdef CONFIG_DISCONTIGMEM
-void
-paging_init (void)
-{
-	extern void discontig_paging_init(void);
-
-	discontig_paging_init();
-	efi_memmap_walk(count_pages, &num_physpages);
-	zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
-}
-#else /* !CONFIG_DISCONTIGMEM */
 void
 paging_init (void)
 {
@@ -606,11 +599,11 @@
 	platform_dma_init();
 #endif
 
-#ifndef CONFIG_DISCONTIGMEM
+#if defined(CONFIG_VIRTUAL_MEM_MAP) || !defined(CONFIG_DISCONTIGMEM)
 	if (!mem_map)
 		BUG();
 	max_mapnr = max_low_pfn;
-#endif
+#endif /* CONFIG_VIRTUAL_MEM_MAP || !CONFIG_DISCONTIGMEM */
 
 	high_memory = __va(max_low_pfn * PAGE_SIZE);
 
include/asm-ia64/meminit.h +22 -1
diff -Nru a/include/asm-ia64/meminit.h b/include/asm-ia64/meminit.h
@@ -31,10 +31,31 @@
 extern void reserve_memory (void);
 extern void find_initrd (void);
 extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg);
+extern void paging_init(void);
+ 
+/*
+ * For rounding an address to the next IA64_GRANULE_SIZE or order
+ */
+#define GRANULEROUNDDOWN(n) ((n) & ~(IA64_GRANULE_SIZE-1))
+#define GRANULEROUNDUP(n) (((n)+IA64_GRANULE_SIZE-1) & ~(IA64_GRANULE_SIZE-1))
+#define ORDERROUNDDOWN(n) ((n) & ~((PAGE_SIZE<<MAX_ORDER)-1))
 
 #ifdef CONFIG_DISCONTIGMEM
-extern void call_pernode_memory (unsigned long start, unsigned long end, void *arg);
+extern void call_pernode_memory(unsigned long start, unsigned long len,
+				void *func);
+#else
+#define call_pernode_memory(start, len, func)	(*func)(start, len, 0)
 #endif
+
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+#define LARGE_GAP 0x40000000 /* Use virtual mem map if hole is > than this */
+extern unsigned long vmalloc_end;
+extern struct page *vmem_map;
+extern unsigned long num_dma_physpages;
+extern int find_largest_hole(u64 start, u64 end, void *arg);
+extern int create_mem_map_page_table(u64 start, u64 end, void *arg);
+#endif
+
 
 #define IGNORE_PFN0	1	/* XXX fix me: ignore pfn 0 until TLB miss handler is updated... */
 
include/asm-ia64/mmzone.h +10 -145

169 lines not on this page · raw message

include/asm-ia64/nodedata.h +7 -25
diff -Nru a/include/asm-ia64/nodedata.h b/include/asm-ia64/nodedata.h
@@ -13,9 +13,12 @@
 #ifndef _ASM_IA64_NODEDATA_H
 #define _ASM_IA64_NODEDATA_H
 
-
+#include <linux/config.h>
+#include <asm/percpu.h>
 #include <asm/mmzone.h>
 
+#ifdef CONFIG_DISCONTIGMEM
+
 /*
  * Node Data. One of these structures is located on each node of a NUMA system.
  */
@@ -24,10 +27,7 @@
 struct ia64_node_data {
 	short			active_cpu_count;
 	short			node;
-        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];
+	struct pglist_data	*pg_data_ptrs[NR_NODES];
 };
 
 
@@ -36,41 +36,23 @@
  */
 #define local_node_data		(local_cpu_data->node_data)
 
-
-/*
- * Return a pointer to the node_data structure for the specified node.
- */
-#define node_data(node)	(local_node_data->node_data_ptrs[node])
-
 /*
  * Get a pointer to the node_id/node_data for the current cpu.
  *    (boot time only)
  */
-extern int boot_get_local_nodeid(void);
-extern struct ia64_node_data *get_node_data_ptr(void);
+extern struct ia64_node_data *early_get_node_data(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 /* CONFIG_DISCONTIGMEM */
 
 #endif /* _ASM_IA64_NODEDATA_H */
include/asm-ia64/numa.h +8 -10
diff -Nru a/include/asm-ia64/numa.h b/include/asm-ia64/numa.h
@@ -13,18 +13,13 @@
 
 #include <linux/config.h>
 #include <linux/cpumask.h>
+#include <linux/cache.h>
+#include <linux/threads.h>
+#include <linux/smp.h>
+#include <asm/mmzone.h>
 
 #ifdef CONFIG_NUMA
 
-#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>
 extern volatile char cpu_to_node_map[NR_CPUS] __cacheline_aligned;
 extern volatile cpumask_t node_to_cpu_mask[NR_NODES] __cacheline_aligned;
 
@@ -65,7 +60,10 @@
 
 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
 
 #endif /* CONFIG_NUMA */
 
include/asm-ia64/page.h +6 -7
diff -Nru a/include/asm-ia64/page.h b/include/asm-ia64/page.h
@@ -94,18 +94,17 @@
 
 #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 
-#ifndef CONFIG_DISCONTIGMEM
-# ifdef CONFIG_VIRTUAL_MEM_MAP
+#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
+#else
+#  define ia64_pfn_valid(pfn)	1
+#endif
+
+#define pfn_valid(pfn)		(((pfn) < max_mapnr) && ia64_pfn_valid(pfn))
 #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/percpu.h +2 -0
diff -Nru a/include/asm-ia64/percpu.h b/include/asm-ia64/percpu.h
@@ -46,11 +46,13 @@
 
 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 */
 
 #define per_cpu(var, cpu)			((void)cpu, per_cpu__##var)
 #define __get_cpu_var(var)			per_cpu__##var
+#define per_cpu_init()				(__phys_per_cpu_start)
 
 #endif	/* SMP */
 
include/asm-ia64/pgtable.h +0 -1
diff -Nru a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
@@ -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)))

include/linux/mm.h +3 -2
diff -Nru a/include/linux/mm.h b/include/linux/mm.h
@@ -13,7 +13,8 @@
 #include <linux/rbtree.h>
 #include <linux/fs.h>
 
-#ifndef CONFIG_DISCONTIGMEM          /* Don't use mapnrs, do it properly */
+#if defined(CONFIG_VIRTUAL_MEM_MAP) || !defined(CONFIG_DISCONTIGMEM)
+/* Don't use mapnrs, do it properly */
 extern unsigned long max_mapnr;
 #endif
 
@@ -340,7 +341,7 @@
 	page->flags |= zone_num << ZONE_SHIFT;
 }
 
-#ifndef CONFIG_DISCONTIGMEM
+#if defined(CONFIG_VIRTUAL_MEM_MAP) || !defined(CONFIG_DISCONTIGMEM)
 /* The array of struct pages - for discontigmem use pgdat->lmem_map */
 extern struct page *mem_map;
 #endif
kernel/ksyms.c +1 -1
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
@@ -114,7 +114,7 @@
 EXPORT_SYMBOL(vunmap);
 EXPORT_SYMBOL(vmalloc_to_page);
 EXPORT_SYMBOL(remap_page_range);
-#ifndef CONFIG_DISCONTIGMEM
+#if defined(CONFIG_VIRTUAL_MEM_MAP) || !defined(CONFIG_DISCONTIGMEM)
 EXPORT_SYMBOL(contig_page_data);
 EXPORT_SYMBOL(mem_map);
 EXPORT_SYMBOL(max_mapnr);
mm/memory.c +1 -1
diff -Nru a/mm/memory.c b/mm/memory.c
@@ -55,7 +55,7 @@
 
 #include <linux/swapops.h>
 
-#ifndef CONFIG_DISCONTIGMEM
+#if defined(CONFIG_VIRTUAL_MEM_MAP) || !defined(CONFIG_DISCONTIGMEM)
 /* use the per-pgdat data instead for discontigmem - mbligh */
 unsigned long max_mapnr;
 struct page *mem_map;
#7 lore raw
In reply to Jesse Barnes
Quoted 2 lines · Jesse Barnes

This patch fixes the last one by not changing around the callback args. All are physical addr, length pairs now.

Oh, and it doesn't break zx1 either. Boot tested zx1 and sn2 configs.

Jesse