Linux Perf Users
 help / color / mirror / Atom feed
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

  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