public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] (2/7) make i386 topology caching
@ 2003-01-07 20:20 Martin J. Bligh
  0 siblings, 0 replies; only message in thread
From: Martin J. Bligh @ 2003-01-07 20:20 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel

Patch originally by Matt Dobson. Reworked a little by me.

Stores the mappings between cpus and nodes in an array, instead of
working them out every time. Gives about 4% off systime for kernel
compile (we use these for every page allocation), and removes one
of the two only usages of apicid->cpu mapping, which is really awkward
to keep for systems with large apic spaces, and is genererally pretty
useless anyway (later patch removes).

diff -urpN -X /home/fletch/.diff.exclude 01-apicid_to_node/arch/i386/kernel/smpboot.c 02-i386_caching_topo/arch/i386/kernel/smpboot.c
--- 01-apicid_to_node/arch/i386/kernel/smpboot.c	Thu Jan  2 22:04:58 2003
+++ 02-i386_caching_topo/arch/i386/kernel/smpboot.c	Tue Jan  7 09:24:51 2003
@@ -503,6 +503,39 @@ static struct task_struct * __init fork_
 	return do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL, NULL);
 }

+#ifdef CONFIG_NUMA
+
+/* which logical CPUs are on which nodes */
+volatile unsigned long node_2_cpu_mask[MAX_NR_NODES] =
+						{ [0 ... MAX_NR_NODES-1] = 0 };
+/* which node each logical CPU is on */
+volatile int cpu_2_node[NR_CPUS] = { [0 ... NR_CPUS-1] = 0 };
+
+/* set up a mapping between cpu and node. */
+static inline void map_cpu_to_node(int cpu, int node)
+{
+	printk("Mapping cpu %d to node %d\n", cpu, node);
+	node_2_cpu_mask[node] |= (1 << cpu);
+	cpu_2_node[cpu] = node;
+}
+
+/* undo a mapping between cpu and node. */
+static inline void unmap_cpu_to_node(int cpu)
+{
+	int node;
+
+	printk("Unmapping cpu %d from all nodes\n", cpu);
+	for (node = 0; node < MAX_NR_NODES; node ++)
+		node_2_cpu_mask[node] &= ~(1 << cpu);
+	cpu_2_node[cpu] = -1;
+}
+#else /* !CONFIG_NUMA */
+
+#define map_cpu_to_node(cpu, node)	({})
+#define unmap_cpu_to_node(cpu)	({})
+
+#endif /* CONFIG_NUMA */
+
 /* which physical APIC ID maps to which logical CPU number */
 volatile int physical_apicid_2_cpu[MAX_APICID];
 /* which logical CPU number maps to which physical APIC ID */
@@ -537,6 +570,7 @@ static inline void map_cpu_to_boot_apici
 	if (clustered_apic_mode) {
 		logical_apicid_2_cpu[apicid] = cpu;	
 		cpu_2_logical_apicid[cpu] = apicid;
+		map_cpu_to_node(cpu, apicid_to_node(apicid));
 	} else {
 		physical_apicid_2_cpu[apicid] = cpu;	
 		cpu_2_physical_apicid[cpu] = apicid;
@@ -552,6 +586,7 @@ static inline void unmap_cpu_to_boot_api
 	if (clustered_apic_mode) {
 		logical_apicid_2_cpu[apicid] = -1;	
 		cpu_2_logical_apicid[cpu] = -1;
+		unmap_cpu_to_node(cpu);
 	} else {
 		physical_apicid_2_cpu[apicid] = -1;	
 		cpu_2_physical_apicid[cpu] = -1;
diff -urpN -X /home/fletch/.diff.exclude 01-apicid_to_node/include/asm-i386/topology.h 02-i386_caching_topo/include/asm-i386/topology.h
--- 01-apicid_to_node/include/asm-i386/topology.h	Sun Nov 17 20:29:26 2002
+++ 02-i386_caching_topo/include/asm-i386/topology.h	Tue Jan  7 09:24:51 2003
@@ -27,12 +27,17 @@
 #ifndef _ASM_I386_TOPOLOGY_H
 #define _ASM_I386_TOPOLOGY_H

-#ifdef CONFIG_X86_NUMAQ
+#ifdef CONFIG_NUMA

-#include <asm/smpboot.h>
+/* Mappings between logical cpu number and node number */
+extern volatile unsigned long node_2_cpu_mask[];
+extern volatile int cpu_2_node[];

 /* Returns the number of the node containing CPU 'cpu' */
-#define __cpu_to_node(cpu) (cpu_to_logical_apicid(cpu) >> 4)
+static inline int __cpu_to_node(int cpu)
+{
+	return cpu_2_node[cpu];
+}

 /* Returns the number of the node containing MemBlk 'memblk' */
 #define __memblk_to_node(memblk) (memblk)
@@ -41,49 +46,22 @@
    so it is a pretty simple function! */
 #define __parent_node(node) (node)

-/* Returns the number of the first CPU on Node 'node'.
- * This should be changed to a set of cached values
- * but this will do for now.
- */
-static inline int __node_to_first_cpu(int node)
-{
-	int i, cpu, logical_apicid = node << 4;
-
-	for(i = 1; i < 16; i <<= 1)
-		/* check to see if the cpu is in the system */
-		if ((cpu = logical_apicid_to_cpu(logical_apicid | i)) >= 0)
-			/* if yes, return it to caller */
-			return cpu;
-
-	BUG(); /* couldn't find a cpu on given node */
-	return -1;
-}
-
-/* Returns a bitmask of CPUs on Node 'node'.
- * This should be changed to a set of cached bitmasks
- * but this will do for now.
- */
+/* Returns a bitmask of CPUs on Node 'node'. */
 static inline unsigned long __node_to_cpu_mask(int node)
 {
-	int i, cpu, logical_apicid = node << 4;
-	unsigned long mask = 0UL;
-
-	if (sizeof(unsigned long) * 8 < NR_CPUS)
-		BUG();
-
-	for(i = 1; i < 16; i <<= 1)
-		/* check to see if the cpu is in the system */
-		if ((cpu = logical_apicid_to_cpu(logical_apicid | i)) >= 0)
-			/* if yes, add to bitmask */
-			mask |= 1 << cpu;
+	return node_2_cpu_mask[node];
+}

-	return mask;
+/* Returns the number of the first CPU on Node 'node'. */
+static inline int __node_to_first_cpu(int node)
+{
+	return __ffs(__node_to_cpu_mask(node));
 }

 /* Returns the number of the first MemBlk on Node 'node' */
 #define __node_to_memblk(node) (node)

-#else /* !CONFIG_X86_NUMAQ */
+#else /* !CONFIG_NUMA */
 /*
  * Other i386 platforms should define their own version of the
  * above macros here.
@@ -91,6 +69,6 @@ static inline unsigned long __node_to_cp

 #include <asm-generic/topology.h>

-#endif /* CONFIG_X86_NUMAQ */
+#endif /* CONFIG_NUMA */

 #endif /* _ASM_I386_TOPOLOGY_H */


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2003-01-07 20:33 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-01-07 20:20 [PATCH] (2/7) make i386 topology caching Martin J. Bligh

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