diff options
| author | Linux Build Service Account <lnxbuild@quicinc.com> | 2017-08-03 20:51:00 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-08-03 20:50:59 -0700 |
| commit | 73c7c075c8aa2f9a0f033b79a4f33ed6aacbd3dc (patch) | |
| tree | cbe4cf020de3f707c6e5c63f9dc7974ad2cd2dc4 | |
| parent | c19a0c49cba14b987748b857e787993b43b30393 (diff) | |
| parent | 9f4e8a6c460bc3e64f4587e2942225d66e99d99b (diff) | |
Merge "Revert "perf: stop deadlock if attempt to bring cpu up fails""
| -rw-r--r-- | drivers/perf/arm_pmu.c | 1 | ||||
| -rw-r--r-- | kernel/events/core.c | 39 | ||||
| -rw-r--r-- | kernel/events/hw_breakpoint.c | 2 |
3 files changed, 41 insertions, 1 deletions
diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index 63ec68e6ac2a..39400dda27c2 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -552,6 +552,7 @@ static void armpmu_init(struct arm_pmu *armpmu) .stop = armpmu_stop, .read = armpmu_read, .filter_match = armpmu_filter_match, + .events_across_hotplug = 1, }; } diff --git a/kernel/events/core.c b/kernel/events/core.c index 7fee87daac56..6cd152e99891 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -1693,7 +1693,33 @@ 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 @@ -1728,6 +1754,9 @@ 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; } @@ -7109,6 +7138,8 @@ 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 @@ -7230,6 +7261,8 @@ 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) @@ -7517,6 +7550,8 @@ 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, }; /* @@ -7598,6 +7633,8 @@ 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) diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c index 92ce5f4ccc26..7da5b674d16e 100644 --- a/kernel/events/hw_breakpoint.c +++ b/kernel/events/hw_breakpoint.c @@ -614,6 +614,8 @@ 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) |
