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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.