Patch "perf: Always wake the parent event" has been added to the 5.16-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

    perf: Always wake the parent event

to the 5.16-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-always-wake-the-parent-event.patch
and it can be found in the queue-5.16 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 3ace183175035ad2b9dae1948227c41d003175d6
Author: James Clark <james.clark@xxxxxxx>
Date:   Mon Dec 6 11:38:40 2021 +0000

    perf: Always wake the parent event
    
    [ Upstream commit 961c39121759ad09a89598ec4ccdd34ae0468a19 ]
    
    When using per-process mode and event inheritance is set to true,
    forked processes will create a new perf events via inherit_event() ->
    perf_event_alloc(). But these events will not have ring buffers
    assigned to them. Any call to wakeup will be dropped if it's called on
    an event with no ring buffer assigned because that's the object that
    holds the wakeup list.
    
    If the child event is disabled due to a call to
    perf_aux_output_begin() or perf_aux_output_end(), the wakeup is
    dropped leaving userspace hanging forever on the poll.
    
    Normally the event is explicitly re-enabled by userspace after it
    wakes up to read the aux data, but in this case it does not get woken
    up so the event remains disabled.
    
    This can be reproduced when using Arm SPE and 'stress' which forks once
    before running the workload. By looking at the list of aux buffers read,
    it's apparent that they stop after the fork:
    
      perf record -e arm_spe// -vvv -- stress -c 1
    
    With this patch applied they continue to be printed. This behaviour
    doesn't happen when using systemwide or per-cpu mode.
    
    Reported-by: Ruben Ayrapetyan <Ruben.Ayrapetyan@xxxxxxx>
    Signed-off-by: James Clark <james.clark@xxxxxxx>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx>
    Link: https://lkml.kernel.org/r/20211206113840.130802-2-james.clark@xxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 04e6e2dae60e4..a0e21d0f36d7a 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6004,6 +6004,8 @@ static void ring_buffer_attach(struct perf_event *event,
 	struct perf_buffer *old_rb = NULL;
 	unsigned long flags;
 
+	WARN_ON_ONCE(event->parent);
+
 	if (event->rb) {
 		/*
 		 * Should be impossible, we set this when removing
@@ -6061,6 +6063,9 @@ static void ring_buffer_wakeup(struct perf_event *event)
 {
 	struct perf_buffer *rb;
 
+	if (event->parent)
+		event = event->parent;
+
 	rcu_read_lock();
 	rb = rcu_dereference(event->rb);
 	if (rb) {
@@ -6074,6 +6079,9 @@ struct perf_buffer *ring_buffer_get(struct perf_event *event)
 {
 	struct perf_buffer *rb;
 
+	if (event->parent)
+		event = event->parent;
+
 	rcu_read_lock();
 	rb = rcu_dereference(event->rb);
 	if (rb) {
@@ -6772,7 +6780,7 @@ static unsigned long perf_prepare_sample_aux(struct perf_event *event,
 	if (WARN_ON_ONCE(READ_ONCE(sampler->oncpu) != smp_processor_id()))
 		goto out;
 
-	rb = ring_buffer_get(sampler->parent ? sampler->parent : sampler);
+	rb = ring_buffer_get(sampler);
 	if (!rb)
 		goto out;
 
@@ -6838,7 +6846,7 @@ static void perf_aux_sample_output(struct perf_event *event,
 	if (WARN_ON_ONCE(!sampler || !data->aux_size))
 		return;
 
-	rb = ring_buffer_get(sampler->parent ? sampler->parent : sampler);
+	rb = ring_buffer_get(sampler);
 	if (!rb)
 		return;
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux