Skip to contentSkip to conversation

Sparse Memory Handling (hot-add foundation)

RFC PATCH In review Dave Hansen 4 participants 9 messages Feb 18, 2005 – Feb 19, 2005

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

RFC PATCH 1/1 Sparse Memory Handling (hot-add foundation)

The attached patch, largely written by Andy Whitcroft, implements a feature which is similar to DISCONTIGMEM, but has some added features. Instead of splitting up the mem_map for each NUMA node, this splits it up into areas that represent fixed blocks of memory. This allows individual pieces of that memory to be easily added and removed.

Because it is so similar to DISCONTIGMEM, it can actually be used in place of it on NUMA systems such as the NUMAQ, or Summit architectures. This patch includes an i386 and ppc64 implementation, but there are x86_64 and ia64 implementations as well.

There are a number of individual patches (with descriptions) which are rolled up in the attached patch: all of the files up to and including "G2-no-memory-at-high_memory-ppc64.patch" from this directory:
http://www.sr71.net/patches/2.6.11/2.6.11-rc3-mhp1/broken-out/

I can post individual patches if anyone would like to comment on them.

-- Dave

arch/arm/mm/init.c renamed from arch/arm/mm/init.c~A6-no_arch_mem_map_init +0 -4
@@ -501,10 +501,6 @@
 				bdata->node_boot_start >> PAGE_SHIFT, zhole_size);
 	}
 
-#ifndef CONFIG_DISCONTIGMEM
-	mem_map = contig_page_data.node_mem_map;
-#endif
-
 	/*
 	 * finish off the bad pages once
 	 * the mem_map is initialised
arch/arm26/mm/init.c renamed from arch/arm26/mm/init.c~A6-no_arch_mem_map_init +0 -2
@@ -309,8 +309,6 @@
 	free_area_init_node(0, pgdat, zone_size,
 			bdata->node_boot_start >> PAGE_SHIFT, zhole_size);
 
-	mem_map = NODE_DATA(0)->node_mem_map;
-
 	/*
 	 * finish off the bad pages once
 	 * the mem_map is initialised
arch/cris/arch-v10/mm/init.c renamed from arch/cris/arch-v10/mm/init.c~A6-no_arch_mem_map_init +0 -1
@@ -184,7 +184,6 @@
 	 */
 
 	free_area_init_node(0, &contig_page_data, zones_size, PAGE_OFFSET >> PAGE_SHIFT, 0);
-	mem_map = contig_page_data.node_mem_map;
 }
 
 /* Initialize remaps of some I/O-ports. It is important that this
arch/i386/Kconfig renamed from arch/i386/Kconfig~B-sparse-080-alloc_remap-i386 +9 -3
@@ -68,7 +68,7 @@
 
 config X86_NUMAQ
 	bool "NUMAQ (IBM/Sequent)"
-	select DISCONTIGMEM
+	#select DISCONTIGMEM
 	select NUMA
 	help
 	  This option is used for getting Linux to run on a (IBM/Sequent) NUMA
@@ -759,16 +759,22 @@
 comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI"
 	depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI)
 
-config DISCONTIGMEM
+config HAVE_ARCH_BOOTMEM_NODE
 	bool
 	depends on NUMA
 	default y
 
-config HAVE_ARCH_BOOTMEM_NODE
+config HAVE_ARCH_ALLOC_REMAP
 	bool
 	depends on NUMA
 	default y
 
+config ARCH_SPARSEMEM_DEFAULT
+	bool
+	depends on (X86_NUMAQ || X86_SUMMIT)
+
+source "mm/Kconfig"
+
 config HIGHPTE
 	bool "Allocate 3rd-level pagetables from highmem"
 	depends on HIGHMEM4G || HIGHMEM64G
arch/i386/kernel/numaq.c renamed from arch/i386/kernel/numaq.c~B-sparse-140-abstract-discontig +3 -1
@@ -32,7 +32,7 @@
 #include <asm/numaq.h>
 
 /* These are needed before the pgdat's are created */
-extern long node_start_pfn[], node_end_pfn[];
+extern long node_start_pfn[], node_end_pfn[], node_remap_size[];
 
 #define	MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT))
 
@@ -59,6 +59,8 @@
 				eq->hi_shrd_mem_start - eq->priv_mem_size);
 			node_end_pfn[node] = MB_TO_PAGES(
 				eq->hi_shrd_mem_start + eq->hi_shrd_mem_size);
+			node_remap_size[node] += memory_present(node,
+				node_start_pfn[node], node_end_pfn[node]);
 		}
 	}
 }
arch/i386/kernel/setup.c renamed from arch/i386/kernel/setup.c~FROM-MM-refactor-i386-memory-setup +70 -11

133 lines not on this page · raw message

arch/i386/kernel/srat.c renamed from arch/i386/kernel/srat.c~B-sparse-140-abstract-discontig +5 -1
@@ -58,7 +58,7 @@
 static int zholes_size_init;
 static unsigned long zholes_size[MAX_NUMNODES * MAX_NR_ZONES];
 
-extern unsigned long node_start_pfn[], node_end_pfn[];
+extern unsigned long node_start_pfn[], node_end_pfn[], node_remap_size[];
 
 extern void * boot_ioremap(unsigned long, unsigned long);
 
@@ -266,6 +266,10 @@
 		       j, node_memory_chunk[j].nid,
 		       node_memory_chunk[j].start_pfn,
 		       node_memory_chunk[j].end_pfn);
+		node_remap_size[node_memory_chunk[j].nid] += memory_present(
+						node_memory_chunk[j].nid,
+						node_memory_chunk[j].start_pfn,
+						node_memory_chunk[j].end_pfn);
 	}
  
 	/*calculate node_start_pfn/node_end_pfn arrays*/
arch/i386/mm/Makefile renamed from arch/i386/mm/Makefile~B-sparse-160-sparsemem-i386 +1 -1
@@ -4,7 +4,7 @@
 
 obj-y	:= init.o pgtable.o fault.o ioremap.o extable.o pageattr.o mmap.o
 
