aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/hw_breakpoint.c2
-rw-r--r--include/linux/perf_event.h1
-rw-r--r--kernel/events/core.c10
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);
1257extern void perf_event_enable(struct perf_event *event); 1257extern void perf_event_enable(struct perf_event *event);
1258extern void perf_event_disable(struct perf_event *event); 1258extern void perf_event_disable(struct perf_event *event);
1259extern void perf_event_disable_local(struct perf_event *event); 1259extern void perf_event_disable_local(struct perf_event *event);
1260extern void perf_event_disable_inatomic(struct perf_event *event);
1260extern void perf_event_task_tick(void); 1261extern void perf_event_task_tick(void);
1261#else /* !CONFIG_PERF_EVENTS: */ 1262#else /* !CONFIG_PERF_EVENTS: */
1262static inline void * 1263static 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}
1961EXPORT_SYMBOL_GPL(perf_event_disable); 1961EXPORT_SYMBOL_GPL(perf_event_disable);
1962 1962
1963void perf_event_disable_inatomic(struct perf_event *event)
1964{
1965 event->pending_disable = 1;
1966 irq_work_queue(&event->pending);
1967}
1968
1963static void perf_set_shadow_time(struct perf_event *event, 1969static 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);