Disable the PMU globally before removing a counter from a
context. This fixes the following lockup:
[22081.741922] ------------[ cut here ]------------
[22081.746668] WARNING: at arch/x86/kernel/cpu/perf_counter.c:803 intel_pmu_handle_irq+0x9b/0x24e()
[22081.755624] Hardware name: X8DTN
[22081.758903] perfcounters: irq loop stuck!
[22081.762985] Modules linked in:
[22081.766136] Pid: 11082, comm: perf Not tainted 2.6.30-rc6-tip #226
[22081.772432] Call Trace:
[22081.774940] <NMI> [<
ffffffff81019aed>] ? intel_pmu_handle_irq+0x9b/0x24e
[22081.781993] [<
ffffffff81019aed>] ? intel_pmu_handle_irq+0x9b/0x24e
[22081.788368] [<
ffffffff8104505c>] ? warn_slowpath_common+0x77/0xa3
[22081.794649] [<
ffffffff810450d3>] ? warn_slowpath_fmt+0x40/0x45
[22081.800696] [<
ffffffff81019aed>] ? intel_pmu_handle_irq+0x9b/0x24e
[22081.807080] [<
ffffffff814d1a72>] ? perf_counter_nmi_handler+0x3f/0x4a
[22081.813751] [<
ffffffff814d2d09>] ? notifier_call_chain+0x58/0x86
[22081.819951] [<
ffffffff8105b250>] ? notify_die+0x2d/0x32
[22081.825392] [<
ffffffff814d1414>] ? do_nmi+0x8e/0x242
[22081.830538] [<
ffffffff814d0f0a>] ? nmi+0x1a/0x20
[22081.835342] [<
ffffffff8117e102>] ? selinux_file_free_security+0x0/0x1a
[22081.842105] [<
ffffffff81018793>] ? x86_pmu_disable_counter+0x15/0x41
[22081.848673] <<EOE>> [<
ffffffff81018f3d>] ? x86_pmu_disable+0x86/0x103
[22081.855512] [<
ffffffff8108fedd>] ? __perf_counter_remove_from_context+0x0/0xfe
[22081.862926] [<
ffffffff8108fcbc>] ? counter_sched_out+0x30/0xce
[22081.868909] [<
ffffffff8108ff36>] ? __perf_counter_remove_from_context+0x59/0xfe
[22081.876382] [<
ffffffff8106808a>] ? smp_call_function_single+0x6c/0xe6
[22081.882955] [<
ffffffff81091b96>] ? perf_release+0x86/0x14c
[22081.888600] [<
ffffffff810c4c84>] ? __fput+0xe7/0x195
[22081.893718] [<
ffffffff810c213e>] ? filp_close+0x5b/0x62
[22081.899107] [<
ffffffff81046a70>] ? put_files_struct+0x64/0xc2
[22081.905031] [<
ffffffff8104841a>] ? do_exit+0x1e2/0x6ef
[22081.910360] [<
ffffffff814d0a60>] ? _spin_lock_irqsave+0x9/0xe
[22081.916292] [<
ffffffff8104898e>] ? do_group_exit+0x67/0x93
[22081.921953] [<
ffffffff810489cc>] ? sys_exit_group+0x12/0x16
[22081.927759] [<
ffffffff8100baab>] ? system_call_fastpath+0x16/0x1b
[22081.934076] ---[ end trace
3a3936ce3e1b4505 ]---
And could potentially also fix the lockup reported by Marcelo Tosatti.
Also, print more debug info in case of a detected lockup.
[ Impact: fix lockup ]
Reported-by: Marcelo Tosatti <mtosatti@redhat.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
again:
if (++loops > 100) {
WARN_ONCE(1, "perfcounters: irq loop stuck!\n");
+ perf_counter_print_debug();
return 1;
}
return;
spin_lock_irqsave(&ctx->lock, flags);
+ /*
+ * Protect the list operation against NMI by disabling the
+ * counters on a global level.
+ */
+ perf_disable();
counter_sched_out(counter, cpuctx, ctx);
counter->task = NULL;
- /*
- * Protect the list operation against NMI by disabling the
- * counters on a global level. NOP for non NMI based counters.
- */
- perf_disable();
list_del_counter(counter, ctx);
- perf_enable();
if (!ctx->task) {
/*
perf_max_counters - perf_reserved_percpu);
}
+ perf_enable();
spin_unlock_irqrestore(&ctx->lock, flags);
}