Skip to content

Commit 32132a3

Browse files
Peter ZijlstraIngo Molnar
authored andcommitted
perf: Specialize perf_event_exit_task()
The perf_remove_from_context() usage in __perf_event_exit_task() is different from the other usages in that this site has already detached and scheduled out the task context. This will stand in the way of stronger assertions checking the (task) context scheduling invariants. Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Cc: Arnaldo Carvalho de Melo <[email protected]> Cc: David Ahern <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Stephane Eranian <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Vince Weaver <[email protected]> Signed-off-by: Ingo Molnar <[email protected]>
1 parent 39a4364 commit 32132a3

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

kernel/events/core.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8726,7 +8726,13 @@ __perf_event_exit_task(struct perf_event *child_event,
87268726
* Do destroy all inherited groups, we don't care about those
87278727
* and being thorough is better.
87288728
*/
8729-
perf_remove_from_context(child_event, !!child_event->parent);
8729+
raw_spin_lock_irq(&child_ctx->lock);
8730+
WARN_ON_ONCE(child_ctx->is_active);
8731+
8732+
if (!!child_event->parent)
8733+
perf_group_detach(child_event);
8734+
list_del_event(child_event, child_ctx);
8735+
raw_spin_unlock_irq(&child_ctx->lock);
87308736

87318737
/*
87328738
* It can happen that the parent exits first, and has events
@@ -8746,17 +8752,15 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn)
87468752
{
87478753
struct perf_event *child_event, *next;
87488754
struct perf_event_context *child_ctx, *clone_ctx = NULL;
8749-
unsigned long flags;
87508755

87518756
if (likely(!child->perf_event_ctxp[ctxn]))
87528757
return;
87538758

8754-
local_irq_save(flags);
8759+
local_irq_disable();
8760+
WARN_ON_ONCE(child != current);
87558761
/*
87568762
* We can't reschedule here because interrupts are disabled,
8757-
* and either child is current or it is a task that can't be
8758-
* scheduled, so we are now safe from rescheduling changing
8759-
* our context.
8763+
* and child must be current.
87608764
*/
87618765
child_ctx = rcu_dereference_raw(child->perf_event_ctxp[ctxn]);
87628766

@@ -8776,7 +8780,7 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn)
87768780
*/
87778781
clone_ctx = unclone_ctx(child_ctx);
87788782
update_context_time(child_ctx);
8779-
raw_spin_unlock_irqrestore(&child_ctx->lock, flags);
8783+
raw_spin_unlock_irq(&child_ctx->lock);
87808784

87818785
if (clone_ctx)
87828786
put_ctx(clone_ctx);

0 commit comments

Comments
 (0)