lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Mon,  6 Dec 2021 11:38:40 +0000
From:   James Clark <james.clark@....com>
To:     peterz@...radead.org, mingo@...hat.com, acme@...nel.org,
        mark.rutland@....com, alexander.shishkin@...ux.intel.com,
        jolsa@...hat.com, namhyung@...nel.org
Cc:     linux-perf-users@...r.kernel.org, leo.yan@...aro.com,
        Suzuki.Poulose@....com, James Clark <james.clark@....com>,
        Ruben Ayrapetyan <Ruben.Ayrapetyan@....com>,
        linux-kernel@...r.kernel.org
Subject: [RFC PATCH 1/1] perf/core: Wake up parent event if inherited event has no ring buffer

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@....com>
Signed-off-by: James Clark <james.clark@....com>
---
 kernel/events/core.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 30d94f68c5bd..76217a3f9cdd 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -5993,6 +5993,9 @@ static void ring_buffer_wakeup(struct perf_event *event)
 
 	rcu_read_lock();
 	rb = rcu_dereference(event->rb);
+	if (!rb && event->parent)
+		rb = rcu_dereference(event->parent->rb);
+
 	if (rb) {
 		list_for_each_entry_rcu(event, &rb->event_list, rb_entry)
 			wake_up_all(&event->waitq);
-- 
2.28.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