From: sashiko-bot@kernel.org
To: "Ian Rogers" <irogers@google.com>
Cc: linux-perf-users@vger.kernel.org
Subject: Re: [PATCH v6] perf record: Fix unhandled POLLHUP on non_perf_event descriptors
Date: Thu, 20 Aug 2026 17:00:21 +0000 [thread overview]
Message-ID: <20260820170022.151081F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260820164937.2734066-1-irogers@google.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] The synchronization logic added to `record__update_evlist_pollfd_from_thread` is flawed and fails to prevent the `-EINVAL` index mismatch abort on `POLLHUP`.
- [Medium] The newly added unit test `test__fdarray__filter` fails unconditionally, breaking the perf test suite.
--
--- Patch [1]: [PATCH v6] perf record: Fix unhandled POLLHUP on non_perf_event descriptors ---
commit a78a902826b55b27b98ff151dcb9dd5753ba4611
Author: Ian Rogers <irogers@google.com>
perf record: Fix unhandled POLLHUP on non_perf_event descriptors
This patch attempts to fix a premature teardown during recording sessions by
propagating the finalized teardown status (-1) from the core evlist back to
the thread's local pollfd array when a POLLHUP is received. It also adds a
unit test to verify that fdarray__filter() properly preserves items marked
as nonfilterable.
> diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
> index e915390556752..719869efdde59 100644
> --- a/tools/perf/builtin-record.c
> +++ b/tools/perf/builtin-record.c
> @@ -1180,6 +1180,16 @@ static int record__update_evlist_pollfd_from_thread(struct record *rec,
> int e_pos = rec->index_map[i].evlist_pollfd_index;
> int t_pos = rec->index_map[i].thread_pollfd_index;
>
> + if (e_entries[e_pos].fd == -1 || e_entries[e_pos].events == 0) {
> + /*
> + * e_entries might have been finalized by evlist__finalize_ctlfd().
> + * We must propagate it to t_entries to avoid index mismatches
> + * and to prevent a poll storm on the next iteration.
> + */
> + t_entries[t_pos].fd = -1;
> + t_entries[t_pos].events = 0;
> + }
[Severity: High]
Does this synchronization logic happen in the correct order to prevent the
-EINVAL index mismatch?
Looking at the main loop in __cmd_record(), fdarray__filter() mutates the
thread's local pollfd array (zeroing events) before
record__update_evlist_pollfd_from_thread() is called:
tools/perf/builtin-record.c:__cmd_record() {
...
if (fdarray__filter(&thread->pollfd, POLLERR | POLLHUP, ...) == 0)
draining = true;
err = record__update_evlist_pollfd_from_thread(rec, rec->evlist, thread);
if (err)
goto out_child;
}
if (evlist__ctlfd_process(rec->evlist, &cmd) > 0) {
...
}
Because evlist__ctlfd_process() hasn't finalized the core evlist's array
yet, e_entries[e_pos].events will still be POLLIN, bypassing this new check.
Since the thread's events field was just zeroed by fdarray__filter(),
the strict equivalence check below (POLLIN != 0) will still fail and abort
the session with -EINVAL.
> +
> if (e_entries[e_pos].fd != t_entries[t_pos].fd ||
> e_entries[e_pos].events != t_entries[t_pos].events) {
> pr_err("Thread and evlist pollfd index mismatch\n");
[ ... ]
> diff --git a/tools/perf/tests/fdarray.c b/tools/perf/tests/fdarray.c
> index 40983c3574b12..2d3db7b754a17 100644
> --- a/tools/perf/tests/fdarray.c
> +++ b/tools/perf/tests/fdarray.c
> @@ -80,6 +80,30 @@ static int test__fdarray__filter(struct test_suite *test __maybe_unused, int sub
[ ... ]
> + if (fda->entries[2].fd == -1) {
> + pr_debug("\nfdarray__filter() illegally modified nonfilterable fd!");
> + goto out_delete;
> + }
> + if (fda->entries[2].revents != POLLHUP) {
> + pr_debug("\nfdarray__filter() illegally modified nonfilterable revents!");
> + goto out_delete;
> + }
[Severity: Medium]
Will this test fail unconditionally?
Looking at fdarray__filter() in tools/lib/api/fd/array.c, it appears to
unconditionally clear the events and revents fields for any entry matching
the filter mask before the nonfilterable flag is ever evaluated:
tools/lib/api/fd/array.c:fdarray__filter() {
...
if (fda->entries[fd].revents & revents) {
if (entry_destructor)
entry_destructor(fda, fd, arg);
fda->entries[fd].revents = fda->entries[fd].events = 0;
continue;
}
...
}
Because revents is unconditionally zeroed, won't this check always evaluate
to true and cause the perf test suite to fail?
> +
> + fda->priv[2].flags = 0; /* reset flags */
> +
> pr_debug("\n");
>
> err = 0;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260820164937.2734066-1-irogers@google.com?part=1
next prev parent reply other threads:[~2026-08-20 17:00 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-10 5:39 [PATCH v1 1/2] perf record: Fix teardown hang on system-wide multi-threaded sessions Ian Rogers
2026-07-10 5:39 ` [PATCH v1 2/2] perf cap: If capability is missing still perform root test Ian Rogers
2026-07-10 5:47 ` sashiko-bot
2026-07-10 22:24 ` Namhyung Kim
2026-07-16 7:40 ` [PATCH v2] perf cap: Remove used_root parameter and simplify capability checks Ian Rogers
2026-07-23 5:06 ` [PATCH v3] " Ian Rogers
2026-07-24 5:47 ` Namhyung Kim
2026-07-10 5:56 ` [PATCH v1 1/2] perf record: Fix teardown hang on system-wide multi-threaded sessions sashiko-bot
2026-07-10 22:02 ` Namhyung Kim
2026-07-12 6:56 ` (subset) " Namhyung Kim
2026-07-16 7:37 ` [PATCH v2] perf record: Fix destructor invocation and event counting in fdarray__filter Ian Rogers
2026-07-16 8:00 ` sashiko-bot
2026-07-23 5:04 ` [PATCH v3] " Ian Rogers
2026-07-23 5:27 ` sashiko-bot
2026-08-17 23:04 ` [PATCH v4] perf fdarray: " Ian Rogers
2026-08-17 23:17 ` Namhyung Kim
2026-08-17 23:30 ` Ian Rogers
2026-08-17 23:28 ` sashiko-bot
2026-08-18 0:31 ` [PATCH v5] perf record: Fix unhandled POLLHUP on non_perf_event descriptors Ian Rogers
2026-08-18 0:43 ` sashiko-bot
2026-08-20 16:49 ` [PATCH v6] " Ian Rogers
2026-08-20 17:00 ` sashiko-bot [this message]
2026-08-20 20:02 ` [PATCH v7] " Ian Rogers
2026-08-20 20:17 ` sashiko-bot
2026-08-20 21:37 ` [PATCH v8] " Ian Rogers
2026-08-20 21:47 ` sashiko-bot
2026-08-20 22:00 ` Ian Rogers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260820170022.151081F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=irogers@google.com \
--cc=linux-perf-users@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox