Skip to contentSkip to conversation

more discontig stuff

PATCH In review Jesse Barnes 2 participants 5 messages Sep 30, 2003 – Oct 6, 2003

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 more discontig stuff

Here's the latest.

o removed changes to kernel/ksyms.c, mm/memory.c and include/linux/mm.h
o created discontig specific versions of pfn_valid, page_to_pfn, and pfn_to_page (still almost identical to those in include/asm/page.h though)
o added #ifdef CONFIG_DISCONTIGMEM include/asm/mmzone.h header file
o other misc. fixes

Generic kernels work on sn2, and probably work on other NUMA platforms, but fail on zx1 at the first alloc_pages() call. Kernels configured specifically for zx1 still work though.

 arch/ia64/Kconfig           |   37 --
 arch/ia64/Makefile          |    2 
 arch/ia64/kernel/setup.c    |   38 --
 arch/ia64/mm/contig.c       |  122 ++++++++
 arch/ia64/mm/discontig.c    |  612 +++++++++++++++++++++++++++-----------------
 arch/ia64/mm/init.c         |  131 +--------
 arch/ia64/sn/kernel/setup.c |    2 
 include/asm-ia64/meminit.h  |   24 +
 include/asm-ia64/mmzone.h   |  159 +----------
 include/asm-ia64/nodedata.h |   32 --
 include/asm-ia64/numa.h     |   18 -
 include/asm-ia64/page.h     |   14 -
 include/asm-ia64/percpu.h   |    2 
 include/asm-ia64/pgtable.h  |    4 

Jesse

arch/ia64/Kconfig +10 -27
diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig
@@ -64,8 +64,6 @@
 
 	  To find out what type of IA-64 system you have, you may want to
 	  check the IA-64 Linux web site at <http://www.linux-ia64.org/>.
-	  As of the time of this writing, most hardware is DIG compliant,
-	  so the "DIG-compliant" option is usually the right choice.
 
 	  HP-simulator   For the HP simulator
 	  (<http://software.hp.com/ia64linux/>).
@@ -91,6 +89,11 @@
 
 config IA64_SGI_SN2
 	bool "SGI-SN2"
+	help
+	  Build a kernel for SGI sn2-based systems.  Choosing this option
+	  rather than building a generic kernel will provide a small
+	  performance boost at the cost of not being able to use the kernel
+	  binary on non-Altix systems.
 
 endchoice
 
@@ -220,24 +223,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 +237,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 +6 -32
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();
 
@@ -576,9 +553,6 @@
 	 * accessing cpu_data() through the canonical per-CPU address.
 	 */
 	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();
-#endif
 	identify_cpu(cpu_info);
 
 #ifdef CONFIG_MCKINLEY
arch/ia64/mm/contig.c +120 -0

123 lines not on this page · raw message

arch/ia64/mm/discontig.c +379 -229

722 lines not on this page · raw message

arch/ia64/mm/init.c +21 -110

190 lines not on this page · raw message

arch/ia64/sn/kernel/setup.c +0 -2
diff -Nru a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
@@ -147,7 +147,6 @@
  * Sets up an initial console to aid debugging.  Intended primarily
  * for bringup.  See start_kernel() in init/main.c.
  */
-#if defined(CONFIG_IA64_EARLY_PRINTK_SGI_SN) || defined(CONFIG_IA64_SGI_SN_SIM)
 
 void __init
 early_sn_setup(void)
@@ -189,7 +188,6 @@
 		printk(KERN_DEBUG "early_sn_setup: setting master_node_bedrock_address to 0x%lx\n", master_node_bedrock_address);
 	}
 }
-#endif /* CONFIG_IA64_EARLY_PRINTK_SGI_SN */
 
 #ifdef CONFIG_IA64_MCA
 extern int platform_intr_list[];
include/asm-ia64/meminit.h +23 -1
diff -Nru a/include/asm-ia64/meminit.h b/include/asm-ia64/meminit.h
@@ -31,10 +31,32 @@
 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);
+extern int count_dma_pages(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 +17 -142

176 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 -8
diff -Nru a/include/asm-ia64/page.h b/include/asm-ia64/page.h
@@ -94,18 +94,16 @@
 
 #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 
+extern int ia64_pfn_valid (unsigned long pfn);
+
 #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 pfn_valid(pfn)		(((pfn) < max_mapnr) && ia64_pfn_valid(pfn))
 #define page_to_pfn(page)	((unsigned long) (page - mem_map))
 #define pfn_to_page(pfn)	(mem_map + (pfn))
+#endif /* CONFIG_DISCONTIGMEM */
+
 #define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
-#endif
+#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
 
 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)))

#1 lore raw
Quoted 10 lines · Jesse Barnes

Here's the latest.

o removed changes to kernel/ksyms.c, mm/memory.c and include/linux/mm.h
o created discontig specific versions of pfn_valid, page_to_pfn, and pfn_to_page (still almost identical to those in include/asm/page.h though)
o added #ifdef CONFIG_DISCONTIGMEM include/asm/mmzone.h header file
o other misc. fixes

Quoted 3 lines

Generic kernels work on sn2, and probably work on other NUMA platforms, but fail on zx1 at the first alloc_pages() call. Kernels configured specifically for zx1 still work though.

... not too much on our DIG64 platform ;-(
But the previous one dated sept 23 looked OK :-)
The manifestation of the problem is that all pages allocation with GFP_DMA fail:

	swapper: page allocation failure. order:0, mode:0x21

Comparing with the working (sept 23) version:
. The zone structs on first __alloc_pages all have free_pages = 0 except for last zone that is on node 3.
. free_all_bootmem_core seems OK.
Any idea ?
Thaks in advance for your help.
Xavier

Traces --------------------------------------------------------------
Placing software IO TLB between 0xe000000004b58000 - 0xe000000004d58000
free_all_bootmem_core: pgdatà00000004b40000 page 007fffc2c50000, idx000, mapà00000004b48000 count>645
free_all_bootmem_core: pgdatà00001000050000 page 007fffd6c00000, idx@000, mapà00001000000000 count?ae4
free_all_bootmem_core: pgdatà00002000060000 page 007fffeac00000, idx@000, mapà00002000000000 count?ae5
free_all_bootmem_core: pgdatà00003000070000 page 007ffffec00000, idx@000, mapà00003000000000 count?ab5
Memory: 16606656k/16695072k available (6727k code, 96848k reserved,
3185k data, 448k init)

upon first __alloc_pages (OK):
------------------------
0xa0000001000e1580 __alloc_pages

        args (0xd0, 0x0, 0xe000000004a42700)
        kernel <NULL> 0x0 0xa0000001000e1580 0x0
0xa0000001000e1d60 __get_free_pages+0xc0
        args (0xd0, 0x0, 0xa0000001000e9700, 0x50d)
        kernel <NULL> 0x0 0xa0000001000e1ca0 0x0

0xa0000001000e9700 cache_grow+0x220

[0]kdb> md 0xe000000004A42700

0xe000000004a42700 04a40d00 e0000000 04a40000 e0000000   ..¤....à..¤....à
0xe000000004a42710 00050d00 e0000010 00060d00 e0000020   .......à.... ..à
0xe000000004a42720 00070d00 e0000030 00000000 00000000   ....0..à........
0xe000000004a42730 00000000 00000000 00000000 00000000   ................
0xe000000004a42740 00000000 00000000 00000000 00000000   ................
0xe000000004a42750 00000000 00000000 00000000 00000000   ................
0xe000000004a42760 00000000 00000000 00000000 00000000   ................
0xe000000004a42770 00000000 00000000 00000000 00000000   ................
[0]kdb>
0xe000000004a42780 00000000 00000000 00000000 00000000   ................
0xe000000004a42790 00000000 00000000 00000000 00000000   ................
0xe000000004a427a0 00000000 00000000 00000000 00000000   ................
0xe000000004a427b0 00000000 00000000 00000000 00000000   ................
0xe000000004a427c0 00000000 00000000 04a40000 e0000000   ..........¤....à
0xe000000004a427d0 00000000 00000000 00000000 00000000   ................
0xe000000004a427e0 00000000 00000000 00000000 00000000   ................
0xe000000004a427f0 00000000 00000000 00000000 00000000   ................
[0]kdb> md E000000004A40D00
0xe000000004a40d00 00000000 00000000 00000000 00000000
                                     XXXXXXXXXXXX
0xe000000004a40d10 00000008 00000000 00000010 00000000   ................
0xe000000004a40d20 00000018 00000000 00000000 00000000   ................
0xe000000004a40d30 00000000 00000000 00000000 00000000   ................
0xe000000004a40d40 00000000 00000000 00000000 00000000   ................
0xe000000004a40d50 00000000 00000000 00000000 00000000   ................
0xe000000004a40d60 00000000 00000000 00000000 00000000   ................
0xe000000004a40d70 00000000 00000000 00000000 00000000   ................
[0]kdb> md E000000004A40000
0xe000000004a40000 00000000 00000000 00000000 00000000   ................
0xe000000004a40010 00000007 00000000 0000000e 00000000   ................
0xe000000004a40020 00000015 00000000 00000000 00000000   ................
0xe000000004a40030 00000000 00000000 00000000 00000000   ................
0xe000000004a40040 00000000 00000000 00000000 00000000   ................
0xe000000004a40050 00000000 00000000 00000000 00000000   ................
0xe000000004a40060 00000000 00000000 00000000 00000000   ................
0xe000000004a40070 00000000 00000000 00000000 00000000   ................
[0]kdb> md E000001000050D00
0xe000001000050d00 00000000 00000000 00000000 00000000   ................
0xe000001000050d10 00000010 00000000 00000020 00000000   ........ .......
0xe000001000050d20 00000030 00000000 00000000 00000000   0...............
0xe000001000050d30 00000000 00000000 00000000 00000000   ................
0xe000001000050d40 00000000 00000000 00000000 00000000   ................
0xe000001000050d50 00000000 00000000 00000000 00000000   ................
0xe000001000050d60 00000000 00000000 00000000 00000000   ................
0xe000001000050d70 00000000 00000000 00000000 00000000   ................
[0]kdb> md E000002000060D00
0xe000002000060d00 00000000 00000000 00000000 00000000   ................
0xe000002000060d10 00000010 00000000 00000020 00000000   ........ .......
0xe000002000060d20 00000030 00000000 00000000 00000000   0...............
0xe000002000060d30 00000000 00000000 00000000 00000000   ................
0xe000002000060d40 00000000 00000000 00000000 00000000   ................
0xe000002000060d50 00000000 00000000 00000000 00000000   ................
0xe000002000060d60 00000000 00000000 00000000 00000000   ................
0xe000002000060d70 00000000 00000000 00000000 00000000   ................
[0]kdb> md E000003000070D00
0xe000003000070d00 00000000 00000000 000de9d4 00000000   ........Ôé......
					XXXXXX
0xe000003000070d10 00000010 00000000 00000020 00000000   ........ .......
0xe000003000070d20 00000030 00000000 00000000 00000000   0...............
0xe000003000070d30 00000000 00000000 00000000 00000000   ................
0xe000003000070d40 00000000 00000000 00000000 00000000   ................
0xe000003000070d50 00000000 00000000 00000000 00000000   ................
0xe000003000070d60 00000000 00000000 00000000 00000000   ................

0xe000003000070d70 00000000 00000000 00000000 00000000
................

Upon DMA __alloc_pages (FAILS)
----------------------
0xa0000001000e1580 __alloc_pages

        args (0x21, 0x0, 0xe000000004a427c8)
        kernel <NULL> 0x0 0xa0000001000e1580 0x0
0xa0000001000e1d60 __get_free_pages+0xc0
        args (0x21, 0x0, 0xa000000100305c40, 0x309)
        kernel <NULL> 0x0 0xa0000001000e1ca0 0x0

0xa000000100305c40 swiotlb_alloc_coherent+0x80

0xe000000004a427c8 04a40000 e0000000 00000000 00000000

0xe000000004a40000 00000000 00000000 00000000 00000000 ................
XXXXXXXX free_pages

0xe000000004a40010 00000007 00000000 0000000e 00000000   ................
0xe000000004a40020 00000015 00000000 00000000 00000000   ................
0xe000000004a40030 00000000 00000000 00000000 00000000   ................
Signature · 8 lines
 Sincères salutations.
_____________________________________________________________________
 
Xavier BRU                 BULL ISD/R&D/INTEL office:     FREC B1-422
tel : +33 (0)4 76 29 77 45                    http://www-frec.bull.fr
fax : +33 (0)4 76 29 77 70                 mailto:[email protected]
addr: BULL, 1 rue de Provence, BP 208, 38432 Echirolles Cedex, FRANCE
_____________________________________________________________________
#2 lore raw
In reply to Jesse Barnes
Quoted 1 line · Xavier Bru

... not too much on our DIG64 platform ;-(

Thanks for looking at it.

Quoted 1 line

But the previous one dated sept 23 looked OK :-)

I fixed a few bugs in the patch since I posted it. Can you try this one? I'll have to try your kdb patch too...

A really dumb bug that I introduced while trying to go above 64p was the is_headless_node() thing (but I don't think that would affect your platform). any_online_cpu(cpumask_t) is undefined if there are no bits set.

Thanks,
Jesse

arch/ia64/Kconfig +10 -27
diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig
@@ -64,8 +64,6 @@
 
 	  To find out what type of IA-64 system you have, you may want to
 	  check the IA-64 Linux web site at <http://www.linux-ia64.org/>.
-	  As of the time of this writing, most hardware is DIG compliant,
-	  so the "DIG-compliant" option is usually the right choice.
 
 	  HP-simulator   For the HP simulator
 	  (<http://software.hp.com/ia64linux/>).
@@ -91,6 +89,11 @@
 
 config IA64_SGI_SN2
 	bool "SGI-SN2"
+	help
+	  Build a kernel for SGI sn2-based systems.  Choosing this option
+	  rather than building a generic kernel will provide a small
+	  performance boost at the cost of not being able to use the kernel
+	  binary on non-Altix systems.
 
 endchoice
 
@@ -220,24 +223,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 +237,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/acpi.c +2 -2
diff -Nru a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
@@ -420,7 +420,7 @@
 		if (!min_hole_size || hole_size < min_hole_size)
 			min_hole_size = hole_size;
 	}
-
+#if 0
 	if (min_hole_size) {
 		if (min_hole_size > size) {
 			printk(KERN_ERR "Too huge memory hole. Ignoring %ld MBytes at %lx\n",
@@ -428,7 +428,7 @@
 			return;
 		}
 	}
-
+#endif
 	/* record this node in proximity bitmap */
 	pxm_bit_set(pxm);
 
arch/ia64/kernel/setup.c +6 -32
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();
 
@@ -576,9 +553,6 @@
 	 * accessing cpu_data() through the canonical per-CPU address.
 	 */
 	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();
-#endif
 	identify_cpu(cpu_info);
 
 #ifdef CONFIG_MCKINLEY
arch/ia64/mm/contig.c +120 -0

123 lines not on this page · raw message

arch/ia64/mm/discontig.c +383 -227

720 lines not on this page · raw message

arch/ia64/mm/init.c +21 -110

190 lines not on this page · raw message

arch/ia64/sn/kernel/setup.c +0 -2
diff -Nru a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
@@ -147,7 +147,6 @@
  * Sets up an initial console to aid debugging.  Intended primarily
  * for bringup.  See start_kernel() in init/main.c.
  */
-#if defined(CONFIG_IA64_EARLY_PRINTK_SGI_SN) || defined(CONFIG_IA64_SGI_SN_SIM)
 
 void __init
 early_sn_setup(void)
@@ -189,7 +188,6 @@
 		printk(KERN_DEBUG "early_sn_setup: setting master_node_bedrock_address to 0x%lx\n", master_node_bedrock_address);
 	}
 }
-#endif /* CONFIG_IA64_EARLY_PRINTK_SGI_SN */
 
 #ifdef CONFIG_IA64_MCA
 extern int platform_intr_list[];
include/asm-ia64/meminit.h +23 -1
diff -Nru a/include/asm-ia64/meminit.h b/include/asm-ia64/meminit.h
@@ -31,10 +31,32 @@
 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);
