Skip to contentSkip to conversation

discontig patch (still ugly)

PATCH In review Jesse Barnes 2 participants 2 messages Sep 22, 2003

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 discontig patch (still ugly)

Ok, here's a new patch that addresses the problems below, just for reference. I'll split out the contig.c stuff and send that seperately in a minute.

Quoted 2 lines · David Mosberger

- in acpi.c, it looks like there is no reason for min_hole_size anymore, yet the patch doesn't clean up this variable

I had just removed that printk at Xavier's request and missed that it wasn't being used anymore. Fixed.

Quoted 2 lines

- MAX_RSVD_REGIONS et al got moved to pgtable.h; why in the world would that be the right place? Just because "it compiled"??

No, because that was necessary for the contig.c/discontig.c seperation. Which header file would be better?

Quoted 1 line

- why is there both vmem_map and mem_map in the NUMA case?

You mean for the discontig case? mem_map isn't there. It only exists (mm/memory.c) if CONFIG_DISCONTIGMEM is off, otherwise we just use vmem_map and pgdata_t->node_mem_map for everything.

Right now (and even without this patch) the config options are kind of a mess. CONFIG_DISCONTIGMEM doesn't make sense without CONFIG_NUMA and CONFIG_VIRTUAL_MEMMAP even though they should all be independent. I'll try to clean that up too.

Thanks,
Jesse

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas:
# ChangeSet 1.1245 -> 1.1246
# arch/ia64/Makefile 1.60 -> 1.61
# include/asm-ia64/page.h 1.21 -> 1.22
# arch/ia64/kernel/setup.c 1.57 -> 1.58
# include/asm-ia64/pgtable.h 1.28 -> 1.29
# arch/ia64/mm/Makefile 1.7 -> 1.8
# include/asm-ia64/numa.h 1.6 -> 1.7
# include/asm-ia64/processor.h 1.50 -> 1.51
# arch/ia64/mm/init.c 1.47 -> 1.48
# arch/ia64/kernel/acpi.c 1.50 -> 1.51
# include/asm-ia64/nodedata.h 1.3 -> 1.4
# include/asm-ia64/percpu.h 1.12 -> 1.13
# arch/ia64/mm/discontig.c 1.4 -> 1.5
# arch/ia64/Kconfig 1.43 -> 1.44
# include/asm-ia64/mmzone.h 1.4 -> 1.5
# (new) -> 1.1 arch/ia64/mm/contig.c
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/09/22 [email protected] 1.1246

# discontig
# --------------------------------------------
#
diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig
--- a/arch/ia64/Kconfig	Mon Sep 22 15:18:18 2003
+++ b/arch/ia64/Kconfig	Mon Sep 22 15:18:18 2003
@@ -220,22 +220,6 @@
 	  Access).  This option is for configuring high-end multiprocessor
 	  server systems.  If in doubt, say N.

-choice
- prompt "Maximum Memory per NUMA Node" if NUMA && IA64_DIG
- depends on NUMA && IA64_DIG
- default IA64_NODESIZE_16GB
-
-config IA64_NODESIZE_16GB
- bool "16GB"
-
-config IA64_NODESIZE_64GB
- bool "64GB"
-
-config IA64_NODESIZE_256GB
- bool "256GB"
-
-endchoice
-
config DISCONTIGMEM
bool "Discontiguous memory support" if (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC) && NUMA default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA

arch/ia64/Makefile +1 -1
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 +1 -29
diff -Nru a/arch/ia64/kernel/acpi.c b/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;
 
@@ -400,34 +400,6 @@
 	/* Ignore disabled entries */
 	if (!ma->flags.enabled)
 		return;
-
-	/*
-	 * When the chunk is not the first one in the node, check distance
-	 * from the other chunks. When the hole is too huge ignore the chunk.
-	 * This restriction should be removed when multiple chunks per node
-	 * is supported.
-	 */
-	pend = &node_memblk[num_memblks];
-	min_hole_size = 0;
-	for (p = &node_memblk[0]; p < pend; p++) {
-		if (p->nid != pxm)
-			continue;
-		if (p->start_paddr < paddr)
-			hole_size = paddr - (p->start_paddr + p->size);
-		else
-			hole_size = p->start_paddr - (paddr + size);
-
-		if (!min_hole_size || hole_size < min_hole_size)
-			min_hole_size = hole_size;
-	}
-
-	if (min_hole_size) {
-		if (min_hole_size > size) {
-			printk(KERN_ERR "Too huge memory hole. Ignoring %ld MBytes at %lx\n",
-			       size/(1024*1024), paddr);
-			return;
-		}
-	}
 
 	/* record this node in proximity bitmap */
 	pxm_bit_set(pxm);
