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@xxxxxxxxxxx> 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) \