+extern int count_dma_pages(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 +17 -142

176 lines not on this page · raw message

include/asm-ia64/nodedata.h +6 -30
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,17 @@
  */
 #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);
-
 /*
  * 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 -8
diff -Nru a/include/asm-ia64/page.h b/include/asm-ia64/page.h
@@ -94,18 +94,16 @@
 
 #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 
+extern int ia64_pfn_valid (unsigned long pfn);
+
 #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 pfn_valid(pfn)		(((pfn) < max_mapnr) && ia64_pfn_valid(pfn))
 #define page_to_pfn(page)	((unsigned long) (page - mem_map))
 #define pfn_to_page(pfn)	(mem_map + (pfn))
+#endif /* CONFIG_DISCONTIGMEM */
+
 #define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
-#endif
+#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
 
 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/asm-ia64/sn/nodepda.h +1 -1
diff -Nru a/include/asm-ia64/sn/nodepda.h b/include/asm-ia64/sn/nodepda.h
@@ -128,7 +128,7 @@
  * Check if given a compact node id the corresponding node has all the
  * cpus disabled. 
  */
-#define is_headless_node(cnode)		(!any_online_cpu(node_to_cpumask(cnode)))
+#define is_headless_node(cnode)		(!node_to_cpu_mask[cnode])
 
 /*
  * Check if given a node vertex handle the corresponding node has all the
#3 lore raw
In reply to Jesse Barnes

Hi Jesse

Thanks for your answer. This new one boots OK with CONFIG_NUMA (zones have now free_pages non 0 at first __alloc_pages).

I applied it on 2.6.0-test5 + your patch dated Sept 22.

I just added a fix to prevent some redeclarations in meminit.h with gcc 3.2 :

include/asm-ia64/meminit.h renamed from include/asm-ia64/meminit.h 2003-10-06 10:51:45.000000000 +0200 +3 -0
@@ -14,6 +14,8 @@
  *
  * More could be added if necessary
  */
+#ifndef _ASM_IA64_MEMINIT_H
+#define _ASM_IA64_MEMINIT_H
 #define IA64_MAX_RSVD_REGIONS 5
 
 struct rsvd_region {
@@ -58,3 +60,4 @@
 
 #define IGNORE_PFN0	1	/* XXX fix me: ignore pfn 0 until TLB miss
 				   handler is updated... */
+#endif /* _ASM_IA64_MEMINIT_H */

Thanks again.

Signature · 8 lines
 Sincères salutations.
_____________________________________________________________________
 
Xavier BRU                 BULL ISD/R&D/INTEL office:     FREC B1-422
tel : +33 (0)4 76 29 77 45                    http://www-frec.bull.fr
fax : +33 (0)4 76 29 77 70                 mailto:[email protected]
addr: BULL, 1 rue de Provence, BP 208, 38432 Echirolles Cedex, FRANCE
_____________________________________________________________________
Quoted 18 lines · Jesse Barnes
Quoted 1 line · Xavier Bru

... not too much on our DIG64 platform ;-(

Thanks for looking at it.

Quoted 1 line

But the previous one dated sept 23 looked OK :-)

I fixed a few bugs in the patch since I posted it. Can you try this one? I'll have to try your kdb patch too...

A really dumb bug that I introduced while trying to go above 64p was the is_headless_node() thing (but I don't think that would affect your platform). any_online_cpu(cpumask_t) is undefined if there are no bits set.

Thanks,
Jesse

#4 lore raw
In reply to Jesse Barnes
Quoted 28 lines · Xavier Bru

Hi Jesse

Thanks for your answer. This new one boots OK with CONFIG_NUMA (zones have now free_pages non 0 at first __alloc_pages).

I applied it on 2.6.0-test5 + your patch dated Sept 22.

I just added a fix to prevent some redeclarations in meminit.h with gcc 3.2 :

include/asm-ia64/meminit.h renamed from include/asm-ia64/meminit.h 2003-10-06 10:51:45.000000000 +0200 +3 -0
@@ -14,6 +14,8 @@
  *
  * More could be added if necessary
  */
+#ifndef _ASM_IA64_MEMINIT_H
+#define _ASM_IA64_MEMINIT_H
 #define IA64_MAX_RSVD_REGIONS 5
 
 struct rsvd_region {
@@ -58,3 +60,4 @@
 
 #define IGNORE_PFN0	1	/* XXX fix me: ignore pfn 0 until TLB miss
 				   handler is updated... */
+#endif /* _ASM_IA64_MEMINIT_H */
Quoted 1 line

Thanks again.

Yeah, David added that to his tree before he put the patch in. I'll have to rediff once he comes back and comes out with a patch against -test6 (or maybe -test7 by then).

Thanks a lot for helping me keep this patch working, I really appreciate it!

Jesse