Second portion. Add a new seg_offset macro to calculate the offset. This can be avoided if the linker relocates the per cpu area to zero. Includes a patch to read trickle count via both methods to verify that it actually works. Both patches on top of the per cpu cleanup patches that I sent today too.
x86_64: Make the x86_32 percpu operations usable on x86_64 Calculate the offset relative to gs in order to be able to address per cpu data using the x86_64 per cpu macros. The subtraction of __per_cpu_start will make the offset based from the beginning of the per cpu area. That is where gs points to. Signed-off-by: Christoph Lameter <[EMAIL PROTECTED]> --- drivers/char/random.c | 2 +- include/asm-x86/percpu.h | 29 ++++++++++++++++++----------- init/main.c | 5 +++++ 3 files changed, 24 insertions(+), 12 deletions(-) Index: linux-2.6.24-rc3-mm2/include/asm-x86/percpu.h =================================================================== --- linux-2.6.24-rc3-mm2.orig/include/asm-x86/percpu.h 2007-11-28 17:50:01.861182410 -0800 +++ linux-2.6.24-rc3-mm2/include/asm-x86/percpu.h 2007-11-28 21:22:50.845872906 -0800 @@ -16,7 +16,13 @@ #define __my_cpu_offset read_pda(data_offset) #define per_cpu_offset(x) (__per_cpu_offset(x)) +#define __percpu_seg "%%gs:" +/* Calculate the offset to use with the segment register */ +#define seg_offset(name) (*SHIFT_PTR(&per_cpu_var(name), - (unsigned long)__per_cpu_start)) +#else +#define __percpu_seg "" +#define seg_offset(name) per_cpu_var(name) #endif #include <asm-generic/percpu.h> @@ -64,16 +70,11 @@ DECLARE_PER_CPU(struct x8664_pda, pda); * PER_CPU(cpu_gdt_descr, %ebx) */ #ifdef CONFIG_SMP - #define __my_cpu_offset x86_read_percpu(this_cpu_off) - /* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */ #define __percpu_seg "%%fs:" - #else /* !SMP */ - #define __percpu_seg "" - #endif /* SMP */ #include <asm-generic/percpu.h> @@ -81,6 +82,13 @@ DECLARE_PER_CPU(struct x8664_pda, pda); /* We can use this directly for local CPU (faster). */ DECLARE_PER_CPU(unsigned long, this_cpu_off); +#define seg_offset(name) per_cpu_var(name) + +#endif /* __ASSEMBLY__ */ +#endif /* !CONFIG_X86_64 */ + +#ifndef __ASSEMBLY__ + /* For arch-specific code, we can use direct single-insn ops (they * don't give an lvalue though). */ extern void __bad_percpu_size(void); @@ -132,11 +140,10 @@ extern void __bad_percpu_size(void); } \ ret__; }) -#define x86_read_percpu(var) percpu_from_op("mov", per_cpu__##var) -#define x86_write_percpu(var,val) percpu_to_op("mov", per_cpu__##var, val) -#define x86_add_percpu(var,val) percpu_to_op("add", per_cpu__##var, val) -#define x86_sub_percpu(var,val) percpu_to_op("sub", per_cpu__##var, val) -#define x86_or_percpu(var,val) percpu_to_op("or", per_cpu__##var, val) +#define x86_read_percpu(var) percpu_from_op("mov", seg_offset(var)) +#define x86_write_percpu(var,val) percpu_to_op("mov", seg_offset(var), val) +#define x86_add_percpu(var,val) percpu_to_op("add", seg_offset(var), val) +#define x86_sub_percpu(var,val) percpu_to_op("sub", seg_offset(var), val) +#define x86_or_percpu(var,val) percpu_to_op("or", seg_offset(var), val) #endif /* !__ASSEMBLY__ */ -#endif /* !CONFIG_X86_64 */ #endif /* _ASM_X86_PERCPU_H_ */ Index: linux-2.6.24-rc3-mm2/drivers/char/random.c =================================================================== --- linux-2.6.24-rc3-mm2.orig/drivers/char/random.c 2007-11-28 21:20:58.225804398 -0800 +++ linux-2.6.24-rc3-mm2/drivers/char/random.c 2007-11-28 21:28:38.967363573 -0800 @@ -272,7 +272,7 @@ static int random_write_wakeup_thresh = static int trickle_thresh __read_mostly = INPUT_POOL_WORDS * 28; -static DEFINE_PER_CPU(int, trickle_count) = 0; +DEFINE_PER_CPU(int, trickle_count) = 55; /* * A pool of size .poolwords is stirred with a primitive polynomial Index: linux-2.6.24-rc3-mm2/init/main.c =================================================================== --- linux-2.6.24-rc3-mm2.orig/init/main.c 2007-11-28 21:10:54.245804225 -0800 +++ linux-2.6.24-rc3-mm2/init/main.c 2007-11-28 21:22:17.769053628 -0800 @@ -504,6 +504,8 @@ void __init __attribute__((weak)) smp_se { } +DECLARE_PER_CPU(int, trickle_count); + asmlinkage void __init start_kernel(void) { char * command_line; @@ -645,6 +647,9 @@ asmlinkage void __init start_kernel(void acpi_early_init(); /* before LAPIC and SMP init */ + printk("Reading trickle cound =%lu. Is %lu\n", + x86_read_percpu(trickle_count), + __raw_get_cpu_var(trickle_count)); /* Do the rest non-__init'ed, we're now alive */ rest_init(); } - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/