linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/05][RFC] NUMA emulation update
@ 2005-11-10  9:08 Magnus Damm
  2005-11-10  9:08 ` [PATCH 01/05] NUMA: Generic code Magnus Damm
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Magnus Damm @ 2005-11-10  9:08 UTC (permalink / raw)
  To: linux-mm, linux-kernel; +Cc: Magnus Damm, pj, ak

CONFIG_NUMA_EMU - new and improved!

These patches update the current x86_64 NUMA emulation code by adding support
for dividing real NUMA nodes into several smaller emulated nodes. The good old
x86_64 implementation of NUMA emulation written by Andi Kleen has worked well
since 2.6.9, but it lacks support for dividing multiple real NUMA nodes.

The patches also break out the NUMA emulation code into some simple generic 
functions that could be used by several platforms. Only x86_64 gets modified
by this patch set, but I've planned to convert my i386 NUMA emulation code to
use these generic functions later on. I know that some kind of NUMA emulation
code also exists for ia64, and maybe it is possible to build that code on top
of the generic functions too.

Patches on top of 2.6.14-mm1:

[PATCH 01/05] NUMA: Generic code
[PATCH 02/05] x86_64: NUMA cleanup
[PATCH 03/05] x86_64: NUMA emulation
[PATCH 04/05] x86_64: NUMA without SMP
[PATCH 05/05] NUMA: find_next_best_node fix

About NUMA emulation:

NUMA emulation could be used to provide coarse-grained memory resource control
using CPUSETS. Another use is as a test environment for NUMA memory code or
CPUSETS using an system emulator such as QEMU.

Feedback is very appreciated.

Thanks,

/ magnus

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

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 01/05] NUMA: Generic code
  2005-11-10  9:08 [PATCH 00/05][RFC] NUMA emulation update Magnus Damm
@ 2005-11-10  9:08 ` Magnus Damm
  2005-11-11  4:16   ` Andi Kleen
  2005-11-10  9:08 ` [PATCH 02/05] x86_64: NUMA cleanup Magnus Damm
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Magnus Damm @ 2005-11-10  9:08 UTC (permalink / raw)
  To: linux-mm, linux-kernel; +Cc: Magnus Damm, pj, ak

Generic CONFIG_NUMA_EMU code.

This patch adds generic NUMA emulation code to the kernel. The code provides 
the architectures with functions that calculate the size of emulated nodes,
together with configuration stuff such as Kconfig and kernel command line code.

Signed-off-by: Magnus Damm <magnus@valinux.co.jp>
---

 include/linux/numa.h  |   25 +++++++++-
 mm/Kconfig            |   17 +++++++
 mm/Makefile           |    1
 mm/numa_emu.c         |  118 ++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 159 insertions(+), 2 deletions(-)

--- from-0001/include/linux/numa.h
+++ to-work/include/linux/numa.h	2005-11-09 11:50:03.000000000 +0900
@@ -2,15 +2,36 @@
 #define _LINUX_NUMA_H
 
 #include <linux/config.h>
+#include <linux/init.h>
 
 #ifndef CONFIG_FLATMEM
 #include <asm/numnodes.h>
 #endif
 
-#ifndef NODES_SHIFT
-#define NODES_SHIFT     0
+#ifndef NODES_SHIFT_HW
+#define NODES_SHIFT_HW     0
 #endif
 
+#ifdef CONFIG_NUMA_EMU
+#define NODES_SHIFT_EMU CONFIG_NUMA_EMU_SHIFT
+/* in mm/numa_emu.c */
+void numa_emu_setup(char *opt);
+int __init numa_emu_new(int nid, 
+			unsigned long real_start, unsigned long real_end, 
+			unsigned long *emu_start, unsigned long *emu_end);
+int __init numa_emu_shrink(int nid, int new_nodes, 
+			   unsigned long real_start, unsigned long real_end,
+			   unsigned long *emu_start, unsigned long *emu_end);
+/* arch-specific */
+void __init numa_emu_setup_nid(int real_nid);
+#else
+#define NODES_SHIFT_EMU 0
+static inline void numa_emu_setup_nid(int real_nid) {}
+static inline void numa_emu_setup(char *opt) {}
+#endif
+
+#define NODES_SHIFT     (NODES_SHIFT_HW + NODES_SHIFT_EMU)
+
 #define MAX_NUMNODES    (1 << NODES_SHIFT)
 
 #endif /* _LINUX_NUMA_H */
--- from-0002/mm/Kconfig
+++ to-work/mm/Kconfig	2005-11-09 11:50:03.000000000 +0900
@@ -77,6 +77,23 @@ config FLAT_NODE_MEM_MAP
 	def_bool y
 	depends on !SPARSEMEM
 
+config NUMA_EMU
+	bool "NUMA Memory Nodes Emulation"
+	select NUMA
+	depends on ARCH_NUMA_EMU_ENABLE
+	default n
+	help
+	  Enable NUMA emulation. Each node will be split into several virtual
+	  nodes when booted with "numa=fake=N", where N is the number of nodes.
+
+config NUMA_EMU_SHIFT
+	int "Maximum shift number of emulated nodes, per real node (1-8)"
+	range 1 8
+	depends on NUMA_EMU
+	default "3"
+	help
+	  This value controls the maximum number of emulated NUMA nodes.
+
 #
 # Both the NUMA code and DISCONTIGMEM use arrays of pg_data_t's
 # to represent different areas of memory.  This variable allows
--- from-0002/mm/Makefile
+++ to-work/mm/Makefile	2005-11-09 11:50:03.000000000 +0900
@@ -16,6 +16,7 @@ obj-$(CONFIG_SWAP)	+= page_io.o swap_sta
 obj-$(CONFIG_SWAP_PREFETCH) += swap_prefetch.o
 obj-$(CONFIG_HUGETLBFS)	+= hugetlb.o
 obj-$(CONFIG_NUMA) 	+= mempolicy.o
+obj-$(CONFIG_NUMA_EMU) 	+= numa_emu.o
 obj-$(CONFIG_SPARSEMEM)	+= sparse.o
 obj-$(CONFIG_SHMEM) += shmem.o
 obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
--- /dev/null
+++ to-work/mm/numa_emu.c	2005-11-09 11:50:04.000000000 +0900
@@ -0,0 +1,118 @@
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/cache.h>
+#include <linux/mm.h>
+#include <linux/numa.h>
+#include <linux/nodemask.h>
+
+extern unsigned long node_start_pfn[MAX_NUMNODES] __read_mostly;
+extern unsigned long node_end_pfn[MAX_NUMNODES] __read_mostly;
+
+int numa_fake __initdata = 0;
+
+void __init numa_emu_setup(char *opt)
+{
+	int max_emu = 1 << CONFIG_NUMA_EMU_SHIFT;
+
+	if (!memcmp(opt, "fake=", 5) && (*(opt + 5))) {
+		numa_fake = simple_strtoul(opt + 5, NULL, 0);
+		numa_fake = min(numa_fake, max_emu);
+		printk("fake numa nodes = %d/%d\n", numa_fake, max_emu);
+       }
+}
+
+unsigned long __init numa_emu_node_size(unsigned long real_size, int last)
+{
+	unsigned long node_size;
+	unsigned long shift;
+
+	if (numa_fake == 0)
+		return 0;
+
+	node_size = real_size / numa_fake;
+
+	if (node_size == 0)
+		return 0;
+
+	shift = 1;
+	while ((1 << shift) <= node_size)
+		shift++;
+
+	shift--;
+
+	node_size = 1 << shift;
+
+#ifdef CONFIG_SPARSEMEM
+	if (node_size * PAGE_SIZE < (1UL << SECTION_SIZE_BITS))
+		return 0;
+#else
+#warning FIXME: Perform similar check for non-sparsemem!
+#endif
+
+	if (last)
+		node_size = real_size - (node_size * (numa_fake - 1));
+
+	return node_size;
+}
+
+int __init numa_emu_new(int nid, 
+			unsigned long real_start, unsigned long real_end, 
+			unsigned long *emu_start, unsigned long *emu_end)
+{
+	int fake_nr = nid >> NODES_SHIFT_HW;
+	unsigned long node_size;
+
+	/* only setup amount of nodes passed on cmdline */
+
+	if (fake_nr >= numa_fake) 
+		return -1;
+
+	node_size = numa_emu_node_size(real_end - real_start, 0);
+
+	if (!node_size)
+		return -1;
+
+	*emu_start = real_start + (fake_nr * node_size);
+
+	if (fake_nr == (numa_fake - 1)) {
+		node_size = numa_emu_node_size(real_end - real_start, 1);
+
+		if (!node_size)
+			return -1;
+
+	}
+
+	*emu_end = *emu_start + node_size;
+	
+	printk("configuring fake node nr %u: pfn %lu - %lu\n", 
+	       nid, *emu_start, *emu_end);
+
+	return 0;
+}
+
+int __init numa_emu_shrink(int nid, int new_nodes, 
+			   unsigned long real_start, unsigned long real_end,
+			   unsigned long *emu_start, unsigned long *emu_end)
+{
+	unsigned long node_size;
+
+	if (numa_fake != (new_nodes + 1))  
+		return -1;
+
+	node_size = numa_emu_node_size(real_end - real_start, 0);
+
+	if (!node_size)
+		return -1;
+
+	*emu_start = real_start;
+	*emu_end = real_start + node_size;
+	
+	printk("configuring real node nr %u: pfn %lu - %lu\n", 
+	       nid, *emu_start, *emu_end);
+
+	printk("NUMA - emulation, adding %u emulated node(s) to node %u\n",
+	       new_nodes, nid);
+
+	return 0;
+}

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

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 02/05] x86_64: NUMA cleanup
  2005-11-10  9:08 [PATCH 00/05][RFC] NUMA emulation update Magnus Damm
  2005-11-10  9:08 ` [PATCH 01/05] NUMA: Generic code Magnus Damm
@ 2005-11-10  9:08 ` Magnus Damm
  2005-11-10  9:08 ` [PATCH 03/05] x86_64: NUMA emulation Magnus Damm
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 14+ messages in thread
From: Magnus Damm @ 2005-11-10  9:08 UTC (permalink / raw)
  To: linux-mm, linux-kernel; +Cc: Magnus Damm, pj, ak

Rearrange the x86_64 NUMA code to make room for the new NUMA emulation code.

This patch rearranges the code and cleans it up a bit by moving duplicated
common code from srat.c and k8topology.c into numa.c.

Signed-off-by: Magnus Damm <magnus@valinux.co.jp>
---

 arch/x86_64/kernel/setup.c  |    7 ------
 arch/x86_64/mm/k8topology.c |   13 -----------
 arch/x86_64/mm/numa.c       |   51 +++++++++++++++++++++++++++++++-------------
 arch/x86_64/mm/srat.c       |   14 +-----------
 include/asm-x86_64/mmzone.h |    1
 5 files changed, 41 insertions(+), 45 deletions(-)

--- from-0002/arch/x86_64/kernel/setup.c
+++ to-work/arch/x86_64/kernel/setup.c	2005-11-08 21:33:12.000000000 +0900
@@ -581,13 +581,6 @@ void __init setup_arch(char **cmdline_p)
 	acpi_boot_table_init();
 #endif
 
-#ifdef CONFIG_ACPI_NUMA
-	/*
-	 * Parse SRAT to discover nodes.
-	 */
-	acpi_numa_init();
-#endif
-
 #ifdef CONFIG_NUMA
 	numa_initmem_init(0, end_pfn); 
 #else
--- from-0002/arch/x86_64/mm/k8topology.c
+++ to-work/arch/x86_64/mm/k8topology.c	2005-11-08 21:33:12.000000000 +0900
@@ -43,7 +43,6 @@ static __init int find_northbridge(void)
 int __init k8_scan_nodes(unsigned long start, unsigned long end)
 { 
 	unsigned long prevbase;
-	struct node nodes[8];
 	int nodeid, i, nb; 
 	unsigned char nodeids[8];
 	int found = 0;
@@ -65,7 +64,6 @@ int __init k8_scan_nodes(unsigned long s
 
 	printk(KERN_INFO "Number of nodes %d\n", numnodes);
 
-	memset(&nodes,0,sizeof(nodes)); 
 	prevbase = 0;
 	for (i = 0; i < 8; i++) { 
 		unsigned long base,limit; 
@@ -155,22 +153,13 @@ int __init k8_scan_nodes(unsigned long s
 	if (!found)
 		return -1; 
 
-	memnode_shift = compute_hash_shift(nodes, numnodes);
-	if (memnode_shift < 0) { 
-		printk(KERN_ERR "No NUMA node hash function found. Contact maintainer\n"); 
-		return -1; 
-	} 
-	printk(KERN_INFO "Using node hash shift of %d\n", memnode_shift); 
-
 	for (i = 0; i < 8; i++) {
 		if (nodes[i].start != nodes[i].end) { 
 			nodeid = nodeids[i];
 			apicid_to_node[nodeid << dualcore] = i;
 			apicid_to_node[(nodeid << dualcore) + dualcore] = i;
-			setup_node_bootmem(i, nodes[i].start, nodes[i].end); 
+			node_set_online(i);
 		} 
 	}
-
-	numa_init_array();
 	return 0;
 } 
--- from-0002/arch/x86_64/mm/numa.c
+++ to-work/arch/x86_64/mm/numa.c	2005-11-08 21:37:37.000000000 +0900
@@ -11,6 +11,7 @@
 #include <linux/ctype.h>
 #include <linux/module.h>
 #include <linux/nodemask.h>
+#include <linux/acpi.h>
 
 #include <asm/e820.h>
 #include <asm/proto.h>
@@ -25,6 +26,7 @@
 struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
 bootmem_data_t plat_node_bdata[MAX_NUMNODES];
 
+struct node nodes[MAX_NUMNODES] __initdata;
 int memnode_shift;
 u8  memnodemap[NODEMAPSIZE];
 
@@ -190,7 +192,6 @@ int numa_fake __initdata = 0;
 static int numa_emulation(unsigned long start_pfn, unsigned long end_pfn)
 {
  	int i;
- 	struct node nodes[MAX_NUMNODES];
  	unsigned long sz = ((end_pfn - start_pfn)<<PAGE_SHIFT) / numa_fake;
 
  	/* Kludge needed for the hash function */
@@ -203,7 +204,6 @@ static int numa_emulation(unsigned long 
  		sz = x;
  	}
 
- 	memset(&nodes,0,sizeof(nodes));
  	for (i = 0; i < numa_fake; i++) {
  		nodes[i].start = (start_pfn<<PAGE_SHIFT) + i*sz;
  		if (i == numa_fake-1)
@@ -215,38 +215,43 @@ static int numa_emulation(unsigned long 
  		       (nodes[i].end - nodes[i].start) >> 20);
 		node_set_online(i);
  	}
- 	memnode_shift = compute_hash_shift(nodes, numa_fake);
- 	if (memnode_shift < 0) {
- 		memnode_shift = 0;
- 		printk(KERN_ERR "No NUMA hash function found. Emulation disabled.\n");
- 		return -1;
- 	}
- 	for_each_online_node(i)
- 		setup_node_bootmem(i, nodes[i].start, nodes[i].end);
- 	numa_init_array();
  	return 0;
 }
 #endif
 
-void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
+void __init numa_initmem_doinit(unsigned long start_pfn, unsigned long end_pfn)
 { 
 	int i;
 
+	memset(&nodes,0,sizeof(nodes)); 
+
 #ifdef CONFIG_NUMA_EMU
 	if (numa_fake && !numa_emulation(start_pfn, end_pfn))
  		return;
 #endif
 
+	memset(&nodes,0,sizeof(nodes)); 
+
 #ifdef CONFIG_ACPI_NUMA
+	/*
+	 * Parse SRAT to discover nodes.
+	 */
+	acpi_numa_init();
+
 	if (!numa_off && !acpi_scan_nodes(start_pfn << PAGE_SHIFT,
 					  end_pfn << PAGE_SHIFT))
  		return;
 #endif
 
+	memset(&nodes,0,sizeof(nodes)); 
+
 #ifdef CONFIG_K8_NUMA
 	if (!numa_off && !k8_scan_nodes(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT))
 		return;
 #endif
+
+	memset(&nodes,0,sizeof(nodes)); 
+
 	printk(KERN_INFO "%s\n",
 	       numa_off ? "NUMA turned off" : "No NUMA configuration found");
 
@@ -254,14 +259,32 @@ void __init numa_initmem_init(unsigned l
 	       start_pfn << PAGE_SHIFT,
 	       end_pfn << PAGE_SHIFT); 
 		/* setup dummy node covering all memory */ 
-	memnode_shift = 63; 
 	memnodemap[0] = 0;
 	nodes_clear(node_online_map);
 	node_set_online(0);
 	for (i = 0; i < NR_CPUS; i++)
 		numa_set_node(i, 0);
 	node_to_cpumask[0] = cpumask_of_cpu(0);
-	setup_node_bootmem(0, start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT);
+	nodes[0].start = start_pfn << PAGE_SHIFT;
+	nodes[0].end = end_pfn << PAGE_SHIFT;
+}
+
+void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
+{ 
+	int i;
+
+	numa_initmem_doinit(start_pfn, end_pfn);
+
+	memnode_shift = compute_hash_shift(nodes, num_online_nodes());
+	if (memnode_shift < 0) { 
+		printk(KERN_ERR "No NUMA node hash function found. Contact maintainer\n"); 
+		return; 
+	} 
+	printk(KERN_INFO "Using node hash shift of %d\n", memnode_shift); 
+
+ 	for_each_online_node(i)
+ 		setup_node_bootmem(i, nodes[i].start, nodes[i].end);
+ 	numa_init_array();
 }
 
 __cpuinit void numa_add_cpu(int cpu)
--- from-0002/arch/x86_64/mm/srat.c
+++ to-work/arch/x86_64/mm/srat.c	2005-11-08 21:35:35.000000000 +0900
@@ -22,7 +22,6 @@ static struct acpi_table_slit *acpi_slit
 
 static nodemask_t nodes_parsed __initdata;
 static nodemask_t nodes_found __initdata;
-static struct node nodes[MAX_NUMNODES] __initdata;
 static __u8  pxm2node[256] = { [0 ... 255] = 0xff };
 
 static int node_to_pxm(int n);
@@ -182,26 +181,17 @@ int __init acpi_scan_nodes(unsigned long
 		cutoff_node(i, start, end);
 		if (nodes[i].start == nodes[i].end)
 			node_clear(i, nodes_parsed);
-	}
-
-	memnode_shift = compute_hash_shift(nodes, nodes_weight(nodes_parsed));
-	if (memnode_shift < 0) {
-		printk(KERN_ERR
-		     "SRAT: No NUMA node hash function found. Contact maintainer\n");
-		bad_srat();
-		return -1;
+		else
+			node_set_online(i);
 	}
 
 	/* Finally register nodes */
-	for_each_node_mask(i, nodes_parsed)
-		setup_node_bootmem(i, nodes[i].start, nodes[i].end);
 	for (i = 0; i < NR_CPUS; i++) { 
 		if (cpu_to_node[i] == NUMA_NO_NODE)
 			continue;
 		if (!node_isset(cpu_to_node[i], nodes_parsed))
 			numa_set_node(i, NUMA_NO_NODE);
 	}
-	numa_init_array();
 	return 0;
 }
 
--- from-0002/include/asm-x86_64/mmzone.h
+++ to-work/include/asm-x86_64/mmzone.h	2005-11-08 21:33:34.000000000 +0900
@@ -17,6 +17,7 @@
 /* Simple perfect hash to map physical addresses to node numbers */
 extern int memnode_shift; 
 extern u8  memnodemap[NODEMAPSIZE]; 
+extern struct node nodes[MAX_NUMNODES] __initdata;
 
 extern struct pglist_data *node_data[];
 

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

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 03/05] x86_64: NUMA emulation
  2005-11-10  9:08 [PATCH 00/05][RFC] NUMA emulation update Magnus Damm
  2005-11-10  9:08 ` [PATCH 01/05] NUMA: Generic code Magnus Damm
  2005-11-10  9:08 ` [PATCH 02/05] x86_64: NUMA cleanup Magnus Damm
@ 2005-11-10  9:08 ` Magnus Damm
  2005-11-10  9:08 ` [PATCH 04/05] x86_64: NUMA without SMP Magnus Damm
  2005-11-10  9:08 ` [PATCH 05/05] NUMA: find_next_best_node fix Magnus Damm
  4 siblings, 0 replies; 14+ messages in thread
From: Magnus Damm @ 2005-11-10  9:08 UTC (permalink / raw)
  To: linux-mm, linux-kernel; +Cc: Magnus Damm, pj, ak

Improve the x86_64 NUMA emulation code to use the generic NUMA emulation code.

This patch replaces the current x86_64 CONFIG_NUMA_EMU code with a more 
advanced implementation that uses the generic NUMA emulation code. The x86_64 
NUMA emulation today only supports dividing of nodes on single node systems, 
but this implementation supports both single node systems and larger systems
with multiple NUMA nodes. With the patch, each real NUMA node will be divided
into several smaller nodes during boot if requested on the kernel command line.

Signed-off-by: Magnus Damm <magnus@valinux.co.jp>
---

 arch/x86_64/Kconfig           |   11 +--
 arch/x86_64/mm/numa.c         |  119 +++++++++++++++++++++---------------------
 include/asm-x86_64/numa.h     |    1
 include/asm-x86_64/numnodes.h |    6 +-
 4 files changed, 68 insertions(+), 69 deletions(-)

--- from-0005/arch/x86_64/Kconfig
+++ to-work/arch/x86_64/Kconfig	2005-11-09 11:50:03.000000000 +0900
@@ -258,14 +258,6 @@ config X86_64_ACPI_NUMA
        help
 	 Enable ACPI SRAT based node topology detection.
 
