perf: stop deadlock if attempt to bring cpu up fails
When an attempt is made to free an event on a CPU which is no longer online, perf tries to bring the CPU online. This can fail, resulting in an UP_CANCELLED notifier, which eventually tries to acquire the ctx->mutex which is already being held by the code, which brings up the CPU. Removing the attempt to bring the cpu up will remove this deadlock, but also requires temporarily removing support of counting events across hotplug. This will be restored in a later patch. Conflicts: kernel/events/core.c kernel/events/hw_breakpoint.c Change-Id: Iaafa3c6688d26508857472fd5bb32139a137880e Signed-off-by: Neil Leeder <nleeder@codeaurora.org>
This commit is contained in:
parent
6f56b2a9c8
commit
5f71e693df
3 changed files with 1 additions and 41 deletions
|
@ -552,7 +552,6 @@ static void armpmu_init(struct arm_pmu *armpmu)
|
|||
.stop = armpmu_stop,
|
||||
.read = armpmu_read,
|
||||
.filter_match = armpmu_filter_match,
|
||||
.events_across_hotplug = 1,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1693,33 +1693,7 @@ static int __perf_remove_from_context(void *info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static void perf_retry_remove(struct perf_event *event,
|
||||
struct remove_event *rep)
|
||||
{
|
||||
int up_ret;
|
||||
/*
|
||||
* CPU was offline. Bring it online so we can
|
||||
* gracefully exit a perf context.
|
||||
*/
|
||||
up_ret = cpu_up(event->cpu);
|
||||
if (!up_ret)
|
||||
/* Try the remove call once again. */
|
||||
cpu_function_call(event->cpu, __perf_remove_from_context,
|
||||
rep);
|
||||
else
|
||||
pr_err("Failed to bring up CPU: %d, ret: %d\n",
|
||||
event->cpu, up_ret);
|
||||
}
|
||||
#else
|
||||
static void perf_retry_remove(struct perf_event *event,
|
||||
struct remove_event *rep)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
/*
|
||||
* Remove the event from a task's (or a CPU's) list of events.
|
||||
*
|
||||
* CPU events are removed with a smp call. For task events we only
|
||||
|
@ -1754,9 +1728,6 @@ static void __ref perf_remove_from_context(struct perf_event *event,
|
|||
*/
|
||||
ret = cpu_function_call(event->cpu, __perf_remove_from_context,
|
||||
&re);
|
||||
if (ret == -ENXIO)
|
||||
perf_retry_remove(event, &re);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -7138,8 +7109,6 @@ static struct pmu perf_swevent = {
|
|||
.start = perf_swevent_start,
|
||||
.stop = perf_swevent_stop,
|
||||
.read = perf_swevent_read,
|
||||
|
||||
.events_across_hotplug = 1,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_EVENT_TRACING
|
||||
|
@ -7261,8 +7230,6 @@ static struct pmu perf_tracepoint = {
|
|||
.start = perf_swevent_start,
|
||||
.stop = perf_swevent_stop,
|
||||
.read = perf_swevent_read,
|
||||
|
||||
.events_across_hotplug = 1,
|
||||
};
|
||||
|
||||
static inline void perf_tp_register(void)
|
||||
|
@ -7550,8 +7517,6 @@ static struct pmu perf_cpu_clock = {
|
|||
.start = cpu_clock_event_start,
|
||||
.stop = cpu_clock_event_stop,
|
||||
.read = cpu_clock_event_read,
|
||||
|
||||
.events_across_hotplug = 1,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -7633,8 +7598,6 @@ static struct pmu perf_task_clock = {
|
|||
.start = task_clock_event_start,
|
||||
.stop = task_clock_event_stop,
|
||||
.read = task_clock_event_read,
|
||||
|
||||
.events_across_hotplug = 1,
|
||||
};
|
||||
|
||||
static void perf_pmu_nop_void(struct pmu *pmu)
|
||||
|
|
|
@ -614,8 +614,6 @@ static struct pmu perf_breakpoint = {
|
|||
.start = hw_breakpoint_start,
|
||||
.stop = hw_breakpoint_stop,
|
||||
.read = hw_breakpoint_pmu_read,
|
||||
|
||||
.events_across_hotplug = 1,
|
||||
};
|
||||
|
||||
int __init init_hw_breakpoint(void)
|
||||
|
|
Loading…
Add table
Reference in a new issue