[RFC PATCH 03/09] robust VM per_cpu generic header

Steven Rostedt rostedt at goodmis.org
Wed May 17 19:57:37 EST 2006


This patch adds the VM per_cpu to the generic per_cpu.h header.

If __ARCH_HAS_VM_PERCPU is defined, it is expected that the arch
also defined the following:

PERCPU_START - start of VM area that per_cpu variables will be stored.
PERCPU_SIZE - size of the VM area for each CPU.  So the total size
		would be PERCPU_SIZE * NR_CPU

If __ARCH_HAS_VM_PERCPU is not defined, it falls back to the old
percpu hack.

Signed-off-by: Steven Rostedt <rostedt at goodmis.org>

Index: linux-2.6.16-test/include/asm-generic/percpu.h
===================================================================
--- linux-2.6.16-test.orig/include/asm-generic/percpu.h	2006-05-17 04:32:27.000000000 -0400
+++ linux-2.6.16-test/include/asm-generic/percpu.h	2006-05-17 04:57:21.000000000 -0400
@@ -5,25 +5,52 @@
 #define __GENERIC_PER_CPU
 #ifdef CONFIG_SMP

-extern unsigned long __per_cpu_offset[NR_CPUS];
-
 /* Separate out the type, so (int[3], foo) works. */
 #define DEFINE_PER_CPU(type, name) \
     __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name

+#ifdef __ARCH_HAS_VM_PERCPU
+
+#include <asm/sections.h>
+
+/*
+ * This is included in linux/percpu.h and if PERCPU_ENOUGH_ROOM is already
+ * defined, it wont overwrite it.
+ * This allows kernel/module.c to be the same for both archs with VM
+ * per_cpu and without.
+ */
+#define PERCPU_ENOUGH_ROOM PERCPU_SIZE
+
+#define __PERCPU_OFFSET_ADDRESS(i) ((PERCPU_START+PERCPU_SIZE*(i)) - \
+			(unsigned long)__per_cpu_start)
+
+extern void setup_per_cpu_areas (void);
+extern int percpu_modcopy(void *pcpudst, void *src, unsigned long size);
+
+#else /* !__ARCH_HAS_VM_PERCPU */
+
+extern unsigned long __per_cpu_offset[NR_CPUS];
+
+#define __PERCPU_OFFSET_ADDRESS(i) __per_cpu_offset[i]
+
+/* A macro to avoid #include hell... */
+#define percpu_modcopy(pcpudst, src, size)				\
+({									\
+	unsigned int __i;						\
+	for (__i = 0; __i < NR_CPUS; __i++)				\
+		if (cpu_possible(__i))					\
+			memcpy((pcpudst)+__PERCPU_OFFSET_ADDRESS(__i),	\
+			       (src), (size));				\
+	0;								\
+})
+
+#endif /* __ARCH_HAS_VM_PERCPU */
+
 /* var is in discarded region: offset to particular copy we want */
-#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]))
+#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, \
+					__PERCPU_OFFSET_ADDRESS(cpu)))
 #define __get_cpu_var(var) per_cpu(var, smp_processor_id())

-/* A macro to avoid #include hell... */
-#define percpu_modcopy(pcpudst, src, size)			\
-do {								\
-	unsigned int __i;					\
-	for (__i = 0; __i < NR_CPUS; __i++)			\
-		if (cpu_possible(__i))				\
-			memcpy((pcpudst)+__per_cpu_offset[__i],	\
-			       (src), (size));			\
-} while (0)
 #else /* ! SMP */

 #define DEFINE_PER_CPU(type, name) \




More information about the Linuxppc-dev mailing list