linux/arch
Eric Dumazet 889a7a6a5d percpu, x86: Fix percpu_xchg_op()
These recent percpu commits:

  2485b6464c: x86,percpu: Move out of place 64 bit ops into X86_64 section
  8270137a0d: cpuops: Use cmpxchg for xchg to avoid lock semantics

Caused this 'perf top' crash:

 Kernel panic - not syncing: Fatal exception in interrupt
 Pid: 0, comm: swapper Tainted: G     D
 2.6.38-rc2-00181-gef71723 #413 Call Trace: <IRQ> [<ffffffff810465b5>]
    ? panic
    ? kmsg_dump
    ? kmsg_dump
    ? oops_end
    ? no_context
    ? __bad_area_nosemaphore
    ? perf_output_begin
    ? bad_area_nosemaphore
    ? do_page_fault
    ? __task_pid_nr_ns
    ? perf_event_tid
    ? __perf_event_header__init_id
    ? validate_chain
    ? perf_output_sample
    ? trace_hardirqs_off
    ? page_fault
    ? irq_work_run
    ? update_process_times
    ? tick_sched_timer
    ? tick_sched_timer
    ? __run_hrtimer
    ? hrtimer_interrupt
    ? account_system_vtime
    ? smp_apic_timer_interrupt
    ? apic_timer_interrupt
 ...

Looking at assembly code, I found:

list = this_cpu_xchg(irq_work_list, NULL);

gives this wrong code : (gcc-4.1.2 cross compiler)

ffffffff810bc45e:
	mov    %gs:0xead0,%rax
	cmpxchg %rax,%gs:0xead0
	jne    ffffffff810bc45e <irq_work_run+0x3e>
	test   %rax,%rax
	je     ffffffff810bc4aa <irq_work_run+0x8a>

Tell gcc we dirty eax/rax register in percpu_xchg_op()

Compiler must use another register to store pxo_new__

We also dont need to reload percpu value after a jump,
since a 'failed' cmpxchg already updated eax/rax

Wrong generated code was :
	xor     %rax,%rax   /* load 0 into %rax */
1:	mov     %gs:0xead0,%rax
	cmpxchg %rax,%gs:0xead0
	jne     1b
	test    %rax,%rax

After patch :

	xor     %rdx,%rdx   /* load 0 into %rdx */
	mov     %gs:0xead0,%rax
1:	cmpxchg %rdx,%gs:0xead0
	jne     1b:
	test    %rax,%rax

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Christoph Lameter <cl@linux-foundation.org>
Cc: Tejun Heo <tj@kernel.org>
LKML-Reference: <1295973114.3588.312.camel@edumazet-laptop>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2011-01-26 08:10:49 +01:00
..
alpha alpha: Use generic irq Kconfig 2011-01-21 11:55:31 +01:00
arm Merge branch 'omap-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6 2011-01-25 05:29:49 +10:00
avr32 kconfig: rename CONFIG_EMBEDDED to CONFIG_EXPERT 2011-01-20 17:02:05 -08:00
blackfin blackfin: Use generic irq Kconfig 2011-01-21 11:55:31 +01:00
cris cris: Use generic irq Kconfig 2011-01-21 11:55:25 +01:00
frv frv: Use generic irq Kconfig 2011-01-21 11:55:32 +01:00
h8300 h8300: Use generic irq Kconfig 2011-01-21 11:55:24 +01:00
ia64 ia64: Use generic irq Kconfig 2011-01-21 11:55:32 +01:00
m32r m32r: Convert to generic irq Kconfig 2011-01-21 11:55:30 +01:00
m68k Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu 2011-01-18 08:05:20 -08:00
m68knommu m68knommu: Use generic irq Kconfig 2011-01-21 11:55:32 +01:00
microblaze microblaze: Use generic irq Kconfig 2011-01-21 11:55:32 +01:00
mips genirq: Remove __do_IRQ 2011-01-21 11:55:31 +01:00
mn10300 mn10300: Use generic irq Kconfig 2011-01-21 11:55:33 +01:00
parisc parisc: Use generic irq Kconfig 2011-01-21 11:55:33 +01:00
powerpc Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip 2011-01-25 05:26:47 +10:00
s390 Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6 2011-01-14 08:47:26 -08:00
score score: Use generic irq Kconfig 2011-01-21 11:55:34 +01:00
sh kconfig: rename CONFIG_EMBEDDED to CONFIG_EXPERT 2011-01-20 17:02:05 -08:00
sparc sparc: Use generic irq Kconfig 2011-01-21 11:55:34 +01:00
tile tile: Use generic irq Kconfig 2011-01-21 11:55:34 +01:00
um um: Use generic irq Kconfig 2011-01-21 11:55:35 +01:00
x86 percpu, x86: Fix percpu_xchg_op() 2011-01-26 08:10:49 +01:00
xtensa kconfig: rename CONFIG_EMBEDDED to CONFIG_EXPERT 2011-01-20 17:02:05 -08:00
.gitignore
Kconfig [S390] mutex: Introduce arch_mutex_cpu_relax() 2011-01-05 12:47:31 +01:00