• Mathieu Desnoyers's avatar
    x86: fall back on interrupt disable in cmpxchg8b on 80386 and 80486 · 2c0b8a75
    Mathieu Desnoyers authored
    Actually, on 386, cmpxchg and cmpxchg_local fall back on
    cmpxchg_386_u8/16/32: it disables interruptions around non atomic
    updates to mimic the cmpxchg behavior.
    
    The comment:
    /* Poor man's cmpxchg for 386. Unsuitable for SMP */
    
    already present in cmpxchg_386_u32 tells much about how this cmpxchg
    implementation should not be used in a SMP context. However, the cmpxchg_local
    can perfectly use this fallback, since it only needs to be atomic wrt the local
    cpu.
    
    This patch adds a cmpxchg_486_u64 and uses it as a fallback for cmpxchg64
    and cmpxchg64_local on 80386 and 80486.
    
    Q:
    but why is it called cmpxchg_486 when the other functions are called
    
    A:
    Because the standard cmpxchg is missing only on 386, but cmpxchg8b is
    missing both on 386 and 486.
    
    Citing Intel's Instruction set reference:
    
    cmpxchg:
    This instruction is not supported on Intel processors earlier than the
    Intel486 processors.
    
    cmpxchg8b:
    This instruction encoding is not supported on Intel processors earlier
    than the Pentium processors.
    
    Q:
    What's the reason to have cmpxchg64_local on 32 bit architectures?
    Without that need all this would just be a few simple defines.
    
    A:
    cmpxchg64_local on 32 bits architectures takes unsigned long long
    parameters, but cmpxchg_local only takes longs. Since we have cmpxchg8b
    to execute a 8 byte cmpxchg atomically on pentium and +, it makes sense
    to provide a flavor of cmpxchg and cmpxchg_local using this instruction.
    
    Also, for 32 bits architectures lacking the 64 bits atomic cmpxchg, it
    makes sense _not_ to define cmpxchg64 while cmpxchg could still be
    available.
    
    Moreover, the fallback for cmpxchg8b on i386 for 386 and 486 is a
    
    However, cmpxchg64_local will be emulated by disabling interrupts on all
    architectures where it is not supported atomically.
    
    Therefore, we *could* turn cmpxchg64_local into a cmpxchg_local, but it
    would make the 386/486 fallbacks ugly, make its design different from
    cmpxchg/cmpxchg64 (which really depends on atomic operations and cannot
    be emulated) and require the __cmpxchg_local to be expressed as a macro
    rather than an inline function so the parameters would not be fixed to
    unsigned long long in every case.
    
    So I think cmpxchg64_local makes sense there, but I am open to
    suggestions.
    
    Q:
    Are there any callers?
    
    A:
    I am actually using it in LTTng in my timestamping code. I use it to
    work around CPUs with asynchronous TSCs. I need to update 64 bits
    values atomically on this 32 bits architecture.
    
    Changelog:
    - Ran though checkpatch.
    Signed-off-by: default avatarMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
    Cc: Andi Kleen <ak@suse.de>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    2c0b8a75
cmpxchg_32.h 8.92 KB