-config NUMA_EMU
-	bool "NUMA emulation"
-	depends on NUMA
-	help
-	  Enable NUMA emulation. A flat machine will be split
-	  into virtual nodes when booted with "numa=fake=N", where N is the
-	  number of nodes. This is only useful for debugging.
-
 config ARCH_DISCONTIGMEM_ENABLE
        bool
        depends on NUMA
@@ -288,6 +280,9 @@ config ARCH_FLATMEM_ENABLE
 	def_bool y
 	depends on !NUMA
 
+config ARCH_NUMA_EMU_ENABLE
+	def_bool y
+
 source "mm/Kconfig"
 
 config HAVE_ARCH_EARLY_PFN_TO_NID
--- from-0006/arch/x86_64/mm/numa.c
+++ to-work/arch/x86_64/mm/numa.c	2005-11-09 17:50:54.000000000 +0900
@@ -48,15 +48,14 @@ int numa_off __initdata;
  * 0 if memnodmap[] too small (of shift too small)
  * -1 if node overlap or lost ram (shift too big)
  */
-static int __init populate_memnodemap(
-	const struct node *nodes, int numnodes, int shift)
+static int __init populate_memnodemap(const struct node *nodes, int shift)
 {
 	int i; 
 	int res = -1;
 	unsigned long addr, end;
 
 	memset(memnodemap, 0xff, sizeof(memnodemap));
-	for (i = 0; i < numnodes; i++) {
+	for_each_online_node(i) {
 		addr = nodes[i].start;
 		end = nodes[i].end;
 		if (addr >= end)
@@ -74,17 +73,17 @@ static int __init populate_memnodemap(
 	return res;
 }
 
-int __init compute_hash_shift(struct node *nodes, int numnodes)
+int __init compute_hash_shift(struct node *nodes)
 {
 	int shift = 20;
 
-	while (populate_memnodemap(nodes, numnodes, shift + 1) >= 0)
+	while (populate_memnodemap(nodes, shift + 1) >= 0)
 		shift++;
 
 	printk(KERN_DEBUG "Using %d for the hash shift.\n",
 		shift);
 
-	if (populate_memnodemap(nodes, numnodes, shift) != 1) {
+	if (populate_memnodemap(nodes, shift) != 1) {
 		printk(KERN_INFO
 	"Your memory is not aligned you need to rebuild your kernel "
 	"with a bigger NODEMAPSIZE shift=%d\n",
@@ -186,36 +185,53 @@ void __init numa_init_array(void)
 }
 
 #ifdef CONFIG_NUMA_EMU
-int numa_fake __initdata = 0;
-
-/* Numa emulation */
-static int numa_emulation(unsigned long start_pfn, unsigned long end_pfn)
+void __init numa_emu_setup_nid(int real_nid)
 {
- 	int i;
- 	unsigned long sz = ((end_pfn - start_pfn)<<PAGE_SHIFT) / numa_fake;
+	unsigned long start_pfn, end_pfn;
+	int real_max = 1 << NODES_SHIFT_HW;
+	int nid, new_nodes;
+
+	if (real_nid >= real_max)
+		return;
+
+	/* setup emulated nodes */
+
+	new_nodes = 0;
+
+	for (nid = real_nid + real_max; nid < MAX_NUMNODES; nid += real_max) { 
+		if (numa_emu_new(nid, nodes[real_nid].start >> PAGE_SHIFT, 
+				 nodes[real_nid].end >> PAGE_SHIFT,
+				 &start_pfn, &end_pfn) != 0)
+		     break;
+
+		nodes[nid].start = start_pfn << PAGE_SHIFT;
+		nodes[nid].end = end_pfn << PAGE_SHIFT;
+		new_nodes++;
+	}
+
+	if (!new_nodes)
+		return;
+
+	/* shrink real node */
+
+	if (numa_emu_shrink(real_nid, new_nodes,
+			    nodes[real_nid].start >> PAGE_SHIFT, 
+			    nodes[real_nid].end >> PAGE_SHIFT,
+			    &start_pfn, &end_pfn) != 0)
+		return;
+
+	nodes[real_nid].start = start_pfn << PAGE_SHIFT;
+	nodes[real_nid].end = end_pfn << PAGE_SHIFT;
+
+	/* set emulated nodes online */
+
+	for (nid = real_nid + real_max; nid < MAX_NUMNODES; nid += real_max) { 
+		node_set_online(nid);
+
+		if (!--new_nodes)
+			break;
+	}
 
- 	/* Kludge needed for the hash function */
- 	if (hweight64(sz) > 1) {
- 		unsigned long x = 1;
- 		while ((x << 1) < sz)
- 			x <<= 1;
- 		if (x < sz/2)
- 			printk("Numa emulation unbalanced. Complain to maintainer\n");
- 		sz = x;
- 	}
-
- 	for (i = 0; i < numa_fake; i++) {
- 		nodes[i].start = (start_pfn<<PAGE_SHIFT) + i*sz;
- 		if (i == numa_fake-1)
- 			sz = (end_pfn<<PAGE_SHIFT) - nodes[i].start;
- 		nodes[i].end = nodes[i].start + sz;
- 		printk(KERN_INFO "Faking node %d at %016Lx-%016Lx (%LuMB)\n",
- 		       i,
- 		       nodes[i].start, nodes[i].end,
- 		       (nodes[i].end - nodes[i].start) >> 20);
-		node_set_online(i);
- 	}
- 	return 0;
 }
 #endif
 
@@ -223,16 +239,10 @@ void __init numa_initmem_doinit(unsigned
 { 
 	int i;
 
+#ifdef CONFIG_ACPI_NUMA
+	nodes_clear(node_online_map);
 	memset(&nodes,0,sizeof(nodes)); 
 
-#ifdef CONFIG_NUMA_EMU
-	if (numa_fake && !numa_emulation(start_pfn, end_pfn))
- 		return;
-#endif
-
-	memset(&nodes,0,sizeof(nodes)); 
-
-#ifdef CONFIG_ACPI_NUMA
 	/*
 	 * Parse SRAT to discover nodes.
 	 */
@@ -243,28 +253,26 @@ void __init numa_initmem_doinit(unsigned
  		return;
 #endif
 
+#ifdef CONFIG_K8_NUMA
+	nodes_clear(node_online_map);
 	memset(&nodes,0,sizeof(nodes)); 
 
-#ifdef CONFIG_K8_NUMA
 	if (!numa_off && !k8_scan_nodes(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT))
 		return;
 #endif
 
+	nodes_clear(node_online_map);
 	memset(&nodes,0,sizeof(nodes)); 
 
 	printk(KERN_INFO "%s\n",
 	       numa_off ? "NUMA turned off" : "No NUMA configuration found");
 
-	printk(KERN_INFO "Faking a node at %016lx-%016lx\n", 
+	printk(KERN_INFO "Single node at %016lx-%016lx\n", 
 	       start_pfn << PAGE_SHIFT,
 	       end_pfn << PAGE_SHIFT); 
 		/* setup dummy node covering all memory */ 
-	memnodemap[0] = 0;
-	nodes_clear(node_online_map);
+
 	node_set_online(0);
-	for (i = 0; i < NR_CPUS; i++)
-		numa_set_node(i, 0);
-	node_to_cpumask[0] = cpumask_of_cpu(0);
 	nodes[0].start = start_pfn << PAGE_SHIFT;
 	nodes[0].end = end_pfn << PAGE_SHIFT;
 }
@@ -275,7 +283,10 @@ void __init numa_initmem_init(unsigned l
 
 	numa_initmem_doinit(start_pfn, end_pfn);
 
-	memnode_shift = compute_hash_shift(nodes, num_online_nodes());
+	for_each_online_node(i)
+		numa_emu_setup_nid(i);
+
+	memnode_shift = compute_hash_shift(nodes);
 	if (memnode_shift < 0) { 
 		printk(KERN_ERR "No NUMA node hash function found. Contact maintainer\n"); 
 		return; 
@@ -321,13 +332,7 @@ __init int numa_setup(char *opt) 
 { 
 	if (!strncmp(opt,"off",3))
 		numa_off = 1;
-#ifdef CONFIG_NUMA_EMU
-	if(!strncmp(opt, "fake=", 5)) {
-		numa_fake = simple_strtoul(opt+5,NULL,0); ;
-		if (numa_fake >= MAX_NUMNODES)
-			numa_fake = MAX_NUMNODES;
-	}
-#endif
+        numa_emu_setup(opt);
 #ifdef CONFIG_ACPI_NUMA
  	if (!strncmp(opt,"noacpi",6))
  		acpi_numa = -1;
--- from-0002/include/asm-x86_64/numa.h
+++ to-work/include/asm-x86_64/numa.h	2005-11-09 11:50:03.000000000 +0900
@@ -8,7 +8,6 @@ struct node { 
 	u64 start,end; 
 };
 
-extern int compute_hash_shift(struct node *nodes, int numnodes);
 extern int pxm_to_node(int nid);
 
 #define ZONE_ALIGN (1UL << (MAX_ORDER+PAGE_SHIFT))
--- from-0001/include/asm-x86_64/numnodes.h
+++ to-work/include/asm-x86_64/numnodes.h	2005-11-09 11:50:03.000000000 +0900
@@ -3,10 +3,10 @@
 
 #include <linux/config.h>
 
-#ifdef CONFIG_NUMA
-#define NODES_SHIFT	6
+#if defined(CONFIG_K8_NUMA) || defined(CONFIG_ACPI_NUMA)
+#define NODES_SHIFT_HW	3
 #else
-#define NODES_SHIFT	0
+#define NODES_SHIFT_HW	0
 #endif
 
 #endif

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

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 04/05] x86_64: NUMA without SMP
  2005-11-10  9:08 [PATCH 00/05][RFC] NUMA emulation update Magnus Damm
                   ` (2 preceding siblings ...)
  2005-11-10  9:08 ` [PATCH 03/05] x86_64: NUMA emulation Magnus Damm
@ 2005-11-10  9:08 ` Magnus Damm
  2005-11-10  9:08 ` [PATCH 05/05] NUMA: find_next_best_node fix Magnus Damm
  4 siblings, 0 replies; 14+ messages in thread
From: Magnus Damm @ 2005-11-10  9:08 UTC (permalink / raw)
  To: linux-mm, linux-kernel; +Cc: Magnus Damm, pj, ak

Remove the SMP dependency from NUMA on x86_64.

This simple change is boot tested on real x86_64 NUMA hardware and in QEMU. 
Works with CONFIG_NUMA_EMU, CONFIG_K8_NUMA and CONFIG_ACPI_NUMA. This change
has earlier been discussed with Andi Kleen and rejected, but it is included
in this patch set for completeness.

Signed-off-by: Magnus Damm <magnus@valinux.co.jp>
---

 Kconfig |    1 -
 1 files changed, 1 deletion(-)

--- from-0002/arch/x86_64/Kconfig
+++ to-0005/arch/x86_64/Kconfig	2005-11-08 21:26:03.000000000 +0900
@@ -228,7 +228,6 @@ source "kernel/Kconfig.preempt"
 
 config NUMA
        bool "Non Uniform Memory Access (NUMA) Support"
-       depends on SMP
        help
 	 Enable NUMA (Non Uniform Memory Access) support. The kernel 
 	 will try to allocate memory used by a CPU on the local memory 

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

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 05/05] NUMA: find_next_best_node fix
  2005-11-10  9:08 [PATCH 00/05][RFC] NUMA emulation update Magnus Damm
                   ` (3 preceding siblings ...)
  2005-11-10  9:08 ` [PATCH 04/05] x86_64: NUMA without SMP Magnus Damm
@ 2005-11-10  9:08 ` Magnus Damm
  4 siblings, 0 replies; 14+ messages in thread
From: Magnus Damm @ 2005-11-10  9:08 UTC (permalink / raw)
  To: linux-mm, linux-kernel; +Cc: Magnus Damm, pj, ak

Fix find_next_best_node() to support node masks with holes.

find_next_best_node() does currently not support node masks with holes. For 
instance, a node mask with nodes 1, 8 and 16 online will not work correctly.
The use of % num_online_nodes() in the code below hints that only a single 
contiguous range of nodes is supported without this patch.

Signed-off-by: Magnus Damm <magnus@valinux.co.jp>
---

 page_alloc.c |   25 +++++++++++++++----------
 1 files changed, 15 insertions(+), 10 deletions(-)

--- from-0002/mm/page_alloc.c
+++ to-work/mm/page_alloc.c	2005-11-09 17:48:24.000000000 +0900
@@ -1554,26 +1554,31 @@ static int __initdata node_load[MAX_NUMN
  */
 static int __init find_next_best_node(int node, nodemask_t *used_node_mask)
 {
-	int i, n, val;
+	int n, val;
 	int min_val = INT_MAX;
 	int best_node = -1;
+	int first_node = node;
 
-	for_each_online_node(i) {
+	/* Use the local node if we haven't already */
+	if (node_isset(node, *used_node_mask))
+		n = !first_node;
+	else {
+		n = first_node;
+		best_node = node;
+	}
+
+	for (; n != first_node; node = n) {
 		cpumask_t tmp;
 
-		/* Start from local node */
-		n = (node+i) % num_online_nodes();
+		n = next_node(node, node_online_map);
+
+		if (n == MAX_NUMNODES)
+			n = first_node(node_online_map);
 
 		/* Don't want a node to appear more than once */
 		if (node_isset(n, *used_node_mask))
 			continue;
 
-		/* Use the local node if we haven't already */
-		if (!node_isset(node, *used_node_mask)) {
-			best_node = node;
-			break;
-		}
-
 		/* Use the distance array to find the distance */
 		val = node_distance(node, n);
 

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

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 01/05] NUMA: Generic code
  2005-11-10  9:08 ` [PATCH 01/05] NUMA: Generic code Magnus Damm
@ 2005-11-11  4:16   ` Andi Kleen
  2005-11-15  8:34     ` Magnus Damm
  0 siblings, 1 reply; 14+ messages in thread
From: Andi Kleen @ 2005-11-11  4:16 UTC (permalink / raw)
  To: Magnus Damm; +Cc: linux-mm, linux-kernel, pj

On Thursday 10 November 2005 10:08, Magnus Damm wrote:
> Generic CONFIG_NUMA_EMU code.
>
> This patch adds generic NUMA emulation code to the kernel. The code
> provides the architectures with functions that calculate the size of
> emulated nodes, together with configuration stuff such as Kconfig and
> kernel command line code.

IMHO making it generic and bloated like this is total overkill
for this simple debugginghack. I think it is better to keep 
it simple and hiden it in a architecture specific dark corners, not expose it 
like this.

I think the patch shouldn't be applied.

-Andi

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

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 01/05] NUMA: Generic code
  2005-11-11  4:16   ` Andi Kleen
@ 2005-11-15  8:34     ` Magnus Damm
  2005-11-15 14:15       ` Andi Kleen
  0 siblings, 1 reply; 14+ messages in thread
From: Magnus Damm @ 2005-11-15  8:34 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Magnus Damm, linux-mm, linux-kernel, pj

On 11/11/05, Andi Kleen <ak@suse.de> wrote:
> On Thursday 10 November 2005 10:08, Magnus Damm wrote:
> > Generic CONFIG_NUMA_EMU code.
> >
> > This patch adds generic NUMA emulation code to the kernel. The code
> > provides the architectures with functions that calculate the size of
> > emulated nodes, together with configuration stuff such as Kconfig and
> > kernel command line code.
>
> IMHO making it generic and bloated like this is total overkill
> for this simple debugginghack. I think it is better to keep
> it simple and hiden it in a architecture specific dark corners, not expose it
> like this.

My plan with breaking out the NUMA emulation code was to merge my i386
stuff with the x86_64 code, but as you say - it might be overkill.

What do you think about the fact that real NUMA nodes now can be
divided into several smaller nodes?

/ magnus

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

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 01/05] NUMA: Generic code
  2005-11-15  8:34     ` Magnus Damm
@ 2005-11-15 14:15       ` Andi Kleen
  2005-11-16  5:22         ` Magnus Damm
  0 siblings, 1 reply; 14+ messages in thread
From: Andi Kleen @ 2005-11-15 14:15 UTC (permalink / raw)
  To: Magnus Damm; +Cc: Magnus Damm, linux-mm, linux-kernel, pj

On Tuesday 15 November 2005 09:34, Magnus Damm wrote:

> 
> My plan with breaking out the NUMA emulation code was to merge my i386
> stuff with the x86_64 code, but as you say - it might be overkill.
> 
> What do you think about the fact that real NUMA nodes now can be
> divided into several smaller nodes?

Is it really needed? I never needed it.  Normally numa emulation 
is just for basic numa testing, and for that just an independent
split is good enough.

-Andi

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

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 01/05] NUMA: Generic code
  2005-11-15 14:15       ` Andi Kleen
@ 2005-11-16  5:22         ` Magnus Damm
  2005-11-16  7:48           ` Andi Kleen
  0 siblings, 1 reply; 14+ messages in thread
From: Magnus Damm @ 2005-11-16  5:22 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Magnus Damm, linux-mm, linux-kernel, pj

On 11/15/05, Andi Kleen <ak@suse.de> wrote:
> On Tuesday 15 November 2005 09:34, Magnus Damm wrote:
>
> >
> > My plan with breaking out the NUMA emulation code was to merge my i386
> > stuff with the x86_64 code, but as you say - it might be overkill.
> >
> > What do you think about the fact that real NUMA nodes now can be
> > divided into several smaller nodes?
>
> Is it really needed? I never needed it.  Normally numa emulation
> is just for basic numa testing, and for that just an independent
> split is good enough.

For testing, your NUMA emulation code is perfect IMO. But for memory
resource control your NUMA emulation code may be too simple.

With my patch, CONFIG_NUMA_EMU provides a way to partition a machine
into several smaller nodes, regardless if the machine is using NUMA or
not.

This NUMA emulation code together with CPUSETS could be seen as a
simple alternative to the memory resource control provided by CKRM.

/ magnus

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

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 01/05] NUMA: Generic code
  2005-11-16  5:22         ` Magnus Damm
@ 2005-11-16  7:48           ` Andi Kleen
  2005-11-16  7:57             ` Magnus Damm
  0 siblings, 1 reply; 14+ messages in thread
From: Andi Kleen @ 2005-11-16  7:48 UTC (permalink / raw)
  To: Magnus Damm; +Cc: Magnus Damm, linux-mm, linux-kernel, pj, werner

Magnus Damm <magnus.damm@gmail.com> writes:
> 
> For testing, your NUMA emulation code is perfect IMO. But for memory
> resource control your NUMA emulation code may be too simple.
> 
> With my patch, CONFIG_NUMA_EMU provides a way to partition a machine
> into several smaller nodes, regardless if the machine is using NUMA or
> not.
> 
> This NUMA emulation code together with CPUSETS could be seen as a
> simple alternative to the memory resource control provided by CKRM.

I believe Werner tried to use it at some point for that and it just
didn't work very well. So it doesn't seem to be very useful for
that usecase.

-Andi

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

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 01/05] NUMA: Generic code
  2005-11-16  7:48           ` Andi Kleen
@ 2005-11-16  7:57             ` Magnus Damm
  2005-11-16  8:38               ` Andi Kleen
  2005-11-16 11:31               ` Werner Almesberger
  0 siblings, 2 replies; 14+ messages in thread
From: Magnus Damm @ 2005-11-16  7:57 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Magnus Damm, linux-mm, linux-kernel, pj, werner

On 16 Nov 2005 08:48:39 +0100, Andi Kleen <ak@suse.de> wrote:
> Magnus Damm <magnus.damm@gmail.com> writes:
> >
> > For testing, your NUMA emulation code is perfect IMO. But for memory
> > resource control your NUMA emulation code may be too simple.
> >
> > With my patch, CONFIG_NUMA_EMU provides a way to partition a machine
> > into several smaller nodes, regardless if the machine is using NUMA or
> > not.
> >
> > This NUMA emulation code together with CPUSETS could be seen as a
> > simple alternative to the memory resource control provided by CKRM.
>
> I believe Werner tried to use it at some point for that and it just
> didn't work very well. So it doesn't seem to be very useful for
> that usecase.

Sorry, but which one did not work very well? CKRM memory controller or
NUMA emulation + CPUSETS?

Thanks,

/ magnus

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

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 01/05] NUMA: Generic code
  2005-11-16  7:57             ` Magnus Damm
@ 2005-11-16  8:38               ` Andi Kleen
  2005-11-16 11:31               ` Werner Almesberger
  1 sibling, 0 replies; 14+ messages in thread
From: Andi Kleen @ 2005-11-16  8:38 UTC (permalink / raw)
  To: Magnus Damm; +Cc: Magnus Damm, linux-mm, linux-kernel, pj, werner

On Wednesday 16 November 2005 08:57, Magnus Damm wrote:

> 
> Sorry, but which one did not work very well? CKRM memory controller or
> NUMA emulation + CPUSETS?

Using simulated nodes for controlling memory.

-Andi

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

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 01/05] NUMA: Generic code
  2005-11-16  7:57             ` Magnus Damm
  2005-11-16  8:38               ` Andi Kleen
@ 2005-11-16 11:31               ` Werner Almesberger
  1 sibling, 0 replies; 14+ messages in thread
From: Werner Almesberger @ 2005-11-16 11:31 UTC (permalink / raw)
  To: Magnus Damm; +Cc: Andi Kleen, Magnus Damm, linux-mm, linux-kernel, pj

Magnus Damm wrote:
> Sorry, but which one did not work very well? CKRM memory controller or
> NUMA emulation + CPUSETS?

We tried to partition our memory using the NUMA emulation, such that
timing-critical processes would allocate from one node, while all
the rest of the system would allocate from the other node.

The idea was that the timing-critical processes, with a fairly
"calm" allocation behaviour (read file data into the page cache,
then evict it again), would never or almost never trigger memory
reclaim this way, and thus have better worst-case latency.

Unfortunately, our benchmarks didn't show any improvements in
latency. In fact, the results were slightly worse, perhaps because
of processes on the "regular" node holding shared resources while
in memory reclaim.

I'm not entirely sure why this didn't work better. At least in
theory, it should have.

We did this in the ABISS project, about one year ago in response
to quite nasty reclaim latency suddenly appearing in an earlier
2.6 kernel. When we asked various MM developers, but none of them
was aware of any change that would make reclaims all of a sudden
very intrusive, and they attributed it to the "butterfly effect".
After a while (i.e., in later kernels), the butterflies must have
chosen a different victim, and the latency got better on its own.

So, in the end, we didn't need that NUMA hack to control reclaims.
But if they should rear their ugly heads again, it may be worth
having a second look.

- Werner

-- 
  _________________________________________________________________________
 / Werner Almesberger, Buenos Aires, Argentina     werner@almesberger.net /
/_http://www.almesberger.net/____________________________________________/

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

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2005-11-16 11:31 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-11-10  9:08 [PATCH 00/05][RFC] NUMA emulation update Magnus Damm
2005-11-10  9:08 ` [PATCH 01/05] NUMA: Generic code Magnus Damm
2005-11-11  4:16   ` Andi Kleen
2005-11-15  8:34     ` Magnus Damm
2005-11-15 14:15       ` Andi Kleen
2005-11-16  5:22         ` Magnus Damm
2005-11-16  7:48           ` Andi Kleen
2005-11-16  7:57             ` Magnus Damm
2005-11-16  8:38               ` Andi Kleen
2005-11-16 11:31               ` Werner Almesberger
2005-11-10  9:08 ` [PATCH 02/05] x86_64: NUMA cleanup Magnus Damm
2005-11-10  9:08 ` [PATCH 03/05] x86_64: NUMA emulation Magnus Damm
2005-11-10  9:08 ` [PATCH 04/05] x86_64: NUMA without SMP Magnus Damm
2005-11-10  9:08 ` [PATCH 05/05] NUMA: find_next_best_node fix Magnus Damm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox