Skip to content

Commit 1476b21

Browse files
Leo-YanIngo Molnar
authored andcommitted
perf/aux: Fix pending disable flow when the AUX ring buffer overruns
If an AUX event overruns, the event core layer intends to disable the event by setting the 'pending_disable' flag. Unfortunately, the event is not actually disabled afterwards. In commit: ca6c213 ("perf: Fix missing SIGTRAPs") the 'pending_disable' flag was changed to a boolean. However, the AUX event code was not updated accordingly. The flag ends up holding a CPU number. If this number is zero, the flag is taken as false and the IRQ work is never triggered. Later, with commit: 2b84def ("perf: Split __perf_pending_irq() out of perf_pending_irq()") a new IRQ work 'pending_disable_irq' was introduced to handle event disabling. The AUX event path was not updated to kick off the work queue. To fix this bug, when an AUX ring buffer overrun is detected, call perf_event_disable_inatomic() to initiate the pending disable flow. Also update the outdated comment for setting the flag, to reflect the boolean values (0 or 1). Fixes: 2b84def ("perf: Split __perf_pending_irq() out of perf_pending_irq()") Fixes: ca6c213 ("perf: Fix missing SIGTRAPs") Signed-off-by: Leo Yan <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Reviewed-by: James Clark <[email protected]> Reviewed-by: Yeoreum Yun <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Arnaldo Carvalho de Melo <[email protected]> Cc: Ian Rogers <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Liang Kan <[email protected]> Cc: Marco Elver <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Sebastian Andrzej Siewior <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected]
1 parent 86731a2 commit 1476b21

File tree

2 files changed

+5
-5
lines changed

2 files changed

+5
-5
lines changed

kernel/events/core.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7251,15 +7251,15 @@ static void __perf_pending_disable(struct perf_event *event)
72517251
* CPU-A CPU-B
72527252
*
72537253
* perf_event_disable_inatomic()
7254-
* @pending_disable = CPU-A;
7254+
* @pending_disable = 1;
72557255
* irq_work_queue();
72567256
*
72577257
* sched-out
7258-
* @pending_disable = -1;
7258+
* @pending_disable = 0;
72597259
*
72607260
* sched-in
72617261
* perf_event_disable_inatomic()
7262-
* @pending_disable = CPU-B;
7262+
* @pending_disable = 1;
72637263
* irq_work_queue(); // FAILS
72647264
*
72657265
* irq_work_run()

kernel/events/ring_buffer.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ void *perf_aux_output_begin(struct perf_output_handle *handle,
441441
* store that will be enabled on successful return
442442
*/
443443
if (!handle->size) { /* A, matches D */
444-
event->pending_disable = smp_processor_id();
444+
perf_event_disable_inatomic(handle->event);
445445
perf_output_wakeup(handle);
446446
WRITE_ONCE(rb->aux_nest, 0);
447447
goto err_put;
@@ -526,7 +526,7 @@ void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size)
526526

527527
if (wakeup) {
528528
if (handle->aux_flags & PERF_AUX_FLAG_TRUNCATED)
529-
handle->event->pending_disable = smp_processor_id();
529+
perf_event_disable_inatomic(handle->event);
530530
perf_output_wakeup(handle);
531531
}
532532

0 commit comments

Comments
 (0)