From: sashiko-bot@kernel.org
To: "Ian Rogers" <irogers@google.com>
Cc: linux-perf-users@vger.kernel.org
Subject: Re: [PATCH v2 2/6] perf bpf-filter: Add lock_held() sample filter
Date: Sat, 17 Oct 2026 17:35:08 +0000 [thread overview]
Message-ID: <sashiko-outbox-175711@kernel.org> (raw)
In-Reply-To: <20261017171437.2066343-3-irogers@google.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] perf bpf-filter: rwlock read_count leak in record_lock_acquired_owner()
- [Medium] perf bpf-filter: missing error return on node_data lookup in init_numa_data()
--
commit 782c7a3aaec8d457ca5bf045258b33f6bbfbcae8
Author: Ian Rogers <irogers@google.com>
perf bpf-filter: Add lock_held() sample filter
This commit adds BPF sample filter predicates lock_held(<lock>),
lock_held_read(<lock>) / lock_held_shared(<lock>), and
lock_held_write(<lock>) / lock_held_exclusive(<lock>) to record perf event
samples only when a specified kernel lock is held. It evaluates lock
ownership directly in kernel memory where possible and falls back to a
held_locks BPF hash map populated by fentry/fexit hooks on kernel
lock/unlock functions.
> diff --git a/tools/perf/util/bpf-filter.c b/tools/perf/util/bpf-filter.c
> index 72e83ac1d6a4b..2f4c6bd85f89f 100644
> --- a/tools/perf/util/bpf-filter.c
> +++ b/tools/perf/util/bpf-filter.c
[ ... ]
> @@ -155,9 +171,814 @@ static int check_sample_flags(struct evsel *evsel, struct perf_bpf_filter_expr *
[ ... ]
> +static void init_numa_data(struct sample_filter_bpf *skel, struct btf *btf)
> +{
> + u64 addr = 0;
> + char *buf = NULL, *p;
> + size_t len;
> + long last = -1;
> + int ret;
> +
> + if (!btf)
> + return;
> +
> + ret = btf__find_by_name_kind(btf, "zone", BTF_KIND_STRUCT);
> + if (ret < 0)
> + return;
> +
> + ret = btf__resolve_size(btf, ret);
> + if (ret < 0)
> + return;
> +
> + skel->rodata->sizeof_zone = ret;
> +
> + if (find_kernel_lock_sym("contig_page_data", &addr) == 0) {
> + skel->rodata->contig_page_data_addr = addr;
> + return;
> + }
> +
> + if (find_kernel_lock_sym("node_data", &addr) == 0)
> + skel->rodata->node_data_addr = addr;
> +
> + if (sysfs__read_str("devices/system/node/online", &buf, &len) >= 0) {
> + p = buf;
> + while (p && *p) {
> + char *end;
> +
> + last = strtol(p, &end, 0);
> + if (end == p)
> + break;
> + p = end;
> + if (*p == ',' || *p == '-' || *p == '\n')
> + p++;
> + }
> + skel->rodata->nr_nodes = last + 1;
> + free(buf);
> + }
> +}
[Severity: Medium]
What happens in init_numa_data() when find_kernel_lock_sym("node_data",
&addr) fails (for example, when /proc/kallsyms zeroes symbol addresses
under kptr_restrict for a non-root user with CAP_BPF)?
Unlike init_numa_data() in tools/perf/util/bpf_lock_contention.c, this does
not return early on failure, so skel->rodata->node_data_addr remains 0
while skel->rodata->nr_nodes is populated from devices/system/node/online.
When collect_lock_syms later calls do_collect_lock_syms() ->
do_collect_zone_lock() in tools/perf/util/bpf_skel/lock_data.h:
} else if (nr_nodes > 0) {
struct pglist_data **node_data = (void *)(long)node_data_addr;
for (int i = 0; i < nr_nodes; i++) {
struct pglist_data *pgdat = NULL;
int err;
err = bpf_core_read(&pgdat, sizeof(pgdat), &node_data[i]);
will this attempt to read from kernel address 0x0 and leave lock_syms
unpopulated without reporting an error for lock_held(zone_lock)?
[ ... ]
> diff --git a/tools/perf/util/bpf_skel/sample_filter.bpf.c b/tools/perf/util/bpf_skel/sample_filter.bpf.c
> index e5666d4c17228..480ba4b49793d 100644
> --- a/tools/perf/util/bpf_skel/sample_filter.bpf.c
> +++ b/tools/perf/util/bpf_skel/sample_filter.bpf.c
[ ... ]
> @@ -295,4 +525,739 @@ int perf_sample_filter(void *ctx)
[ ... ]
> +static __always_inline int record_lock_acquired_owner(__u64 lock_addr, __u32 flags, __u32 owner_id)
> +{
[ ... ]
> + existing = bpf_map_lookup_elem(&held_locks, &addr_key);
> + if (existing) {
> + /* Non-reader locks are not recursive; avoid double-counting */
> + if (!is_read && existing->write_count > 0)
> + return 0;
> + if (is_read)
> + __sync_fetch_and_add(&existing->read_count, 1);
> + else
> + __sync_fetch_and_add(&existing->write_count, 1);
> + } else {
> + struct held_lock_val first = {
> + .read_count = is_read ? 1 : 0,
> + .write_count = is_read ? 0 : 1,
> + .flags = flags,
> + };
> +
> + if (bpf_map_update_elem(&held_locks, &addr_key, &first, BPF_ANY) < 0)
> + return 0;
> + }
> +
> + if (class_id)
> + update_held_lock_count(class_id, owner_id, PBF_LOCK_CLASS, flags, true);
> + if (kmem_cache_addr) {
> + update_held_lock_count((__u64)kmem_cache_addr, owner_id,
> + PBF_LOCK_SLAB, flags, true);
> + }
> + if (match_type)
> + update_held_lock_count(type_flag, owner_id, PBF_LOCK_TYPE, flags, true);
> +
> + return 0;
> +}
[Severity: Medium]
Can record_lock_acquired_owner() leak read_count in the held_locks map when
rwlocks are acquired via read_lock_irq() or read_lock_bh() on kernels with
CONFIG_GENERIC_LOCKBREAK=y and CONFIG_DEBUG_LOCK_ALLOC=n?
In kernel/locking/spinlock.c, BUILD_LOCK_OPS(read, rwlock, __acquires_shared)
implements __raw_read_lock_irq() and __raw_read_lock_bh() by calling the
noinline function _raw_read_lock_irqsave():
static void __lockfunc __raw_##op##_lock_irq(locktype##_t *lock) \
lock_ctx_op(lock) \
{ \
_raw_##op##_lock_irqsave(lock); \
} \
\
static void __lockfunc __raw_##op##_lock_bh(locktype##_t *lock) \
lock_ctx_op(lock) \
{ \
unsigned long flags; \
flags = _raw_##op##_lock_irqsave(lock); \
local_bh_disable(); \
local_irq_restore(flags); \
}
Since LOCK_PROG_RWLOCK_READ attaches fexit hooks to _raw_read_lock_irq,
_raw_read_lock_bh, and _raw_read_lock_irqsave, a single read_lock_irq() or
read_lock_bh() call fires both the inner fexit_raw_read_lock_irqsave hook
and the outer fexit_raw_read_lock_irq / fexit_raw_read_lock_bh hook.
Because is_read is true for LCB_F_SPIN | LCB_F_READ, the nested-call check
(!is_read && existing->write_count > 0) is bypassed and read_count is
incremented twice (for PBF_LOCK_ADDR as well as any active PBF_LOCK_SLAB or
PBF_LOCK_TYPE entries). On release, _raw_read_unlock_irq() and
_raw_read_unlock_bh() do not call _raw_read_unlock_irqrestore(), so
record_lock_released() only runs once, leaving read_count permanently
elevated in held_locks.
[ ... ]
> +/* RWlock acquire/release hooks */
> +SEC("fexit/_raw_read_lock")
> +int BPF_PROG(fexit_raw_read_lock, void *lock)
> +{
> + return record_lock_acquired(ctx, LCB_F_SPIN | LCB_F_READ);
> +}
> +
> +SEC("fexit/_raw_read_lock_irq")
> +int BPF_PROG(fexit_raw_read_lock_irq, void *lock)
> +{
> + return record_lock_acquired(ctx, LCB_F_SPIN | LCB_F_READ);
> +}
> +
> +SEC("fexit/_raw_read_lock_irqsave")
> +int BPF_PROG(fexit_raw_read_lock_irqsave, void *lock, unsigned long flags)
> +{
> + return record_lock_acquired(ctx, LCB_F_SPIN | LCB_F_READ);
> +}
> +
> +SEC("fexit/_raw_read_lock_bh")
> +int BPF_PROG(fexit_raw_read_lock_bh, void *lock)
> +{
> + return record_lock_acquired(ctx, LCB_F_SPIN | LCB_F_READ);
> +}
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261017171437.2066343-1-irogers@google.com?part=2
next prev parent reply other threads:[~2026-10-17 17:35 UTC|newest]
Thread overview: 129+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-17 5:45 [PATCH v1 0/5] perf bpf-filter / lock contention: Add lock_held() sample filter and RCU/SRCU support Ian Rogers
2026-10-17 5:45 ` [PATCH v1 1/5] perf lock contention: Share common BPF and lock type definitions in lock_data.h Ian Rogers
2026-10-17 5:52 ` sashiko-bot
2026-10-17 5:45 ` [PATCH v1 2/5] perf bpf-filter: Add lock_held() sample filter Ian Rogers
2026-10-17 6:09 ` sashiko-bot
2026-10-17 5:45 ` [PATCH v1 3/5] perf test: Add tests for lock_held() BPF " Ian Rogers
2026-10-17 5:49 ` sashiko-bot
2026-10-17 5:45 ` [PATCH v1 4/5] perf bpf-filter: Extend lock_held() to support RCU, Tasks Trace RCU, and SRCU Ian Rogers
2026-10-17 5:56 ` sashiko-bot
2026-10-17 5:45 ` [PATCH v1 5/5] perf lock contention: Extend BPF lock contention to RCU " Ian Rogers
2026-10-17 6:08 ` sashiko-bot
2026-10-17 17:14 ` [PATCH v2 0/6] perf bpf-filter / lock contention: Add lock_held() sample filter and RCU/SRCU support Ian Rogers
2026-10-17 17:14 ` [PATCH v2 1/6] perf lock contention: Share common BPF and lock type definitions in lock_data.h Ian Rogers
2026-10-17 17:31 ` sashiko-bot
2026-10-17 17:14 ` [PATCH v2 2/6] perf bpf-filter: Add lock_held() sample filter Ian Rogers
2026-10-17 17:35 ` sashiko-bot [this message]
2026-10-17 17:14 ` [PATCH v2 3/6] perf test: Add tests for lock_held() BPF " Ian Rogers
2026-10-17 17:17 ` sashiko-bot
2026-10-17 17:14 ` [PATCH v2 4/6] perf bpf-filter: Extend lock_held() to support RCU, Tasks Trace RCU, and SRCU Ian Rogers
2026-10-17 17:25 ` sashiko-bot
2026-10-17 17:14 ` [PATCH v2 5/6] perf lock contention: Extend BPF lock contention to RCU " Ian Rogers
2026-10-17 17:30 ` sashiko-bot
2026-10-17 17:14 ` [PATCH v2 6/6] perf lock contention: Filter events before creating lock_stat Ian Rogers
2026-10-17 17:17 ` sashiko-bot
2026-10-18 5:37 ` [PATCH v3 0/6] perf bpf-filter / lock contention: Add lock_held() sample filter and RCU/SRCU support Ian Rogers
2026-10-18 5:37 ` [PATCH v3 1/6] perf lock contention: Share common BPF and lock type definitions in lock_data.h Ian Rogers
2026-10-18 5:50 ` sashiko-bot
2026-10-18 5:37 ` [PATCH v3 2/6] perf bpf-filter: Add lock_held() sample filter Ian Rogers
2026-10-18 6:12 ` sashiko-bot
2026-10-18 5:37 ` [PATCH v3 3/6] perf test: Add tests for lock_held() BPF " Ian Rogers
2026-10-18 5:41 ` sashiko-bot
2026-10-18 5:37 ` [PATCH v3 4/6] perf bpf-filter: Extend lock_held() to support RCU, Tasks Trace RCU, and SRCU Ian Rogers
2026-10-18 5:51 ` sashiko-bot
2026-10-18 5:37 ` [PATCH v3 5/6] perf lock contention: Extend BPF lock contention to RCU " Ian Rogers
2026-10-18 5:48 ` sashiko-bot
2026-10-18 5:37 ` [PATCH v3 6/6] perf lock contention: Filter events before creating lock_stat Ian Rogers
2026-10-18 5:40 ` sashiko-bot
2026-10-19 7:00 ` [PATCH v3 0/6] perf bpf-filter / lock contention: Add lock_held() sample filter and RCU/SRCU support Namhyung Kim
2026-10-19 19:08 ` Ian Rogers
2026-10-19 22:09 ` [PATCH v4 0/7] " Ian Rogers
2026-10-19 22:09 ` [PATCH v4 1/7] perf lock contention: Filter events before creating lock_stat Ian Rogers
2026-10-19 22:14 ` sashiko-bot
2026-10-20 4:34 ` Namhyung Kim
2026-10-21 21:39 ` Arnaldo Carvalho de Melo
2026-10-19 22:09 ` [PATCH v4 2/7] perf bpf-filter: Support BPF sample filters on tracepoint events Ian Rogers
2026-10-19 22:26 ` sashiko-bot
2026-10-20 5:41 ` Namhyung Kim
2026-10-20 15:30 ` Ian Rogers
2026-10-20 22:29 ` Namhyung Kim
2026-10-19 22:09 ` [PATCH v4 3/7] perf lock contention: Share common BPF and lock type definitions in lock_data.h Ian Rogers
2026-10-19 22:17 ` sashiko-bot
2026-10-19 22:09 ` [PATCH v4 4/7] perf bpf-filter: Add lock_held() sample filter Ian Rogers
2026-10-19 22:28 ` sashiko-bot
2026-10-19 22:09 ` [PATCH v4 5/7] perf test: Add tests for lock_held() BPF " Ian Rogers
2026-10-19 22:12 ` sashiko-bot
2026-10-19 22:09 ` [PATCH v4 6/7] perf bpf-filter: Extend lock_held() to support RCU, Tasks Trace RCU, and SRCU Ian Rogers
2026-10-19 22:19 ` sashiko-bot
2026-10-19 22:09 ` [PATCH v4 7/7] perf lock contention: Extend BPF lock contention to RCU " Ian Rogers
2026-10-19 22:19 ` sashiko-bot
2026-10-20 20:58 ` [PATCH v5 0/8] perf bpf-filter / lock contention: Add lock_held() sample filter and RCU/SRCU support Ian Rogers
2026-10-20 20:58 ` [PATCH v5 1/8] perf lock contention: Filter events before creating lock_stat Ian Rogers
2026-10-20 22:38 ` sashiko-bot
2026-10-20 20:58 ` [PATCH v5 2/8] perf bpf-filter: Fix bpf_link leak by using PERF_EVENT_IOC_SET_BPF Ian Rogers
2026-10-20 22:41 ` sashiko-bot
2026-10-20 20:58 ` [PATCH v5 3/8] perf bpf-filter: Support BPF sample filters on tracepoint events Ian Rogers
2026-10-20 22:57 ` sashiko-bot
2026-10-20 20:58 ` [PATCH v5 4/8] perf lock contention: Share common BPF and lock type definitions in lock_data.h Ian Rogers
2026-10-20 22:42 ` Namhyung Kim
2026-10-20 23:02 ` sashiko-bot
2026-10-20 20:58 ` [PATCH v5 5/8] perf bpf-filter: Add lock_held() sample filter Ian Rogers
2026-10-20 22:49 ` Namhyung Kim
2026-10-20 23:17 ` sashiko-bot
2026-10-20 20:58 ` [PATCH v5 6/8] perf test: Add tests for lock_held() BPF " Ian Rogers
2026-10-20 23:20 ` sashiko-bot
2026-10-20 20:58 ` [PATCH v5 7/8] perf bpf-filter: Extend lock_held() to support RCU, Tasks Trace RCU, and SRCU Ian Rogers
2026-10-20 23:29 ` sashiko-bot
2026-10-20 20:58 ` [PATCH v5 8/8] perf lock contention: Extend BPF lock contention to RCU " Ian Rogers
2026-10-20 23:37 ` sashiko-bot
2026-10-22 20:29 ` [PATCH v6 00/11] perf bpf-filter / lock contention: Add lock_held() sample filter and RCU/SRCU support Ian Rogers
2026-10-22 20:29 ` [PATCH v6 01/11] perf bpf-filter: Fix bpf_link leak by using PERF_EVENT_IOC_SET_BPF Ian Rogers
2026-10-22 20:35 ` sashiko-bot
2026-10-22 22:06 ` Namhyung Kim
2026-10-22 20:29 ` [PATCH v6 02/11] perf bpf-filter: Support BPF sample filters on tracepoint events Ian Rogers
2026-10-22 20:55 ` sashiko-bot
2026-10-22 20:29 ` [PATCH v6 03/11] perf lock contention: Share common BPF and lock type definitions in lock_data.h Ian Rogers
2026-10-22 20:36 ` sashiko-bot
2026-10-22 20:29 ` [PATCH v6 04/11] perf lock contention: Extend get_lock_owner() for rt_mutex and mutex handoff Ian Rogers
2026-10-22 20:41 ` sashiko-bot
2026-10-22 20:29 ` [PATCH v6 05/11] perf bpf-filter: Add lock_held() sample filter for global mutexes Ian Rogers
2026-10-22 20:46 ` sashiko-bot
2026-10-22 22:55 ` Namhyung Kim
2026-10-23 5:16 ` Ian Rogers
2026-10-22 20:29 ` [PATCH v6 06/11] perf bpf-filter: Extend lock_held() to other kernel lock types Ian Rogers
2026-10-22 20:55 ` sashiko-bot
2026-10-22 22:56 ` Namhyung Kim
2026-10-23 5:19 ` Ian Rogers
2026-10-22 20:29 ` [PATCH v6 07/11] perf bpf-filter: Support per-process and semi-global locks in lock_held() Ian Rogers
2026-10-22 20:49 ` sashiko-bot
2026-10-22 20:30 ` [PATCH v6 08/11] perf bpf-filter: Support slab cache locks (&<name>) " Ian Rogers
2026-10-22 20:37 ` sashiko-bot
2026-10-22 20:30 ` [PATCH v6 09/11] perf test: Add tests for lock_held() BPF sample filter Ian Rogers
2026-10-22 20:37 ` sashiko-bot
2026-10-22 20:30 ` [PATCH v6 10/11] perf bpf-filter: Extend lock_held() to support RCU, Tasks Trace RCU, and SRCU Ian Rogers
2026-10-22 20:44 ` sashiko-bot
2026-10-22 20:30 ` [PATCH v6 11/11] perf lock contention: Extend BPF lock contention to RCU " Ian Rogers
2026-10-22 20:43 ` sashiko-bot
2026-10-23 19:05 ` [PATCH v7 00/11] perf bpf-filter / lock contention: Add lock_held() sample filter and RCU/SRCU support Ian Rogers
2026-10-23 19:05 ` [PATCH v7 01/11] perf bpf-filter: Fix bpf_link leak by using PERF_EVENT_IOC_SET_BPF Ian Rogers
2026-10-23 19:17 ` sashiko-bot
2026-10-23 19:05 ` [PATCH v7 02/11] perf bpf-filter: Support BPF sample filters on tracepoint events Ian Rogers
2026-10-23 19:22 ` sashiko-bot
2026-10-23 19:05 ` [PATCH v7 03/11] perf lock contention: Share common BPF and lock type definitions in lock_data.h Ian Rogers
2026-10-23 19:17 ` sashiko-bot
2026-10-23 19:05 ` [PATCH v7 04/11] perf lock contention: Extend get_lock_owner() for rt_mutex and mutex handoff Ian Rogers
2026-10-23 19:19 ` sashiko-bot
2026-10-23 19:05 ` [PATCH v7 05/11] perf bpf-filter: Add lock_held() sample filter for global mutexes Ian Rogers
2026-10-23 19:20 ` sashiko-bot
2026-10-23 19:05 ` [PATCH v7 06/11] perf bpf-filter: Extend lock_held() to other kernel lock types Ian Rogers
2026-10-23 19:26 ` sashiko-bot
2026-10-23 19:05 ` [PATCH v7 07/11] perf bpf-filter: Support per-process and semi-global locks in lock_held() Ian Rogers
2026-10-23 19:20 ` sashiko-bot
2026-10-23 19:05 ` [PATCH v7 08/11] perf bpf-filter: Support slab cache locks (&<name>) " Ian Rogers
2026-10-23 19:18 ` sashiko-bot
2026-10-23 19:05 ` [PATCH v7 09/11] perf test: Add tests for lock_held() BPF sample filter Ian Rogers
2026-10-23 19:16 ` sashiko-bot
2026-10-23 19:05 ` [PATCH v7 10/11] perf bpf-filter: Extend lock_held() to support RCU, Tasks Trace RCU, and SRCU Ian Rogers
2026-10-23 19:28 ` sashiko-bot
2026-10-23 19:05 ` [PATCH v7 11/11] perf lock contention: Extend BPF lock contention to RCU " Ian Rogers
2026-10-23 19:25 ` sashiko-bot
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=sashiko-outbox-175711@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.