-obj-$(CONFIG_DISCONTIGMEM)	+= discontig.o
+obj-$(CONFIG_NUMA) += discontig.o
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
 obj-$(CONFIG_HIGHMEM) += highmem.o
 obj-$(CONFIG_BOOT_IOREMAP) += boot_ioremap.o
arch/i386/mm/boot_ioremap.c renamed from arch/i386/mm/boot_ioremap.c~FROM-MM-mostly-i386-mm-cleanup +2 -2
@@ -61,8 +61,8 @@
 /* the virtual space we're going to remap comes from this array */
 #define BOOT_IOREMAP_PAGES 4
 #define BOOT_IOREMAP_SIZE (BOOT_IOREMAP_PAGES*PAGE_SIZE)
-__initdata char boot_ioremap_space[BOOT_IOREMAP_SIZE] 
-		__attribute__ ((aligned (PAGE_SIZE)));
+static __initdata char boot_ioremap_space[BOOT_IOREMAP_SIZE]
+		       __attribute__ ((aligned (PAGE_SIZE)));
 
 /*
  * This only applies to things which need to ioremap before paging_init()
arch/i386/mm/discontig.c renamed from arch/i386/mm/discontig.c~FROM-MM-consolidate-set_max_mapnr_init-implementations +111 -178

417 lines not on this page · raw message

arch/i386/mm/init.c renamed from arch/i386/mm/init.c~FROM-MM-consolidate-set_max_mapnr_init-implementations +21 -50

154 lines not on this page · raw message

arch/ia64/mm/contig.c renamed from arch/ia64/mm/contig.c~A6-no_arch_mem_map_init +1 -1
@@ -283,7 +283,7 @@
 		vmem_map = (struct page *) vmalloc_end;
 		efi_memmap_walk(create_mem_map_page_table, NULL);
 
-		mem_map = contig_page_data.node_mem_map = vmem_map;
+		NODE_DATA(0)->node_mem_map = vmem_map;
 		free_area_init_node(0, &contig_page_data, zones_size,
 				    0, zholes_size);
 
arch/m32r/mm/init.c renamed from arch/m32r/mm/init.c~A6-no_arch_mem_map_init +0 -2
@@ -121,8 +121,6 @@
 
 	free_area_init_node(0, NODE_DATA(0), zones_size, start_pfn, 0);
 
-	mem_map = contig_page_data.node_mem_map;
-
 	return 0;
 }
 #else	/* CONFIG_DISCONTIGMEM */
arch/ppc64/Kconfig renamed from arch/ppc64/Kconfig~B-sparse-170-sparsemem-ppc64 +19 -4
@@ -192,17 +192,32 @@
 	depends on SMP
 	default "32"
 
+config ARCH_HAS_BOOTPA
+	bool
+	default y
+
 config HMT
 	bool "Hardware multithreading"
 	depends on SMP && PPC_PSERIES
 
-config DISCONTIGMEM
-	bool "Discontiguous Memory Support"
-	depends on SMP && PPC_PSERIES
+source "mm/Kconfig"
+
+config ARCH_SPARSEMEM_DEFAULT
+	bool
+	depends on PPC_PSERIES
+
+config ARCH_DISCONTIGMEM_DISABLE
+	bool
+	depends on !SMP || !PPC_PSERIES
+
+config ARCH_SPARSEMEM_DISABLE
+	bool
+	depends on !SMP || !PPC_PSERIES
 
 config NUMA
 	bool "NUMA support"
-	depends on DISCONTIGMEM
+	default y if (DISCONTIGMEM)
+	default y if (SPARSEMEM)
 
 config SCHED_SMT
 	bool "SMT (Hyperthreading) scheduler support"
arch/ppc64/kernel/prom_init.c renamed from arch/ppc64/kernel/prom_init.c~G0-ppc64-__boot-fixes +4 -4
@@ -913,11 +913,11 @@
 	extern unsigned long __secondary_hold_spinloop;
 	extern unsigned long __secondary_hold_acknowledge;
 	unsigned long *spinloop
-		= (void *)virt_to_abs(&__secondary_hold_spinloop);
+		= (void *)boot_virt_to_abs(&__secondary_hold_spinloop);
 	unsigned long *acknowledge
-		= (void *)virt_to_abs(&__secondary_hold_acknowledge);
+		= (void *)boot_virt_to_abs(&__secondary_hold_acknowledge);
 	unsigned long secondary_hold
-		= virt_to_abs(*PTRRELOC((unsigned long *)__secondary_hold));
+		= boot_virt_to_abs(*PTRRELOC((unsigned long *)__secondary_hold));
 	struct prom_t *_prom = PTRRELOC(&prom);
 
 	prom_debug("prom_hold_cpus: start...\n");
@@ -1563,7 +1563,7 @@
 	if ( r3 && r4 && r4 != 0xdeadbeef) {
 		u64 val;
 
-		RELOC(prom_initrd_start) = (r3 >= KERNELBASE) ? __pa(r3) : r3;
+		RELOC(prom_initrd_start) = (r3 >= KERNELBASE) ? __boot_pa(r3) : r3;
 		RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
 
 		val = (u64)RELOC(prom_initrd_start);
arch/ppc64/kernel/rtas.c renamed from arch/ppc64/kernel/rtas.c~G0-ppc64-__boot-fixes +4 -2
@@ -36,6 +36,7 @@
 struct rtas_t rtas = { 
 	.lock = SPIN_LOCK_UNLOCKED
 };
+static unsigned long rtas_args_paddr;
 
 EXPORT_SYMBOL(rtas);
 
@@ -192,8 +193,7 @@
 	for (i = 0; i < nret; ++i)
 		rtas_args->rets[i] = 0;
 
-	PPCDBG(PPCDBG_RTAS, "\tentering rtas with 0x%lx\n",
-		__pa(rtas_args));
+	PPCDBG(PPCDBG_RTAS, "\tentering rtas with 0x%lx\n", rtas_args_paddr);
 	enter_rtas(__pa(rtas_args));
 	PPCDBG(PPCDBG_RTAS, "\treturned from rtas ...\n");
 
@@ -605,6 +605,8 @@
 #endif /* CONFIG_HOTPLUG_CPU */
 	}
 
