Skip to contentSkip to conversation

Patch "perf: Cure event->pending_disable race" has been added to the 4.4-stable tree

PATCH [email protected] 1 participant 1 message Apr 17, 2016

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

    perf: Cure event->pending_disable race

to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
perf-cure-event-pending_disable-race.patch
and it can be found in the queue-4.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From 28a967c3a2f99fa3b5f762f25cb2a319d933571b Mon Sep 17 00:00:00 2001

From: Peter Zijlstra <[email protected]>
Date: Wed, 24 Feb 2016 18:45:46 +0100
Subject: perf: Cure event->pending_disable race

From: Peter Zijlstra <[email protected]>

commit 28a967c3a2f99fa3b5f762f25cb2a319d933571b upstream.

Because event_sched_out() checks event->pending_disable _before_ actually disabling the event, it can happen that the event fires after it checks but before it gets disabled.

This would leave event->pending_disable set and the queued irq_work will try and process it.

However, if the event trigger was during schedule(), the event might have been de-scheduled by the time the irq_work runs, and perf_event_disable_local() will fail.

Fix this by checking event->pending_disable _after_ we call event->pmu->del(). This depends on the latter being a compiler barrier, such that the compiler does not lift the load and re-creates the problem.

---
 kernel/events/core.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/events/core.c +3 -3
@@ -1580,14 +1580,14 @@ event_sched_out(struct perf_event *event
 
 	perf_pmu_disable(event->pmu);
 
+	event->tstamp_stopped = tstamp;
+	event->pmu->del(event, 0);
+	event->oncpu = -1;
 	event->state = PERF_EVENT_STATE_INACTIVE;
 	if (event->pending_disable) {
 		event->pending_disable = 0;
 		event->state = PERF_EVENT_STATE_OFF;
 	}
-	event->tstamp_stopped = tstamp;
-	event->pmu->del(event, 0);
-	event->oncpu = -1;
 
 	if (!is_software_event(event))
 		cpuctx->active_oncpu--;

Patches currently in stable-queue which might be from [email protected] are

queue-4.4/perf-cure-event-pending_disable-race.patch queue-4.4/perf-do-not-double-free.patch