diff options
| -rw-r--r-- | arch/powerpc/kernel/hw_breakpoint.c | 2 | ||||
| -rw-r--r-- | include/linux/perf_event.h | 1 | ||||
| -rw-r--r-- | kernel/events/core.c | 10 |
3 files changed, 10 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c index 9781c69eae57..03d089b3ed72 100644 --- a/arch/powerpc/kernel/hw_breakpoint.c +++ b/arch/powerpc/kernel/hw_breakpoint.c | |||
| @@ -275,7 +275,7 @@ int hw_breakpoint_handler(struct die_args *args) | |||
| 275 | if (!stepped) { | 275 | if (!stepped) { |
| 276 | WARN(1, "Unable to handle hardware breakpoint. Breakpoint at " | 276 | WARN(1, "Unable to handle hardware breakpoint. Breakpoint at " |
| 277 | "0x%lx will be disabled.", info->address); | 277 | "0x%lx will be disabled.", info->address); |
| 278 | perf_event_disable(bp); | 278 | perf_event_disable_inatomic(bp); |
| 279 | goto out; | 279 | goto out; |
| 280 | } | 280 | } |
| 281 | /* | 281 | /* |
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 060d0ede88df..4741ecdb9817 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
| @@ -1257,6 +1257,7 @@ extern u64 perf_swevent_set_period(struct perf_event *event); | |||
| 1257 | extern void perf_event_enable(struct perf_event *event); | 1257 | extern void perf_event_enable(struct perf_event *event); |
| 1258 | extern void perf_event_disable(struct perf_event *event); | 1258 | extern void perf_event_disable(struct perf_event *event); |
| 1259 | extern void perf_event_disable_local(struct perf_event *event); | 1259 | extern void perf_event_disable_local(struct perf_event *event); |
| 1260 | extern void perf_event_disable_inatomic(struct perf_event *event); | ||
| 1260 | extern void perf_event_task_tick(void); | 1261 | extern void perf_event_task_tick(void); |
| 1261 | #else /* !CONFIG_PERF_EVENTS: */ | 1262 | #else /* !CONFIG_PERF_EVENTS: */ |
| 1262 | static inline void * | 1263 | static inline void * |
diff --git a/kernel/events/core.c b/kernel/events/core.c index a5d2e62faf7e..0e292132efac 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
| @@ -1960,6 +1960,12 @@ void perf_event_disable(struct perf_event *event) | |||
| 1960 | } | 1960 | } |
| 1961 | EXPORT_SYMBOL_GPL(perf_event_disable); | 1961 | EXPORT_SYMBOL_GPL(perf_event_disable); |
| 1962 | 1962 | ||
| 1963 | void perf_event_disable_inatomic(struct perf_event *event) | ||
| 1964 | { | ||
| 1965 | event->pending_disable = 1; | ||
| 1966 | irq_work_queue(&event->pending); | ||
| 1967 | } | ||
| 1968 | |||
| 1963 | static void perf_set_shadow_time(struct perf_event *event, | 1969 | static void perf_set_shadow_time(struct perf_event *event, |
| 1964 | struct perf_event_context *ctx, | 1970 | struct perf_event_context *ctx, |
| 1965 | u64 tstamp) | 1971 | u64 tstamp) |
| @@ -7075,8 +7081,8 @@ static int __perf_event_overflow(struct perf_event *event, | |||
| 7075 | if (events && atomic_dec_and_test(&event->event_limit)) { | 7081 | if (events && atomic_dec_and_test(&event->event_limit)) { |
| 7076 | ret = 1; | 7082 | ret = 1; |
| 7077 | event->pending_kill = POLL_HUP; | 7083 | event->pending_kill = POLL_HUP; |
| 7078 | event->pending_disable = 1; | 7084 | |
| 7079 | irq_work_queue(&event->pending); | 7085 | perf_event_disable_inatomic(event); |
| 7080 | } | 7086 | } |
| 7081 | 7087 | ||
| 7082 | READ_ONCE(event->overflow_handler)(event, data, regs); | 7088 | READ_ONCE(event->overflow_handler)(event, data, regs); |