+	/* Get and save off phys address of rtas structure argunemt field */
+	rtas_args_paddr = __boot_pa(&rtas.args);
 }
 
 
arch/ppc64/kernel/setup.c renamed from arch/ppc64/kernel/setup.c~G0-ppc64-__boot-fixes +10 -6
@@ -411,7 +411,7 @@
 	 * tree, like retreiving the physical memory map or
 	 * calculating/retreiving the hash table size
 	 */
-	early_init_devtree(__va(dt_ptr));
+	early_init_devtree(__boot_va(dt_ptr));
 
 	/*
 	 * Iterate all ppc_md structures until we find the proper
@@ -544,10 +544,10 @@
 
 	prop = (u64 *)get_property(of_chosen, "linux,initrd-start", NULL);
 	if (prop != NULL) {
-		initrd_start = (unsigned long)__va(*prop);
+		initrd_start = (unsigned long)__boot_va(*prop);
 		prop = (u64 *)get_property(of_chosen, "linux,initrd-end", NULL);
 		if (prop != NULL) {
-			initrd_end = (unsigned long)__va(*prop);
+			initrd_end = (unsigned long)__boot_va(*prop);
 			initrd_below_start_ok = 1;
 		} else
 			initrd_start = 0;
@@ -954,9 +954,9 @@
 	 * SLB misses on them.
 	 */
 	for_each_cpu(i) {
-		softirq_ctx[i] = (struct thread_info *)__va(lmb_alloc_base(THREAD_SIZE,
+		softirq_ctx[i] = (struct thread_info *)__boot_va(lmb_alloc_base(THREAD_SIZE,
 					THREAD_SIZE, 0x10000000));
-		hardirq_ctx[i] = (struct thread_info *)__va(lmb_alloc_base(THREAD_SIZE,
+		hardirq_ctx[i] = (struct thread_info *)__boot_va(lmb_alloc_base(THREAD_SIZE,
 					THREAD_SIZE, 0x10000000));
 	}
 }
@@ -985,7 +985,7 @@
 	limit = min(0x10000000UL, lmb.rmo_size);
 
 	for_each_cpu(i)
-		paca[i].emergency_sp = __va(lmb_alloc_base(PAGE_SIZE, 128,
+		paca[i].emergency_sp = __boot_va(lmb_alloc_base(PAGE_SIZE, 128,
 						limit)) + PAGE_SIZE;
 }
 
@@ -1026,6 +1026,10 @@
 
 	/* set up the bootmem stuff with available memory */
 	do_init_bootmem();
+#ifdef CONFIG_SPARSEMEM
+	sparse_init();
+#endif
+
 
 	ppc_md.setup_arch();
 
arch/ppc64/mm/Makefile renamed from arch/ppc64/mm/Makefile~B-sparse-170-sparsemem-ppc64 +1 -1
@@ -6,6 +6,6 @@
 
 obj-y := fault.o init.o imalloc.o hash_utils.o hash_low.o tlb.o \
 	slb_low.o slb.o stab.o mmap.o
-obj-$(CONFIG_DISCONTIGMEM) += numa.o
+obj-$(CONFIG_NUMA) += numa.o
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
 obj-$(CONFIG_PPC_MULTIPLATFORM) += hash_native.o
arch/ppc64/mm/hash_utils.c renamed from arch/ppc64/mm/hash_utils.c~G0-ppc64-__boot-fixes +2 -2
@@ -119,12 +119,12 @@
 #ifdef CONFIG_PPC_PSERIES
 		if (systemcfg->platform & PLATFORM_LPAR)
 			ret = pSeries_lpar_hpte_insert(hpteg, va,
-				virt_to_abs(addr) >> PAGE_SHIFT,
+				boot_virt_to_abs(addr) >> PAGE_SHIFT,
 				0, mode, 1, large);
 		else
 #endif /* CONFIG_PPC_PSERIES */
 			ret = native_hpte_insert(hpteg, va,
-				virt_to_abs(addr) >> PAGE_SHIFT,
+				boot_virt_to_abs(addr) >> PAGE_SHIFT,
 				0, mode, 1, large);
 
 		if (ret == -1) {
arch/ppc64/mm/init.c renamed from arch/ppc64/mm/init.c~A6-no_arch_mem_map_init +103 -7

161 lines not on this page · raw message

arch/ppc64/mm/numa.c renamed from arch/ppc64/mm/numa.c~B-sparse-130-add-early_pfn_to_nid +41 -5

82 lines not on this page · raw message

arch/sh/mm/init.c renamed from arch/sh/mm/init.c~A6-no_arch_mem_map_init +0 -2
@@ -216,8 +216,6 @@
 #endif
 	NODE_DATA(0)->node_mem_map = NULL;
 	free_area_init_node(0, NODE_DATA(0), zones_size, __MEMORY_START >> PAGE_SHIFT, 0);
-	/* XXX: MRB-remove - this doesn't seem sane, should this be done somewhere else ?*/
-	mem_map = NODE_DATA(0)->node_mem_map;
 
 #ifdef CONFIG_DISCONTIGMEM
 	/*
arch/sh64/mm/init.c renamed from arch/sh64/mm/init.c~A6-no_arch_mem_map_init +0 -3
@@ -124,9 +124,6 @@
 	zones_size[ZONE_DMA] = MAX_LOW_PFN - START_PFN;
 	NODE_DATA(0)->node_mem_map = NULL;
 	free_area_init_node(0, NODE_DATA(0), zones_size, __MEMORY_START >> PAGE_SHIFT, 0);
-
-	/* XXX: MRB-remove - this doesn't seem sane, should this be done somewhere else ?*/
-	mem_map = NODE_DATA(0)->node_mem_map;
 }
 
 void __init mem_init(void)
arch/sparc/mm/srmmu.c renamed from arch/sparc/mm/srmmu.c~A6-no_arch_mem_map_init +0 -1
@@ -1343,7 +1343,6 @@
 
 		free_area_init_node(0, &contig_page_data, zones_size,
 				    pfn_base, zholes_size);
-		mem_map = contig_page_data.node_mem_map;
 	}
 }
 
arch/sparc/mm/sun4c.c renamed from arch/sparc/mm/sun4c.c~A6-no_arch_mem_map_init +0 -1
@@ -2116,7 +2116,6 @@
 
 		free_area_init_node(0, &contig_page_data, zones_size,
 				    pfn_base, zholes_size);
-		mem_map = contig_page_data.node_mem_map;
 	}
 
 	cnt = 0;
arch/sparc64/mm/init.c renamed from arch/sparc64/mm/init.c~A6-no_arch_mem_map_init +0 -1
@@ -1512,7 +1512,6 @@
 
 		free_area_init_node(0, &contig_page_data, zones_size,
 				    phys_base >> PAGE_SHIFT, zholes_size);
-		mem_map = contig_page_data.node_mem_map;
 	}
 
 	device_scan();
