forked from Minki/linux
2c0b8a7578
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> |
||
---|---|---|
.. | ||
acpi | ||
cpu | ||
.gitignore | ||
alternative.c | ||
aperture_64.c | ||
apic_32.c | ||
apic_64.c | ||
apm_32.c | ||
asm-offsets_32.c | ||
asm-offsets_64.c | ||
asm-offsets.c | ||
audit_64.c | ||
bootflag.c | ||
bugs_64.c | ||
cpuid.c | ||
crash_dump_32.c | ||
crash_dump_64.c | ||
crash.c | ||
doublefault_32.c | ||
e820_32.c | ||
e820_64.c | ||
early_printk.c | ||
early-quirks.c | ||
efi_32.c | ||
efi_stub_32.S | ||
entry_32.S | ||
entry_64.S | ||
genapic_64.c | ||
genapic_flat_64.c | ||
geode_32.c | ||
head64.c | ||
head_32.S | ||
head_64.S | ||
hpet.c | ||
i386_ksyms_32.c | ||
i387_32.c | ||
i387_64.c | ||
i8237.c | ||
i8253.c | ||
i8259_32.c | ||
i8259_64.c | ||
init_task.c | ||
io_apic_32.c | ||
io_apic_64.c | ||
io_delay.c | ||
ioport_32.c | ||
ioport_64.c | ||
irq_32.c | ||
irq_64.c | ||
k8.c | ||
kprobes_32.c | ||
kprobes_64.c | ||
ldt.c | ||
machine_kexec_32.c | ||
machine_kexec_64.c | ||
Makefile | ||
Makefile_32 | ||
Makefile_64 | ||
mca_32.c | ||
mfgpt_32.c | ||
microcode.c | ||
module_32.c | ||
module_64.c | ||
mpparse_32.c | ||
mpparse_64.c | ||
msr.c | ||
nmi_32.c | ||
nmi_64.c | ||
numaq_32.c | ||
paravirt_32.c | ||
pci-calgary_64.c | ||
pci-dma_32.c | ||
pci-dma_64.c | ||
pci-gart_64.c | ||
pci-nommu_64.c | ||
pci-swiotlb_64.c | ||
pcspeaker.c | ||
pmtimer_64.c | ||
process_32.c | ||
process_64.c | ||
ptrace_32.c | ||
ptrace_64.c | ||
quirks.c | ||
reboot_32.c | ||
reboot_64.c | ||
reboot_fixups_32.c | ||
relocate_kernel_32.S | ||
relocate_kernel_64.S | ||
rtc.c | ||
scx200_32.c | ||
setup64.c | ||
setup_32.c | ||
setup_64.c | ||
sigframe_32.h | ||
signal_32.c | ||
signal_64.c | ||
smp_32.c | ||
smp_64.c | ||
smpboot_32.c | ||
smpboot_64.c | ||
smpcommon_32.c | ||
srat_32.c | ||
stacktrace.c | ||
summit_32.c | ||
suspend_64.c | ||
suspend_asm_64.S | ||
sys_i386_32.c | ||
sys_x86_64.c | ||
syscall_64.c | ||
syscall_table_32.S | ||
tce_64.c | ||
time_32.c | ||
time_64.c | ||
tls.c | ||
topology.c | ||
trampoline_32.S | ||
trampoline_64.S | ||
traps_32.c | ||
traps_64.c | ||
tsc_32.c | ||
tsc_64.c | ||
tsc_sync.c | ||
verify_cpu_64.S | ||
vm86_32.c | ||
vmi_32.c | ||
vmiclock_32.c | ||
vmlinux_32.lds.S | ||
vmlinux_64.lds.S | ||
vmlinux.lds.S | ||
vsmp_64.c | ||
vsyscall_64.c | ||
x8664_ksyms_64.c |