arch/ia64/kernel/setup.c +10 -157

218 lines not on this page · raw message

arch/ia64/mm/Makefile +3 -0
diff -Nru a/arch/ia64/mm/Makefile b/arch/ia64/mm/Makefile
@@ -7,3 +7,6 @@
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
 obj-$(CONFIG_NUMA)	   += numa.o
 obj-$(CONFIG_DISCONTIGMEM) += discontig.o
+ifndef CONFIG_DISCONTIGMEM
+obj-y += contig.o
+endif
arch/ia64/mm/contig.c new file +131 -0

131 lines not on this page · raw message

arch/ia64/mm/discontig.c +219 -156

490 lines not on this page · raw message

arch/ia64/mm/init.c +88 -137

302 lines not on this page · raw message

include/asm-ia64/mmzone.h +22 -122

179 lines not on this page · raw message

include/asm-ia64/nodedata.h +9 -30
diff -Nru a/include/asm-ia64/nodedata.h b/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>
 
 /*
@@ -22,15 +22,17 @@
 
 struct pglist_data;
 struct ia64_node_data {
-	short			active_cpu_count;
 	short			node;
+	short			active_cpu_count;
+	/*
+	 * The fields are read-only (after boot). They contain pointers
+	 * to various structures located on other nodes. Ths data is
+	 * replicated on each node in order to reduce off-node references.
+	 */
         struct pglist_data	*pg_data_ptrs[NR_NODES];
-	struct page		*bank_mem_map_base[NR_BANKS];
 	struct ia64_node_data	*node_data_ptrs[NR_NODES];
-	short			node_id_map[NR_BANKS];
 };
 
-
 /*
  * Return a pointer to the node_data structure for the executing cpu.
  */
@@ -40,7 +42,8 @@
 /*
  * Return a pointer to the node_data structure for the specified node.
  */
-#define node_data(node)	(local_node_data->node_data_ptrs[node])
+#define node_data(node) (local_node_data->node_data_ptrs[node])
+#define NODE_DATA(nid) (local_node_data->pg_data_ptrs[nid])
 
 /*
  * Get a pointer to the node_id/node_data for the current cpu.
@@ -48,29 +51,5 @@
  */
 extern int boot_get_local_nodeid(void);
 extern struct ia64_node_data *get_node_data_ptr(void);
-
-/*
- * Given a node id, return a pointer to the pg_data_t for the node.
- * The following 2 macros are similar. 
- *
- * NODE_DATA 	- should be used in all code not related to system
- *		  initialization. It uses pernode data structures to minimize
- *		  offnode memory references. However, these structure are not 
- *		  present during boot. This macro can be used once cpu_init
- *		  completes.
- *
- * BOOT_NODE_DATA
- *		- should be used during system initialization 
- *		  prior to freeing __initdata. It does not depend on the percpu
- *		  area being present.
- *
- * NOTE:   The names of these macros are misleading but are difficult to change
- *	   since they are used in generic linux & on other architecures.
- */
-#define NODE_DATA(nid)		(local_node_data->pg_data_ptrs[nid])
-#define BOOT_NODE_DATA(nid)	boot_get_pg_data_ptr((long)(nid))
-
-struct pglist_data;
-extern struct pglist_data * __init boot_get_pg_data_ptr(long);
 
 #endif /* _ASM_IA64_NODEDATA_H */
include/asm-ia64/numa.h +15 -1
diff -Nru a/include/asm-ia64/numa.h b/include/asm-ia64/numa.h
@@ -15,13 +15,21 @@
 
 #ifdef CONFIG_DISCONTIGMEM
 # include <asm/mmzone.h>
-# define NR_MEMBLKS   (NR_BANKS)
 #else
 # define NR_NODES     (8)
 # define NR_MEMBLKS   (NR_NODES * 8)
 #endif
 
 #include <linux/cache.h>
+#include <linux/threads.h>
+#include <linux/smp.h>
+
+#define NODEMASK_WORDCOUNT       ((NR_NODES+(BITS_PER_LONG-1))/BITS_PER_LONG)
+
+#define NODE_MASK_NONE   { [0 ... ((NR_NODES+BITS_PER_LONG-1)/BITS_PER_LONG)-1] = 0 }
+
+typedef unsigned long   nodemask_t[NODEMASK_WORDCOUNT];
+                                                                                                                             
 extern volatile char cpu_to_node_map[NR_CPUS] __cacheline_aligned;
 extern volatile cpumask_t node_to_cpu_mask[NR_NODES] __cacheline_aligned;
 