arch/um/kernel/mem.c renamed from arch/um/kernel/mem.c~FROM-MM-mostly-i386-mm-cleanup +1 -1
@@ -138,7 +138,7 @@
 	pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)),\
  			  (vaddr)), (vaddr))
 
-void __init kmap_init(void)
+static void __init kmap_init(void)
 {
 	unsigned long kmap_vstart;
 
arch/um/kernel/physmem.c renamed from arch/um/kernel/physmem.c~A6-no_arch_mem_map_init +0 -1
@@ -294,7 +294,6 @@
 		INIT_LIST_HEAD(&p->lru);
 	}
 
-	mem_map = map;
 	max_mapnr = total_pages;
 	return(0);
 }
arch/v850/kernel/setup.c renamed from arch/v850/kernel/setup.c~A6-no_arch_mem_map_init +0 -1
@@ -283,5 +283,4 @@
 	NODE_DATA(0)->node_mem_map = NULL;
 	free_area_init_node (0, NODE_DATA(0), zones_size,
 			     ADDR_TO_PAGE (PAGE_OFFSET), 0);
-	mem_map = NODE_DATA(0)->node_mem_map;
 }
include/asm-frv/highmem.h renamed from include/asm-frv/highmem.h~FROM-MM-mostly-i386-mm-cleanup +0 -2
@@ -44,8 +44,6 @@
 #define kmap_pte ______kmap_pte_in_TLB
 extern pte_t *pkmap_page_table;
 
-extern void kmap_init(void);
-
 #define flush_cache_kmaps()  do { } while (0)
 
 /*
include/asm-i386/highmem.h renamed from include/asm-i386/highmem.h~FROM-MM-mostly-i386-mm-cleanup +0 -2
@@ -33,8 +33,6 @@
 extern pgprot_t kmap_prot;
 extern pte_t *pkmap_page_table;
 
-extern void kmap_init(void);
-
 /*
  * Right now we initialize only a single pte table. It can be extended
  * easily, subsequent pte tables have to be allocated in one physical
include/asm-i386/mmzone.h renamed from include/asm-i386/mmzone.h~A2.1-re-memset-i386-pgdats +45 -19

84 lines not on this page · raw message

include/asm-i386/page.h renamed from include/asm-i386/page.h~B-sparse-075-validate-remap-pages +8 -4
@@ -119,6 +119,8 @@
 
 extern int sysctl_legacy_va_layout;
 
+extern int page_is_ram(unsigned long pagenr);
+
 #endif /* __ASSEMBLY__ */
 
 #ifdef __ASSEMBLY__
@@ -131,14 +133,16 @@
 #define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
 #define VMALLOC_RESERVE		((unsigned long)__VMALLOC_RESERVE)
 #define MAXMEM			(-__PAGE_OFFSET-__VMALLOC_RESERVE)
-#define __pa(x)			((unsigned long)(x)-PAGE_OFFSET)
-#define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
+#define __boot_pa(x)		((unsigned long)(x)-PAGE_OFFSET)
+#define __boot_va(x)		((void *)((unsigned long)(x)+PAGE_OFFSET))
+#define __pa(x)			__boot_pa(x)
+#define __va(x)			__boot_va(x)
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
-#ifndef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_FLATMEM
 #define pfn_to_page(pfn)	(mem_map + (pfn))
 #define page_to_pfn(page)	((unsigned long)((page) - mem_map))
 #define pfn_valid(pfn)		((pfn) < max_mapnr)
-#endif /* !CONFIG_DISCONTIGMEM */
+#endif /* CONFIG_FLATMEM */
 #define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
 
 #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
include/asm-i386/pgtable.h renamed from include/asm-i386/pgtable.h~B-sparse-160-sparsemem-i386 +2 -2
@@ -396,9 +396,9 @@
 
 #endif /* !__ASSEMBLY__ */
 
-#ifndef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_FLATMEM
 #define kern_addr_valid(addr)	(1)
-#endif /* !CONFIG_DISCONTIGMEM */
+#endif /* CONFIG_FLATMEM */
 
 #define io_remap_page_range(vma, vaddr, paddr, size, prot)		\
 		remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
include/asm-ppc/highmem.h renamed from include/asm-ppc/highmem.h~FROM-MM-mostly-i386-mm-cleanup +0 -2
@@ -35,8 +35,6 @@
 extern pgprot_t kmap_prot;
 extern pte_t *pkmap_page_table;
 
-extern void kmap_init(void) __init;
-
 /*
  * Right now we initialize only a single pte table. It can be extended
  * easily, subsequent pte tables have to be allocated in one physical
include/asm-ppc64/abs_addr.h renamed from include/asm-ppc64/abs_addr.h~G1-kravetz-ppc64-fixes +2 -0
@@ -104,5 +104,7 @@
 /* Convenience macros */
 #define virt_to_abs(va) phys_to_abs(__pa(va))
 #define abs_to_virt(aa) __va(abs_to_phys(aa))
+#define boot_virt_to_abs(va) phys_to_abs(__boot_pa(va))
+#define boot_abs_to_virt(aa) __boot_va(abs_to_phys(aa))
 
 #endif /* _ABS_ADDR_H */
include/asm-ppc64/dma.h renamed from include/asm-ppc64/dma.h~G0-ppc64-__boot-fixes +2 -0
@@ -26,6 +26,8 @@
 /* The maximum address that we can perform a DMA transfer to on this platform */
 /* Doesn't really apply... */
 #define MAX_DMA_ADDRESS  (~0UL)
