--- include/asm-generic/percpu.h | 4 ++-- include/asm-ia64/page.h | 2 +- include/linux/percpu.h | 2 ++ mm/allocpercpu.c | 26 +++++++++++++++++--------- 4 files changed, 22 insertions(+), 12 deletions(-) Index: linux-2.6/mm/allocpercpu.c =================================================================== --- linux-2.6.orig/mm/allocpercpu.c 2007-11-01 11:47:06.952979728 -0700 +++ linux-2.6/mm/allocpercpu.c 2007-11-01 11:47:16.769208980 -0700 @@ -28,7 +28,12 @@ /* * Maximum allowed per cpu data per cpu */ +#ifdef CONFIG_NUMA +#define PER_CPU_ALLOC_SIZE (32768 + MAX_NUMNODES * 512) +#else #define PER_CPU_ALLOC_SIZE 32768 +#endif + #define UNIT_SIZE sizeof(unsigned long long) #define UNITS_PER_CPU (PER_CPU_ALLOC_SIZE / UNIT_SIZE) @@ -37,7 +42,7 @@ enum unit_type { FREE, END, USED }; static u8 cpu_alloc_map[UNITS_PER_CPU] = { 1, }; static DEFINE_SPINLOCK(cpu_alloc_map_lock); -static DEFINE_PER_CPU(int, cpu_area)[UNITS_PER_CPU]; +static DEFINE_PER_CPU(unsigned long long, cpu_area)[UNITS_PER_CPU]; #define CPU_DATA_OFFSET ((unsigned long)&per_cpu__cpu_area) @@ -70,15 +75,15 @@ static void set_map(int start, int lengt */ static int clear_map(int start) { - int units = 0; + int index = start; - while (cpu_alloc_map[start + units] == USED) { - cpu_alloc_map[start + units] = FREE; - units++; + while (cpu_alloc_map[index] == USED) { + cpu_alloc_map[index] = FREE; + index++; } - BUG_ON(cpu_alloc_map[start] != END); - cpu_alloc_map[start] = FREE; - return units + 1; + BUG_ON(cpu_alloc_map[index] != END); + cpu_alloc_map[index] = FREE; + return index - start + 1; } /* @@ -97,8 +102,11 @@ static void *cpu_alloc(unsigned long siz while (start < UNITS_PER_CPU && cpu_alloc_map[start] != FREE) start++; - if (start == UNITS_PER_CPU) + if (start == UNITS_PER_CPU) { + spin_unlock(&cpu_alloc_map_lock); + printk(KERN_CRIT "Dynamic per cpu memory exhausted\n"); return NULL; + } end = start + 1; while (end < UNITS_PER_CPU && end - start < units && Index: linux-2.6/include/asm-ia64/page.h =================================================================== --- linux-2.6.orig/include/asm-ia64/page.h 2007-11-01 11:45:52.747246694 -0700 +++ linux-2.6/include/asm-ia64/page.h 2007-11-01 11:47:16.769208980 -0700 @@ -44,7 +44,7 @@ #define PAGE_MASK (~(PAGE_SIZE - 1)) #define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) -#define PERCPU_PAGE_SHIFT 16 /* log2() of max. size of per-CPU area */ +#define PERCPU_PAGE_SHIFT 20 /* log2() of max. size of per-CPU area */ #define PERCPU_PAGE_SIZE (__IA64_UL_CONST(1) << PERCPU_PAGE_SHIFT) Index: linux-2.6/include/asm-generic/percpu.h =================================================================== --- linux-2.6.orig/include/asm-generic/percpu.h 2007-11-01 11:47:06.728974498 -0700 +++ linux-2.6/include/asm-generic/percpu.h 2007-11-01 11:47:16.773209076 -0700 @@ -48,6 +48,8 @@ do { \ #define __get_cpu_var(var) per_cpu__##var #define __raw_get_cpu_var(var) per_cpu__##var +#define this_cpu_offset() 0 + #endif /* SMP */ #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name @@ -55,6 +57,4 @@ do { \ #define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) #define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var) -#define this_cpu_offset() 0 - #endif /* _ASM_GENERIC_PERCPU_H_ */ Index: linux-2.6/include/linux/percpu.h =================================================================== --- linux-2.6.orig/include/linux/percpu.h 2007-11-01 11:47:06.888978234 -0700 +++ linux-2.6/include/linux/percpu.h 2007-11-01 11:47:25.037402082 -0700 @@ -75,6 +75,8 @@ static inline void percpu_free(void *__p kfree(__pdata); } +#define this_cpu_ptr(ptr) ptr + #endif /* CONFIG_SMP */ /* (legacy) interface for use without CPU hotplug handling */