perf, x86: Avoid kfree() in CPU_STARTING
Subsystems (2)
Commit-ID: 7fdba1ca10462f42ad2246b918fe6368f5ce488e Gitweb: http://git.kernel.org/tip/7fdba1ca10462f42ad2246b918fe6368f5ce488e Author: Peter Zijlstra <[email protected]> AuthorDate: Fri, 22 Jul 2011 13:41:54 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Sun, 14 Aug 2011 11:53:02 +0200
perf, x86: Avoid kfree() in CPU_STARTING
On -rt kfree() can schedule, but CPU_STARTING is before the CPU is fully up and running. These are contradictory, so avoid it. Instead push the kfree() to CPU_ONLINE where we're free to schedule.
Reported-by Thomas Gleixner <[email protected]>
Signed-off-by Peter Zijlstra <[email protected]>
Signed-off-by Ingo Molnar <[email protected]>
--- arch/x86/kernel/cpu/perf_event.c | 8 ++++++++ arch/x86/kernel/cpu/perf_event_amd.c | 2 +- arch/x86/kernel/cpu/perf_event_intel.c | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-)
arch/x86/kernel/cpu/perf_event.c +8 -0
@@ -129,6 +129,8 @@ struct cpu_hw_events {* AMD specific bits */ struct amd_nb *amd_nb; + +void *kfree_on_online; };#define __EVENT_CONSTRAINT (c, n, m, w) {\
@@ -1466,10 +1468,12 @@ static int __cpuinit x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) { unsigned int cpu = (long)hcpu; +struct cpu_hw_events *cpuc = &per_cpu (cpu_hw_events, cpu);int ret =NOTIFY_OK ;switch (action & ~CPU_TASKS_FROZEN ) {case CPU_UP_PREPARE : + cpuc->kfree_on_online =NULL ;if (x86_pmu.cpu_prepare) ret = x86_pmu.cpu_prepare (cpu);break ;
@@ -1479,6 +1483,10 @@ x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) x86_pmu.cpu_starting (cpu);break ; +case CPU_ONLINE : +kfree (cpuc->kfree_on_online); +break ; +case CPU_DYING :if (x86_pmu.cpu_dying) x86_pmu.cpu_dying (cpu);
arch/x86/kernel/cpu/perf_event_amd.c +1 -1
@@ -350,7 +350,7 @@ static void amd_pmu_cpu_starting(int cpu)continue ;if (nb->nb_id == nb_id) { -kfree (cpuc->amd_nb); + cpuc->kfree_on_online = cpuc->amd_nb; cpuc->amd_nb = nb;break ; }
arch/x86/kernel/cpu/perf_event_intel.c +1 -1
@@ -1362,7 +1362,7 @@ static void intel_pmu_cpu_starting(int cpu) pc =per_cpu (cpu_hw_events, i).shared_regs;if (pc && pc->core_id == core_id) { -kfree (cpuc->shared_regs); + cpuc->kfree_on_online = cpuc->shared_regs; cpuc->shared_regs = pc;break ; }