+#define MAX_DMA_PHYSADDR MAX_DMA_ADDRESS
+#define MAX_DMA_PHYSADDR MAX_DMA_ADDRESS
 
 #define dma_outb	outb
 #define dma_inb		inb
include/asm-ppc64/mmzone.h renamed from include/asm-ppc64/mmzone.h~B-sparse-170-sparsemem-ppc64 +42 -6

72 lines not on this page · raw message

include/asm-ppc64/page.h renamed from include/asm-ppc64/page.h~B-sparse-170-sparsemem-ppc64 +7 -4
@@ -179,7 +179,10 @@
 	return order;
 }
 
-#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
+#define __boot_pa(x)   ((unsigned long)(x)-PAGE_OFFSET)
+#define __boot_va(x)   ((void *)((unsigned long)(x) + KERNELBASE))
+#define __pa(x)		__boot_pa(x)
+#define __va(x)		__boot_va(x)
 
 extern int page_is_ram(unsigned long pfn);
 
@@ -215,13 +218,13 @@
 #define __bpn_to_ba(x) ((((unsigned long)(x))<<PAGE_SHIFT) + KERNELBASE)
 #define __ba_to_bpn(x) ((((unsigned long)(x)) & ~REGION_MASK) >> PAGE_SHIFT)
 
-#define __va(x) ((void *)((unsigned long)(x) + KERNELBASE))
-
 #ifdef CONFIG_DISCONTIGMEM
 #define page_to_pfn(page)	discontigmem_page_to_pfn(page)
 #define pfn_to_page(pfn)	discontigmem_pfn_to_page(pfn)
 #define pfn_valid(pfn)		discontigmem_pfn_valid(pfn)
-#else
+#endif
+/* XXX/APW: why is SPARSEMEM not here */
+#ifdef CONFIG_FLATMEM
 #define pfn_to_page(pfn)	(mem_map + (pfn))
 #define page_to_pfn(page)	((unsigned long)((page) - mem_map))
 #define pfn_valid(pfn)		((pfn) < max_mapnr)
include/linux/bootmem.h renamed from include/linux/bootmem.h~B-sparse-080-alloc_remap-i386 +17 -4
@@ -36,6 +36,10 @@
 					 * up searching */
 } bootmem_data_t;
 
+#ifndef MAX_DMA_PHYSADDR
+#define MAX_DMA_PHYSADDR (__boot_pa(MAX_DMA_ADDRESS))
+#endif
+
 extern unsigned long __init bootmem_bootmap_pages (unsigned long);
 extern unsigned long __init init_bootmem (unsigned long addr, unsigned long memend);
 extern void __init free_bootmem (unsigned long addr, unsigned long size);
@@ -43,11 +47,11 @@
 #ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE
 extern void __init reserve_bootmem (unsigned long addr, unsigned long size);
 #define alloc_bootmem(x) \