@@ -63,6 +71,12 @@
 extern int paddr_to_nid(unsigned long paddr);
 
 #define local_nodeid (cpu_to_node_map[smp_processor_id()])
+
+#else /* !CONFIG_NUMA */
+
+#define node_distance(from,to) 10
+#define paddr_to_nid(x) 0
+#define local_nodeid 0
 
 #endif /* CONFIG_NUMA */
 
include/asm-ia64/page.h +18 -10
diff -Nru a/include/asm-ia64/page.h b/include/asm-ia64/page.h
@@ -94,18 +94,26 @@
 
 #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 
-#ifndef CONFIG_DISCONTIGMEM
-# ifdef CONFIG_VIRTUAL_MEM_MAP
-   extern int ia64_pfn_valid (unsigned long pfn);
-#  define pfn_valid(pfn)	(((pfn) < max_mapnr) && ia64_pfn_valid(pfn))
-# else
-#  define pfn_valid(pfn)	((pfn) < max_mapnr)
-# endif
-#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
-#define page_to_pfn(page)	((unsigned long) (page - mem_map))
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+extern int ia64_pfn_valid(unsigned long pfn);
+#else
+#define ia64_pfn_valid(pfn) (1)
+#endif
+
+extern unsigned long max_low_pfn;
+#define pfn_valid(pfn) (((pfn) < max_low_pfn) && ia64_pfn_valid(pfn))
+
+#if defined(CONFIG_VIRTUAL_MEM_MAP)
+extern struct page *vmem_map;
+#define pfn_to_page(pfn)	(vmem_map + (pfn))
+#define page_to_pfn(page)	((unsigned long) (page - vmem_map))
+#else
 #define pfn_to_page(pfn)	(mem_map + (pfn))
-#define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
+#define page_to_pfn(page)	((unsigned long) (page - mem_map))
 #endif
+
+#define virt_to_page(kaddr)	(pfn_to_page(__pa(kaddr) >> PAGE_SHIFT))
+#define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
 
 typedef union ia64_va {
 	struct {
include/asm-ia64/percpu.h +1 -0
diff -Nru a/include/asm-ia64/percpu.h b/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 +28 -4
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)))
@@ -415,7 +411,35 @@
 }
 
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+extern unsigned long MAX_DMA_ADDRESS;
+
+/*
+ * Entries defined so far:
+ * 	- boot param structure itself
+ * 	- memory map
+ * 	- initrd (optional)
+ * 	- command line string
+ * 	- kernel code & data
+ *
+ * More could be added if necessary
+ */
+struct rsvd_region {
+	unsigned long start;	/* virtual address of beginning of element */
+	unsigned long end;	/* virtual address of end of element + 1 */
+};
+#define IA64_MAX_RSVD_REGIONS 5
+extern struct rsvd_region rsvd_region[IA64_MAX_RSVD_REGIONS + 1];
+extern int num_rsvd_regions;
 extern void paging_init (void);
+extern int filter_rsvd_memory(unsigned long start, unsigned long end, void *arg);
+#ifdef CONFIG_DISCONTIGMEM
+extern void discontig_mem_init(void);
+extern void call_pernode_memory(unsigned long start, unsigned long end, void *arg);
+#else
+extern unsigned long bootmap_start;
+extern int find_max_pfn(unsigned long start, unsigned long end, void *arg);
+extern int find_bootmap_location(unsigned long start, unsigned long end, void *arg);
+#endif
 
 /*
  * Note: The macros below rely on the fact that MAX_SWAPFILES_SHIFT <= number of
include/asm-ia64/processor.h +2 -0
diff -Nru a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h
@@ -186,6 +186,8 @@
 #endif
 #ifdef CONFIG_NUMA
 	struct ia64_node_data *node_data;
+	struct cpuinfo_ia64 *cpu_data[NR_CPUS];
+	int nodeid;
 #endif
 };
 
#1 lore raw
Quoted 3 lines
Quoted 3 lines

- MAX_RSVD_REGIONS et al got moved to pgtable.h; why in the world would that be the right place? Just because "it compiled"??

Jesse> No, because that was necessary for the contig.c/discontig.c Jesse> seperation. Which header file would be better?

I think it could be just a local header file in arch/ia64/kernel/.

Quoted 1 line
Quoted 1 line

- why is there both vmem_map and mem_map in the NUMA case?

Jesse> You mean for the discontig case? mem_map isn't there. It Jesse> only exists (mm/memory.c) if CONFIG_DISCONTIGMEM is off, Jesse> otherwise we just use vmem_map and pgdata_t->node_mem_map for Jesse> everything.

Then fix mm/memory.c to define mem_map if CONFIG_VIRTUAL_MEMMAP is on.

	--david