android_kernel_motorola_sm6225/arch/x86/kernel/cpu
Mathieu Desnoyers 2c0b8a7578 x86: fall back on interrupt disable in cmpxchg8b on 80386 and 80486
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: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2008-01-30 13:30:47 +01:00
..
cpufreq Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/cpufreq 2007-11-16 18:30:26 -08:00
mcheck x86: extended interrupt LVT support for AMD Barcelona 2008-01-30 13:30:40 +01:00
mtrr x86: use CR0 defines. 2008-01-30 13:30:39 +01:00
addon_cpuid_features.c i386: move kernel/cpu 2007-10-11 11:16:58 +02:00
amd.c spelling fixes: arch/i386/ 2007-10-20 01:13:56 +02:00
bugs.c x86: use CR0 defines. 2008-01-30 13:30:39 +01:00
centaur.c spelling fixes: arch/i386/ 2007-10-20 01:13:56 +02:00
common.c spelling fixes: arch/i386/ 2007-10-20 01:13:56 +02:00
cpu.h i386: move kernel/cpu 2007-10-11 11:16:58 +02:00
cyrix.c x86: use CR0 defines. 2008-01-30 13:30:39 +01:00
intel.c x86: fall back on interrupt disable in cmpxchg8b on 80386 and 80486 2008-01-30 13:30:47 +01:00
intel_cacheinfo.c Kobject: convert arch/* from kobject_unregister() to kobject_put() 2008-01-24 20:40:39 -08:00
Makefile x86: prepare consolidation of cpu/ related Makefiles 2007-10-23 22:37:23 +02:00
nexgen.c i386: move kernel/cpu 2007-10-11 11:16:58 +02:00
perfctr-watchdog.c x86: nuke a ton of unused exports 2008-01-30 13:30:28 +01:00
proc.c x86: show cpuinfo only for online CPUs 2007-11-17 16:27:00 +01:00
transmeta.c i386: move kernel/cpu 2007-10-11 11:16:58 +02:00
umc.c i386: move kernel/cpu 2007-10-11 11:16:58 +02:00