-	__alloc_bootmem((x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
+	__alloc_bootmem((x), SMP_CACHE_BYTES, MAX_DMA_PHYSADDR)
 #define alloc_bootmem_low(x) \
 	__alloc_bootmem((x), SMP_CACHE_BYTES, 0)
 #define alloc_bootmem_pages(x) \
-	__alloc_bootmem((x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
+	__alloc_bootmem((x), PAGE_SIZE, MAX_DMA_PHYSADDR)
 #define alloc_bootmem_low_pages(x) \
 	__alloc_bootmem((x), PAGE_SIZE, 0)
 #endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */
@@ -60,13 +64,22 @@
 extern void * __init __alloc_bootmem_node (pg_data_t *pgdat, unsigned long size, unsigned long align, unsigned long goal);
 #ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE
 #define alloc_bootmem_node(pgdat, x) \
-	__alloc_bootmem_node((pgdat), (x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
+	__alloc_bootmem_node((pgdat), (x), SMP_CACHE_BYTES, MAX_DMA_PHYSADDR)
 #define alloc_bootmem_pages_node(pgdat, x) \
-	__alloc_bootmem_node((pgdat), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
+	__alloc_bootmem_node((pgdat), (x), PAGE_SIZE, MAX_DMA_PHYSADDR)
 #define alloc_bootmem_low_pages_node(pgdat, x) \
 	__alloc_bootmem_node((pgdat), (x), PAGE_SIZE, 0)
 #endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */
 
+#ifdef CONFIG_HAVE_ARCH_ALLOC_REMAP
+extern void *alloc_remap(int nid, unsigned long size);
+#else
+static inline void *alloc_remap(int nid, unsigned long size)
+{
+	return NULL;
+}
+#endif
+
 extern unsigned long __initdata nr_kernel_pages;
 extern unsigned long __initdata nr_all_pages;
 
include/linux/mm.h renamed from include/linux/mm.h~B-sparse-100-cleanup-node-zone +103 -10

135 lines not on this page · raw message

include/linux/mmzone.h renamed from include/linux/mmzone.h~B-sparse-100-cleanup-node-zone +134 -13

178 lines not on this page · raw message

include/linux/numa.h renamed from include/linux/numa.h~B-sparse-150-sparsemem +1 -1
@@ -3,7 +3,7 @@
 
 #include <linux/config.h>
 
-#ifdef CONFIG_DISCONTIGMEM
+#ifndef CONFIG_FLATMEM
 #include <asm/numnodes.h>
 #endif
 
mm/Kconfig new file +19 -0
@@ -0,0 +1,19 @@
+choice
+	prompt "Memory model"
+	default SPARSEMEM if ARCH_SPARSEMEM_DEFAULT
+	default FLATMEM
+
+config DISCONTIGMEM
+	bool "Discontigious Memory"
+	depends on !ARCH_DISCONTIGMEM_DISABLE
+
+config SPARSEMEM
+	bool "Sparse Memory"
+	depends on !ARCH_SPARSEMEM_DISABLE
+
+config FLATMEM
+	bool "Flat Memory"
+
+endchoice
+
+
mm/Makefile renamed from mm/Makefile~B-sparse-150-sparsemem +1 -0
@@ -15,6 +15,7 @@
 obj-$(CONFIG_SWAP)	+= page_io.o swap_state.o swapfile.o thrash.o
 obj-$(CONFIG_HUGETLBFS)	+= hugetlb.o
 obj-$(CONFIG_NUMA) 	+= mempolicy.o
+obj-$(CONFIG_SPARSEMEM)	+= sparse.o
 obj-$(CONFIG_SHMEM) += shmem.o
 obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
 
mm/bootmem.c renamed from mm/bootmem.c~B-sparse-150-sparsemem +17 -1
@@ -256,6 +256,7 @@
 static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
 {
 	struct page *page;
+	unsigned long pfn;
 	bootmem_data_t *bdata = pgdat->bdata;
 	unsigned long i, count, total = 0;
 	unsigned long idx;
@@ -266,15 +267,29 @@
 
 	count = 0;
 	/* first extant page of the node */
-	page = virt_to_page(phys_to_virt(bdata->node_boot_start));
+	pfn = bdata->node_boot_start >> PAGE_SHIFT;
 	idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT);
 	map = bdata->node_bootmem_map;
 	/* Check physaddr is O(LOG2(BITS_PER_LONG)) page aligned */
 	if (bdata->node_boot_start == 0 ||
 	    ffs(bdata->node_boot_start) - PAGE_SHIFT > ffs(BITS_PER_LONG))
 		gofast = 1;
+
+	/*
+	 * APW/XXX: we are making an assumption that our node_boot_start
+	 * is aligned to BITS_PER_LONG ... is this valid/enforced.
+	 */
+	/*
+	 * Make use of the guarentee that *_mem_map will be
+	 * contigious in sections aligned at MAX_ORDER.
+	 */
+	page = pfn_to_page(pfn);
 	for (i = 0; i < idx; ) {
 		unsigned long v = ~map[i / BITS_PER_LONG];
+
+		if ((pfn & ((1 << MAX_ORDER) - 1)) == 0)
+			page = pfn_to_page(pfn);
+
 		if (gofast && v == ~0UL) {
 			int j, order;
 
@@ -304,6 +319,7 @@
 			i+=BITS_PER_LONG;
 			page += BITS_PER_LONG;
 		}
+		pfn += BITS_PER_LONG;
 	}
 	total += count;
 
mm/memory.c renamed from mm/memory.c~B-sparse-150-sparsemem +1 -1
@@ -59,7 +59,7 @@
 #include <linux/swapops.h>
 #include <linux/elf.h>
 
-#ifndef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_FLATMEM
 /* use the per-pgdat data instead for discontigmem - mbligh */
 unsigned long max_mapnr;
 struct page *mem_map;
mm/page_alloc.c renamed from mm/page_alloc.c~A1-pcp_zone_init +178 -90

398 lines not on this page · raw message

mm/sparse.c new file +115 -0

115 lines not on this page · raw message

#1 lore raw

RFC PATCH 1/1 Memory Hotplug

The attached patch is a prototype implementation of memory hot-add. It allows you to boot your system, and add memory to it later. Why would you want to do this? Well, it's a step before memory removal which can help cope with things like bad RAM. This is primarily useful for a machine that you don't want to reboot during an upgrade.

For instance, on my 1GB laptop, I booted with mem=512M on the kernel command-line. Once I had booted, I did the following:

cd /sys/devices/system/memory
echo 0x20000000 > probe
echo 0x30000000 > probe
echo online > memory2/state
echo online > memory3/state

and the last 512MB of my laptop's memory was onlined. The onlining operations can occur from an /etc/hotplug script if desired.

Here's the config file that I used:
http://www.sr71.net/patches/2.6.11/2.6.11-rc3-mhp1/configs/config-i386-T41-laptop

The important config options are:
CONFIG_MEMORY_HOTPLUG=y
CONFIG_SPARSEMEM=y
CONFIG_SIMULATED_MEM_HOTPLUG=y

This patch depends on the previously posed "Sparse Memory Handling (hot-add foundation)" patch.

There are a number of individual patches (with descriptions) which are rolled up in the attached patch: all of the files listed after "G2-no-memory-at-high_memory-ppc64.patch" from this directory:
http://www.sr71.net/patches/2.6.11/2.6.11-rc3-mhp1/broken-out/

I can post individual patches if anyone would like to comment on them.

-- Dave

arch/i386/kernel/setup.c renamed from arch/i386/kernel/setup.c~Y2-page_is_ram_hotplug +2 -0
@@ -118,6 +118,7 @@
 struct edid_info edid_info;
 struct ist_info ist_info;
 struct e820map e820;
+struct e820map bios_e820;
 
 unsigned char aux_device_present;
 
@@ -1417,6 +1418,7 @@
 	else {
 		printk(KERN_INFO "BIOS-provided physical RAM map:\n");
 		print_memory_map(machine_specific_memory_setup());
+		bios_e820 = e820;
 	}
 
 	copy_edd();
arch/i386/mm/init.c renamed from arch/i386/mm/init.c~L1-sysfs-memory-class +130 -19

189 lines not on this page · raw message

arch/ia64/mm/init.c renamed from arch/ia64/mm/init.c~L2-ia64-hotplug-stubs +21 -0
@@ -618,3 +618,24 @@
 	ia32_mem_init();
 #endif
 }
+
+#ifdef	CONFIG_MEMORY_HOTPLUG
+void online_page(struct page *page)
+{
+	ClearPageReserved(page);
+	set_page_count(page, 1);
+	__free_page(page);
+	totalram_pages++;
+	num_physpages++;
+}
+
+int add_memory(u64 start, u64 size, unsigned long attr)
+{
+	return -ENOSYS;
+}
+
+int remove_memory(u64 start, u64 size, unsigned long attr)
+{
+	return -ENOSYS;
+}
+#endif
arch/ppc64/mm/init.c renamed from arch/ppc64/mm/init.c~I0-nonlinear-types +1 -1
@@ -677,7 +677,7 @@
 	zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT;
 
 	free_area_init_node(0, &contig_page_data, zones_size,
-			    __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size);
+			    __pa((void *)PAGE_OFFSET) >> PAGE_SHIFT, zholes_size);
 }
 #endif /* CONFIG_NUMA */
 
drivers/acpi/Kconfig renamed from drivers/acpi/Kconfig~Q-ACPI-hotplug-driver +7 -0
@@ -342,4 +342,11 @@
 	 	This is the ACPI generic container driver which supports
 		ACPI0004, PNP0A05 and PNP0A06 devices
 
+config ACPI_HOTPLUG_MEMORY
+	tristate "Memory Hotplug"
+	depends on ACPI
+	depends on MEMORY_HOTPLUG
+	default m
+	help
+	  This driver adds supports for ACPI Memory Hotplug.
 endmenu
drivers/acpi/Makefile renamed from drivers/acpi/Makefile~Q-ACPI-hotplug-driver +1 -0
@@ -55,3 +55,4 @@
 obj-$(CONFIG_ACPI_IBM)		+= ibm_acpi.o
 obj-$(CONFIG_ACPI_TOSHIBA)	+= toshiba_acpi.o
 obj-$(CONFIG_ACPI_BUS)		+= scan.o motherboard.o
+obj-$(CONFIG_ACPI_HOTPLUG_MEMORY)	+= acpi_memhotplug.o
drivers/acpi/acpi_memhotplug.c new file +542 -0

542 lines not on this page · raw message

drivers/base/Makefile renamed from drivers/base/Makefile~L1-sysfs-memory-class +1 -0
@@ -7,6 +7,7 @@
 obj-y			+= power/
 obj-$(CONFIG_FW_LOADER)	+= firmware_class.o
 obj-$(CONFIG_NUMA)	+= node.o
+obj-$(CONFIG_MEMORY_HOTPLUG) += memory.o
 
 ifeq ($(CONFIG_DEBUG_DRIVER),y)
 EXTRA_CFLAGS += -DDEBUG
drivers/base/init.c renamed from drivers/base/init.c~L1-sysfs-memory-class +2 -0
@@ -9,6 +9,7 @@
 
 #include <linux/device.h>
 #include <linux/init.h>
+#include <linux/memory.h>
 
 extern int devices_init(void);
 extern int buses_init(void);
@@ -39,5 +40,6 @@
 	platform_bus_init();
 	system_bus_init();
 	cpu_dev_init();
+	memory_dev_init();
 	attribute_container_init();
 }
drivers/base/memory.c new file +525 -0

525 lines not on this page · raw message

include/asm-i386/highmem.h renamed from include/asm-i386/highmem.h~L1-sysfs-memory-class +1 -0
@@ -65,6 +65,7 @@
 
 extern void * FASTCALL(kmap_high(struct page *page));
 extern void FASTCALL(kunmap_high(struct page *page));
+extern void flush_all_zero_pkmaps(void);
 
 void *kmap(struct page *page);
 void kunmap(struct page *page);
include/linux/highmem.h renamed from include/linux/highmem.h~L1-sysfs-memory-class +1 -0
@@ -29,6 +29,7 @@
 #define kmap_atomic(page, idx)		page_address(page)
 #define kunmap_atomic(addr, idx)	do { } while (0)
 #define kmap_atomic_to_page(ptr)	virt_to_page(ptr)
+#define flush_all_zero_pkmaps()		do { } while (0)
 
 #endif /* CONFIG_HIGHMEM */
 
include/linux/memory.h new file +78 -0

78 lines not on this page · raw message

include/linux/memory_hotplug.h new file +41 -0

41 lines not on this page · raw message

include/linux/mmzone.h renamed from include/linux/mmzone.h~J-zone_resize_sem +13 -1
@@ -12,6 +12,7 @@
 #include <linux/threads.h>
 #include <linux/numa.h>
 #include <asm/atomic.h>
+#include <asm/semaphore.h>
 
 /* Free memory management - zoned buddy allocator.  */
 #ifndef CONFIG_FORCE_MAX_ZONEORDER
@@ -204,6 +205,7 @@
 
 	unsigned long		spanned_pages;	/* total size, including holes */
 	unsigned long		present_pages;	/* amount of memory (excluding holes) */
+	struct semaphore	resize_sem;
 
 	/*
 	 * rarely used fields:
@@ -277,6 +279,7 @@
 void wakeup_kswapd(struct zone *zone, int order);
 int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
 		int alloc_type, int can_try_harder, int gfp_high);
+void setup_per_zone_pages_min(void);
 
 /*
  * zone_idx() returns 0 for the ZONE_DMA zone, 1 for the ZONE_NORMAL zone, etc.
@@ -472,16 +475,25 @@
 	return (section->section_mem_map & SECTION_HAS_MEM_MAP);
 }
 
+static inline int valid_section_nr(int nr)
+{
+	return valid_section(&mem_section[nr]);
+}
+
 /*
  * Given a kernel address, find the home node of the underlying memory.
  */
 #define kvaddr_to_nid(kaddr)	pfn_to_nid(__pa(kaddr) >> PAGE_SHIFT)
-
 static inline struct mem_section *__pfn_to_section(unsigned long pfn)
 {
 	return &mem_section[pfn >> PFN_SECTION_SHIFT];
 }
 
+static inline int __section_nr(struct mem_section* ms)
+{
+	return ms - &mem_section[0];
+}
+
 #define pfn_to_page(pfn) 						\
 ({ 									\
 	unsigned long __pfn = (pfn);					\
mm/Kconfig renamed from mm/Kconfig~L1-sysfs-memory-class +7 -0
@@ -1,3 +1,7 @@
+config MEMORY_HOTPLUG
+	bool "Allow for memory hot-add"
+	depends on SPARSEMEM && HOTPLUG
+
 choice
 	prompt "Memory model"
 	default SPARSEMEM if ARCH_SPARSEMEM_DEFAULT
@@ -16,4 +20,7 @@
 
 endchoice
 
+config SIMULATED_MEM_HOTPLUG
+	bool "Simulate memory hotplug on non-hotplug hardware"
+	depends on X86 && !X86_64
 
mm/Makefile renamed from mm/Makefile~L1-sysfs-memory-class +1 -0
@@ -18,4 +18,5 @@
 obj-$(CONFIG_SPARSEMEM)	+= sparse.o
 obj-$(CONFIG_SHMEM) += shmem.o
 obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
+obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
 
mm/highmem.c renamed from mm/highmem.c~L1-sysfs-memory-class +1 -1
@@ -59,7 +59,7 @@
 
 static DECLARE_WAIT_QUEUE_HEAD(pkmap_map_wait);
 
-static void flush_all_zero_pkmaps(void)
+void flush_all_zero_pkmaps(void)
 {
 	int i;
 
mm/memory_hotplug.c new file +222 -0

222 lines not on this page · raw message

mm/page_alloc.c renamed from mm/page_alloc.c~I0-nonlinear-types +48 -15

158 lines not on this page · raw message

#2 lore raw

Re: [RFC][PATCH] Memory Hotplug

Quoted 3 lines · Dave Hansen

The attached patch is a prototype implementation of memory hot-add. It allows you to boot your system, and add memory to it later. Why would you want to do this?

I want it so I can grow Xen guests after they have been booted up. Being able to hot-add memory is essential for dynamically resizing the memory of various guest OSes, to readjust them for the workload.

Memory hot-remove isn't really needed with Xen, the balloon driver takes care of that.

Quoted 1 line

I can post individual patches if anyone would like to comment on them.

I'm interested. I want to get this stuff working with Xen ;)

Signature · 8 lines
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it." - Brian W. Kernighan
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#3 lore raw

Re: [RFC][PATCH] Memory Hotplug

Quoted 9 lines · Rik van Riel
Quoted 3 lines · Dave Hansen

The attached patch is a prototype implementation of memory hot-add. It allows you to boot your system, and add memory to it later. Why would you want to do this?

I want it so I can grow Xen guests after they have been booted up. Being able to hot-add memory is essential for dynamically resizing the memory of various guest OSes, to readjust them for the workload.

That's the same thing we like about it on ppc64 partitions.

Quoted 2 lines

Memory hot-remove isn't really needed with Xen, the balloon driver takes care of that.

You can free up individual pages back to the hypervisor, but you might also want the opportunity to free up some unused mem_map if you shrink the partition by a large amount.

Quoted 3 lines
Quoted 1 line

I can post individual patches if anyone would like to comment on them.

I'm interested. I want to get this stuff working with Xen ;)

You can either pull them from here:

	http://www.sr71.net/patches/2.6.11/2.6.11-rc3-mhp1/broken-out/

or grab the whole tarball:

http://www.sr71.net/patches/2.6.11/2.6.11-rc3-mhp1/broken-out-2.6.11-rc3-mhp1.tar.gz

Or, I could always post the whole bunch to lhms. Nobody there should mind too much. :)

The largest part of porting hot-add to a new architecture is usually the sparsemem portion. You'll pretty much have to #ifdef pfn_to_page() and friends, declare a few macros, and then do a bit of debugging. Here's ppc64 as an example:

http://www.sr71.net/patches/2.6.11/2.6.11-rc3-mhp1/broken-out/B-sparse-170-sparsemem-ppc64.patch

-- Dave

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#4 lore raw

Re: [RFC][PATCH] Memory Hotplug

Quoted 6 lines · Dave Hansen
Quoted 2 lines

Memory hot-remove isn't really needed with Xen, the balloon driver takes care of that.

You can free up individual pages back to the hypervisor, but you might also want the opportunity to free up some unused mem_map if you shrink the partition by a large amount.

Agreed, though I rather like the fact that the code can be introduced bit by bit, so the memory hot-remove code (probably the most complex part) doesn't need to be maintained out-of-tree for Xen, but can wait until it is upstream.

Quoted 7 lines
Quoted 3 lines
Quoted 1 line

I can post individual patches if anyone would like to comment on them.

I'm interested. I want to get this stuff working with Xen ;)

You can either pull them from here:

	http://www.sr71.net/patches/2.6.11/2.6.11-rc3-mhp1/broken-out/

Thanks, I'll take a stab at porting this functionality to Xen.

Signature · 8 lines
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it." - Brian W. Kernighan
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#6 lore raw
Quoted 5 lines · Mike Kravetz
Quoted 1 line · Dave Hansen

The attached patch

Just tried to compile this and noticed that there is no definition of valid_section_nr(), referenced in sparse_init.

What's your .config? I didn't actually try it on ppc64, and I may have missed one of the necessary patches. I trimmed it down to very near the minimum set on x86.

-- Dave

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#7 lore raw
In reply to Dave Hansen
Quoted 5 lines · Dave Hansen

The attached patch, largely written by Andy Whitcroft, implements a feature which is similar to DISCONTIGMEM, but has some added features. Instead of splitting up the mem_map for each NUMA node, this splits it up into areas that represent fixed blocks of memory. This allows individual pieces of that memory to be easily added and removed.

[...]

I'm curious - how does this affect .text size for a i386 or x86-64 NUMA kernel? One area I wanted to improve on x86-64 for a long time was to shrink the big virt_to_page() etc. inline macros. Your new code actually looks a bit smaller.

-Andi
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#8 lore raw
Quoted 8 lines · Andi Kleen
Quoted 5 lines · Dave Hansen

The attached patch, largely written by Andy Whitcroft, implements a feature which is similar to DISCONTIGMEM, but has some added features. Instead of splitting up the mem_map for each NUMA node, this splits it up into areas that represent fixed blocks of memory. This allows individual pieces of that memory to be easily added and removed.

Quoted 4 lines

I'm curious - how does this affect .text size for a i386 or x86-64 NUMA kernel? One area I wanted to improve on x86-64 for a long time was to shrink the big virt_to_page() etc. inline macros. Your new code actually looks a bit smaller.

On x86, it looks like a 3k increase in text size. I know Matt Tolentino has been testing it on x86_64, he might have a comparison there for you.

$ size i386-T41-laptop*/vmlinux
   text    data     bss     dec     hex filename
2897131  580592  204252 3681975  382eb7 i386-T41-laptop.sparse/vmlinux
2894166  581832  203228 3679226  3823fa i386-T41-laptop/vmlinux

BTW, this PAE is on and uses 36-bits of physaddr space.

-- Dave

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>