lkml.org 
[lkml]   [2010]   [Dec]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [cpuops cmpxchg V1 2/4] x86: this_cpu_cmpxchg and this_cpu_xchg operations
    Alternate approach: Could also use cmpxchg for xchg..


    Subject: cpuops: Use cmpxchg for xchg to avoid lock semantics

    Cmpxchg has a lower cycle count due to the implied lock semantics of xchg.

    Simulate the xchg through cmpxchg for the cpu ops.

    Signed-off-by: Christoph Lameter <cl@linux.com>

    ---
    arch/x86/include/asm/percpu.h | 68 +++++++-----------------------------------
    1 file changed, 12 insertions(+), 56 deletions(-)

    Index: linux-2.6/arch/x86/include/asm/percpu.h
    ===================================================================
    --- linux-2.6.orig/arch/x86/include/asm/percpu.h 2010-12-08 11:43:50.000000000 -0600
    +++ linux-2.6/arch/x86/include/asm/percpu.h 2010-12-08 12:00:21.000000000 -0600
    @@ -212,48 +212,6 @@ do { \
    ret__; \
    })

    -/*
    - * Beware: xchg on x86 has an implied lock prefix. There will be the cost of
    - * full lock semantics even though they are not needed.
    - */
    -#define percpu_xchg_op(var, nval) \
    -({ \
    - typeof(var) __ret; \
    - typeof(var) __new = (nval); \
    - switch (sizeof(var)) { \
    - case 1: \
    - asm("xchgb %2, "__percpu_arg(1) \
    - : "=a" (__ret), "+m" (var) \
    - : "q" (__new) \
    - : "memory"); \
    - break; \
    - case 2: \
    - asm("xchgw %2, "__percpu_arg(1) \
    - : "=a" (__ret), "+m" (var) \
    - : "r" (__new) \
    - : "memory"); \
    - break; \
    - case 4: \
    - asm("xchgl %2, "__percpu_arg(1) \
    - : "=a" (__ret), "+m" (var) \
    - : "r" (__new) \
    - : "memory"); \
    - break; \
    - case 8: \
    - asm("xchgq %2, "__percpu_arg(1) \
    - : "=a" (__ret), "+m" (var) \
    - : "r" (__new) \
    - : "memory"); \
    - break; \
    - default: __bad_percpu_size(); \
    - } \
    - __ret; \
    -})
    -
    -/*
    - * cmpxchg has no such implied lock semantics as a result it is much
    - * more efficient for cpu local operations.
    - */
    #define percpu_cmpxchg_op(var, oval, nval) \
    ({ \
    typeof(var) __ret; \
    @@ -412,16 +370,6 @@ do { \
    #define irqsafe_cpu_xor_2(pcp, val) percpu_to_op("xor", (pcp), val)
    #define irqsafe_cpu_xor_4(pcp, val) percpu_to_op("xor", (pcp), val)

    -#define __this_cpu_xchg_1(pcp, nval) percpu_xchg_op(pcp, nval)
    -#define __this_cpu_xchg_2(pcp, nval) percpu_xchg_op(pcp, nval)
    -#define __this_cpu_xchg_4(pcp, nval) percpu_xchg_op(pcp, nval)
    -#define this_cpu_xchg_1(pcp, nval) percpu_xchg_op(pcp, nval)
    -#define this_cpu_xchg_2(pcp, nval) percpu_xchg_op(pcp, nval)
    -#define this_cpu_xchg_4(pcp, nval) percpu_xchg_op(pcp, nval)
    -#define irqsafe_cpu_xchg_1(pcp, nval) percpu_xchg_op(pcp, nval)
    -#define irqsafe_cpu_xchg_2(pcp, nval) percpu_xchg_op(pcp, nval)
    -#define irqsafe_cpu_xchg_4(pcp, nval) percpu_xchg_op(pcp, nval)
    -
    #ifndef CONFIG_M386
    #define __this_cpu_add_return_1(pcp, val) percpu_add_return_op(pcp, val)
    #define __this_cpu_add_return_2(pcp, val) percpu_add_return_op(pcp, val)
    @@ -489,16 +437,24 @@ do { \
    #define __this_cpu_add_return_8(pcp, val) percpu_add_return_op(pcp, val)
    #define this_cpu_add_return_8(pcp, val) percpu_add_return_op(pcp, val)

    -#define __this_cpu_xchg_8(pcp, nval) percpu_xchg_op(pcp, nval)
    -#define this_cpu_xchg_8(pcp, nval) percpu_xchg_op(pcp, nval)
    -#define irqsafe_cpu_xchg_8(pcp, nval) percpu_xchg_op(pcp, nval)
    -
    #define __this_cpu_cmpxchg_8(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
    #define this_cpu_cmpxchg_8(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
    #define irqsafe_cpu_cmpxchg_8(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)

    #endif

    +#define this_cpu_xchg(pcp, val) \
    +({ \
    + typeof(val) __o; \
    + do { \
    + __o = __this_cpu_read(pcp); \
    + } while (this_cpu_cmpxchg(pcp, __o, val) != __o); \
    + __o; \
    +})
    +
    +#define __this_cpu_xchg this_cpu_xchg
    +#define irqsafe_cpu_xchg this_cpu_xchg
    +
    /* This is not atomic against other CPUs -- CPU preemption needs to be off */
    #define x86_test_and_clear_bit_percpu(bit, var) \
    ({ \


    \
     
     \ /
      Last update: 2010-12-08 19:11    [W:0.026 / U:29.960 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site