Linux Trace Kernel
 help / color / mirror / Atom feed
* [RFC PATCH bpf-next v3 2/3] ftrace: Use kallsyms binary search for single-symbol lookup
From: Andrey Grodzovsky @ 2026-02-27 20:40 UTC (permalink / raw)
  To: bpf, linux-open-source
  Cc: ast, daniel, andrii, jolsa, rostedt, linux-trace-kernel
In-Reply-To: <20260227204052.725813-1-andrey.grodzovsky@crowdstrike.com>

When ftrace_lookup_symbols() is called with a single symbol (cnt == 1),
use kallsyms_lookup_name() for O(log N) binary search instead of the
full linear scan via kallsyms_on_each_symbol().

ftrace_lookup_symbols() was designed for batch resolution of many
symbols in a single pass.  For large cnt this is efficient: a single
O(N) walk over all symbols with O(log cnt) binary search into the
sorted input array.  But for cnt == 1 it still decompresses all ~200K
kernel symbols only to match one.

kallsyms_lookup_name() uses the sorted kallsyms index and needs only
~17 decompressions for a single lookup.

This is the common path for kprobe.session with exact function names,
where libbpf sends one symbol per BPF_LINK_CREATE syscall.

If binary lookup fails (duplicate symbol names where the first match
is not ftrace-instrumented), the function falls through to the existing
linear scan path.

Before (cnt=1, 50 kprobe.session programs):
  Attach: 858 ms  (kallsyms_expand_symbol 25% of CPU)

After:
  Attach:  52 ms  (16x faster)

Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
---
 kernel/trace/ftrace.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 827fb9a0bf0d..13906af8098a 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -9263,6 +9263,15 @@ static int kallsyms_callback(void *data, const char *name, unsigned long addr)
  * @addrs array, which needs to be big enough to store at least @cnt
  * addresses.
  *
+ * For a single symbol (cnt == 1), uses kallsyms_lookup_name() which
+ * performs an O(log N) binary search via the sorted kallsyms index.
+ * This avoids the full O(N) linear scan over all kernel symbols that
+ * the multi-symbol path requires.
+ *
+ * For multiple symbols, uses a single-pass linear scan via
+ * kallsyms_on_each_symbol() with binary search into the sorted input
+ * array.
+ *
  * Returns: 0 if all provided symbols are found, -ESRCH otherwise.
  */
 int ftrace_lookup_symbols(const char **sorted_syms, size_t cnt, unsigned long *addrs)
@@ -9270,6 +9279,19 @@ int ftrace_lookup_symbols(const char **sorted_syms, size_t cnt, unsigned long *a
 	struct kallsyms_data args;
 	int found_all;
 
+	/* Fast path: single symbol uses O(log N) binary search */
+	if (cnt == 1) {
+		addrs[0] = kallsyms_lookup_name(sorted_syms[0]);
+		if (addrs[0] && ftrace_location(addrs[0]))
+			return 0;
+		/*
+		 * Binary lookup can fail for duplicate symbol names
+		 * where the first match is not ftrace-instrumented.
+		 * Retry with linear scan.
+		 */
+	}
+
+	/* Batch path: single-pass O(N) linear scan */
 	memset(addrs, 0, sizeof(*addrs) * cnt);
 	args.addrs = addrs;
 	args.syms = sorted_syms;
-- 
2.34.1


^ permalink raw reply related

* [RFC PATCH bpf-next v3 3/3] selftests/bpf: add tests for kprobe.session optimization
From: Andrey Grodzovsky @ 2026-02-27 20:40 UTC (permalink / raw)
  To: bpf, linux-open-source
  Cc: ast, daniel, andrii, jolsa, rostedt, linux-trace-kernel
In-Reply-To: <20260227204052.725813-1-andrey.grodzovsky@crowdstrike.com>

Extend existing kprobe_multi_test subtests to validate the
kprobe.session exact function name optimization:

In kprobe_multi_session.c, add test_kprobe_syms which attaches a
kprobe.session program to an exact function name (bpf_fentry_test1)
exercising the fast syms[] path that bypasses kallsyms parsing.  It
calls session_check() so bpf_fentry_test1 is hit by both the wildcard
and exact probes, and test_session_skel_api validates
kprobe_session_result[0] == 4 (entry + return from each probe).

In test_attach_api_fails, add fail_7 and fail_8 verifying error code
consistency between the wildcard pattern path (slow, parses kallsyms)
and the exact function name path (fast, uses syms[] array).  Both
paths must return -ENOENT for non-existent functions.

Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
---
 .../bpf/prog_tests/kprobe_multi_test.c        | 33 +++++++++++++++++--
 .../bpf/progs/kprobe_multi_session.c          | 10 ++++++
 2 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
index 9caef222e528..ea605245ba14 100644
--- a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
+++ b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
@@ -327,6 +327,30 @@ static void test_attach_api_fails(void)
 	if (!ASSERT_EQ(saved_error, -E2BIG, "fail_6_error"))
 		goto cleanup;
 
+	/* fail_7 - non-existent wildcard pattern (slow path) */
+	LIBBPF_OPTS_RESET(opts);
+
+	link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
+						     "__nonexistent_func_xyz_*",
+						     &opts);
+	saved_error = -errno;
+	if (!ASSERT_ERR_PTR(link, "fail_7"))
+		goto cleanup;
+
+	if (!ASSERT_EQ(saved_error, -ENOENT, "fail_7_error"))
+		goto cleanup;
+
+	/* fail_8 - non-existent exact name (fast path), same error as wildcard */
+	link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
+						     "__nonexistent_func_xyz_123",
+						     &opts);
+	saved_error = -errno;
+	if (!ASSERT_ERR_PTR(link, "fail_8"))
+		goto cleanup;
+
+	if (!ASSERT_EQ(saved_error, -ENOENT, "fail_8_error"))
+		goto cleanup;
+
 cleanup:
 	bpf_link__destroy(link);
 	kprobe_multi__destroy(skel);
@@ -355,8 +379,13 @@ static void test_session_skel_api(void)
 	ASSERT_OK(err, "test_run");
 	ASSERT_EQ(topts.retval, 0, "test_run");
 
-	/* bpf_fentry_test1-4 trigger return probe, result is 2 */
-	for (i = 0; i < 4; i++)
+	/*
+	 * bpf_fentry_test1 is hit by both the wildcard probe and the exact
+	 * name probe (test_kprobe_syms), so entry + return fires twice: 4.
+	 * bpf_fentry_test2-4 are hit only by the wildcard probe: 2.
+	 */
+	ASSERT_EQ(skel->bss->kprobe_session_result[0], 4, "kprobe_session_result");
+	for (i = 1; i < 4; i++)
 		ASSERT_EQ(skel->bss->kprobe_session_result[i], 2, "kprobe_session_result");
 
 	/* bpf_fentry_test5-8 trigger only entry probe, result is 1 */
diff --git a/tools/testing/selftests/bpf/progs/kprobe_multi_session.c b/tools/testing/selftests/bpf/progs/kprobe_multi_session.c
index bd8b7fb7061e..d52a65b40bbf 100644
--- a/tools/testing/selftests/bpf/progs/kprobe_multi_session.c
+++ b/tools/testing/selftests/bpf/progs/kprobe_multi_session.c
@@ -76,3 +76,13 @@ int test_kprobe(struct pt_regs *ctx)
 {
 	return session_check(ctx);
 }
+
+/*
+ * Exact function name (no wildcards) - exercises the fast syms[] path
+ * in bpf_program__attach_kprobe_multi_opts() which bypasses kallsyms parsing.
+ */
+SEC("kprobe.session/bpf_fentry_test1")
+int test_kprobe_syms(struct pt_regs *ctx)
+{
+	return session_check(ctx);
+}
-- 
2.34.1


^ permalink raw reply related

* [RFC PATCH bpf-next v3 1/3] libbpf: Optimize kprobe.session attachment for exact function names
From: Andrey Grodzovsky @ 2026-02-27 20:40 UTC (permalink / raw)
  To: bpf, linux-open-source
  Cc: ast, daniel, andrii, jolsa, rostedt, linux-trace-kernel
In-Reply-To: <20260227204052.725813-1-andrey.grodzovsky@crowdstrike.com>

Detect exact function names (no wildcards) in
bpf_program__attach_kprobe_multi_opts() and bypass kallsyms parsing,
passing the symbol directly to the kernel via syms[] array.  This
benefits all callers, not just kprobe.session.

When the pattern contains no '*' or '?' characters, set syms to point
directly at the pattern string and cnt to 1, skipping the expensive
/proc/kallsyms or available_filter_functions parsing (~150ms per
function).

Error code normalization: the fast path returns ESRCH from kernel's
ftrace_lookup_symbols(), while the slow path returns ENOENT from
userspace kallsyms parsing.  Convert ESRCH to ENOENT in the
bpf_link_create error path to maintain API consistency - both paths
now return identical error codes for "symbol not found".

Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
---
 tools/lib/bpf/libbpf.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 0be7017800fe..80278385bc9c 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -12041,7 +12041,15 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
 	if (addrs && syms)
 		return libbpf_err_ptr(-EINVAL);
 
-	if (pattern) {
+	/*
+	 * Exact function name (no wildcards): bypass kallsyms parsing
+	 * and pass the symbol directly to the kernel via syms[] array.
+	 * The kernel's ftrace_lookup_symbols() resolves it efficiently.
+	 */
+	if (pattern && !strpbrk(pattern, "*?")) {
+		syms = &pattern;
+		cnt = 1;
+	} else if (pattern) {
 		if (has_available_filter_functions_addrs())
 			err = libbpf_available_kprobes_parse(&res);
 		else
@@ -12084,6 +12092,14 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
 	link_fd = bpf_link_create(prog_fd, 0, attach_type, &lopts);
 	if (link_fd < 0) {
 		err = -errno;
+		/*
+		 * Normalize error code: when exact name bypasses kallsyms
+		 * parsing, kernel returns ESRCH from ftrace_lookup_symbols().
+		 * Convert to ENOENT for API consistency with the pattern
+		 * matching path which returns ENOENT from userspace.
+		 */
+		if (err == -ESRCH)
+			err = -ENOENT;
 		pr_warn("prog '%s': failed to attach: %s\n",
 			prog->name, errstr(err));
 		goto error;
-- 
2.34.1


^ permalink raw reply related

* [RFC PATCH bpf-next v3 0/3] Optimize kprobe.session attachment for exact function names
From: Andrey Grodzovsky @ 2026-02-27 20:40 UTC (permalink / raw)
  To: bpf, linux-open-source
  Cc: ast, daniel, andrii, jolsa, rostedt, linux-trace-kernel

When libbpf attaches kprobe.session programs with exact function names
(the common case: SEC("kprobe.session/vfs_read")), the current code path
has two independent performance bottlenecks:

1. Userspace (libbpf): attach_kprobe_session() always parses
/proc/kallsyms to resolve function names, even when the name is exact
(no wildcards).  This takes ~150ms per function.

2. Kernel (ftrace): ftrace_lookup_symbols() does a full O(N) linear scan
over ~200K kernel symbols via kallsyms_on_each_symbol(), decompressing
every symbol name, even when resolving a single symbol (cnt == 1).

This series optimizes both layers:

- Patch 1: libbpf detects exact function names (no wildcards) in
bpf_program__attach_kprobe_multi_opts() and bypasses kallsyms parsing,
passing the symbol directly to the kernel via syms[] array.
ESRCH is normalized to ENOENT for API consistency.

- Patch 2: ftrace_lookup_symbols() uses kallsyms_lookup_name() for
O(log N) binary search when cnt == 1, with fallback to linear scan for
duplicate symbols. Included here for context; this patch is destined
for the tracing tree via linux-trace-kernel (Steven Rostedt).

- Patch 3: Selftests validating exact-name attachment via
kprobe_multi_session.c and error consistency between wildcard and exact
paths in test_attach_api_fails.

Changes since v2 [2]:
- Use if/else-if instead of goto (Jiri Olsa)
- Use syms = &pattern directly (Jiri Olsa)
- Drop unneeded pattern = NULL (Jiri Olsa)
- Revert cosmetic rename in attach_kprobe_session (Jiri Olsa)
- Remove "module symbols" from ftrace comment (CI bot)

Changes since v1 [1]:
- Move optimization into attach_kprobe_multi_opts (Jiri Olsa)
- Use ftrace_location as boolean check only (Jiri Olsa)
- Remove verbose perf rationale from comment (Steven Rostedt)
- Consolidate tests into existing subtests (Jiri Olsa)
- Delete standalone _syms.c and _errors.c files

[1] https://lore.kernel.org/bpf/20260223215113.924599-1-andrey.grodzovsky@crowdstrike.com/
[2] https://lore.kernel.org/bpf/20260226173342.3565919-1-andrey.grodzovsky@crowdstrike.com/

Andrey Grodzovsky (3):
  libbpf: Optimize kprobe.session attachment for exact function names
  ftrace: Use kallsyms binary search for single-symbol lookup
  selftests/bpf: add tests for kprobe.session optimization

 kernel/trace/ftrace.c                         | 22 +++++++++++++
 tools/lib/bpf/libbpf.c                        | 18 +++++++++-
 .../bpf/prog_tests/kprobe_multi_test.c        | 33 +++++++++++++++++--
 .../bpf/progs/kprobe_multi_session.c          | 10 ++++++
 4 files changed, 80 insertions(+), 3 deletions(-)

-- 
2.34.1


^ permalink raw reply

* Re: [PATCH v4 4/5] mm: rename zone->lock to zone->_lock
From: David Hildenbrand (Arm) @ 2026-02-27 20:40 UTC (permalink / raw)
  To: Dmitry Ilvokhin, Andrew Morton, Lorenzo Stoakes, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Axel Rasmussen, Yuanchu Xie, Wei Xu, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, Rafael J. Wysocki,
	Pavel Machek, Len Brown, Brendan Jackman, Johannes Weiner, Zi Yan,
	Oscar Salvador, Qi Zheng, Shakeel Butt
  Cc: linux-kernel, linux-mm, linux-trace-kernel, linux-pm,
	"linux-cxl, SeongJae Park
In-Reply-To: <d61500c5784c64e971f4d328c57639303c475f81.1772206930.git.d@ilvokhin.com>

On 2/27/26 17:00, Dmitry Ilvokhin wrote:
> This intentionally breaks direct users of zone->lock at compile time so
> all call sites are converted to the zone lock wrappers. Without the
> rename, present and future out-of-tree code could continue using
> spin_lock(&zone->lock) and bypass the wrappers and tracing
> infrastructure.
> 
> No functional change intended.
> 
> Suggested-by: Andrew Morton <akpm@linux-foundation.org>
> Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
> Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
> Acked-by: SeongJae Park <sj@kernel.org>
> ---

Acked-by: David Hildenbrand (Arm) <david@kernel.org>

-- 
Cheers,

David

^ permalink raw reply

* Re: [PATCH v4 3/5] mm: convert compaction to zone lock wrappers
From: David Hildenbrand (Arm) @ 2026-02-27 20:39 UTC (permalink / raw)
  To: Dmitry Ilvokhin, Andrew Morton, Lorenzo Stoakes, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Axel Rasmussen, Yuanchu Xie, Wei Xu, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, Rafael J. Wysocki,
	Pavel Machek, Len Brown, Brendan Jackman, Johannes Weiner, Zi Yan,
	Oscar Salvador, Qi Zheng, Shakeel Butt
  Cc: linux-kernel, linux-mm, linux-trace-kernel, linux-pm,
	"linux-cxl
In-Reply-To: <3a09e46f52cf9f709b0725bc2b648cc5212843b2.1772206930.git.d@ilvokhin.com>

On 2/27/26 17:00, Dmitry Ilvokhin wrote:
> Compaction uses compact_lock_irqsave(), which currently operates
> on a raw spinlock_t pointer so it can be used for both zone->lock
> and lruvec->lru_lock. Since zone lock operations are now wrapped,
> compact_lock_irqsave() can no longer directly operate on a
> spinlock_t when the lock belongs to a zone.
> 
> Split the helper into compact_zone_lock_irqsave() and
> compact_lruvec_lock_irqsave(), duplicating the small amount of
> shared logic. As there are only two call sites and both statically
> know the lock type, this avoids introducing additional abstraction
> or runtime dispatch in the compaction path.
> 
> No functional change intended.
> 
> Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
> Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
> ---
>  mm/compaction.c | 33 ++++++++++++++++++++++++---------
>  1 file changed, 24 insertions(+), 9 deletions(-)
> 
> diff --git a/mm/compaction.c b/mm/compaction.c
> index fa0e332a8a92..c68fcc416fc7 100644
> --- a/mm/compaction.c
> +++ b/mm/compaction.c
> @@ -503,19 +503,36 @@ static bool test_and_set_skip(struct compact_control *cc, struct page *page)
>   *
>   * Always returns true which makes it easier to track lock state in callers.
>   */
> -static bool compact_lock_irqsave(spinlock_t *lock, unsigned long *flags,
> -						struct compact_control *cc)
> -	__acquires(lock)
> +static bool compact_zone_lock_irqsave(struct zone *zone,
> +				      unsigned long *flags,
> +				      struct compact_control *cc)

... two tabs :)

Acked-by: David Hildenbrand (Arm) <david@kernel.org>

-- 
Cheers,

David

^ permalink raw reply

* Re: [PATCH v4 2/5] mm: convert zone lock users to wrappers
From: David Hildenbrand (Arm) @ 2026-02-27 20:39 UTC (permalink / raw)
  To: Dmitry Ilvokhin, Andrew Morton, Lorenzo Stoakes, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Axel Rasmussen, Yuanchu Xie, Wei Xu, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, Rafael J. Wysocki,
	Pavel Machek, Len Brown, Brendan Jackman, Johannes Weiner, Zi Yan,
	Oscar Salvador, Qi Zheng, Shakeel Butt
  Cc: linux-kernel, linux-mm, linux-trace-kernel, linux-pm,
	"linux-cxl, SeongJae Park
In-Reply-To: <d26a43ebed2f0f1edb9cfe4fbed16dd31c7a069c.1772206930.git.d@ilvokhin.com>

On 2/27/26 17:00, Dmitry Ilvokhin wrote:
> Replace direct zone lock acquire/release operations with the
> newly introduced wrappers.
> 
> The changes are purely mechanical substitutions. No functional change
> intended. Locking semantics and ordering remain unchanged.
> 
> The compaction path is left unchanged for now and will be
> handled separately in the following patch due to additional
> non-trivial modifications.
> 
> Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
> Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
> Reviewed-by: SeongJae Park <sj@kernel.org>
> ---

[...]

>  #ifdef CONFIG_COMPACTION
> @@ -530,11 +531,14 @@ static bool compact_lock_irqsave(spinlock_t *lock, unsigned long *flags,
>   * Returns true if compaction should abort due to fatal signal pending.
>   * Returns false when compaction can continue.
>   */
> -static bool compact_unlock_should_abort(spinlock_t *lock,
> -		unsigned long flags, bool *locked, struct compact_control *cc)
> +
> +static bool compact_unlock_should_abort(struct zone *zone,
> +					unsigned long flags,
> +					bool *locked,
> +					struct compact_control *cc)

We tend to use two-tabs on second parameter line; like the existing code
did.


Besides that

Acked-by: David Hildenbrand (Arm) <david@kernel.org>

-- 
Cheers,

David

^ permalink raw reply

* Re: [PATCHv6 bpf-next 9/9] bpf,x86: Use single ftrace_ops for direct calls
From: Jiri Olsa @ 2026-02-27 20:37 UTC (permalink / raw)
  To: Ihor Solodrai
  Cc: Steven Rostedt, Florent Revest, Mark Rutland, bpf, linux-kernel,
	linux-trace-kernel, linux-arm-kernel, Alexei Starovoitov,
	Daniel Borkmann, Andrii Nakryiko, Menglong Dong, Song Liu,
	Kumar Kartikeya Dwivedi
In-Reply-To: <1b58ffb2-92ae-433a-ba46-95294d6edea2@linux.dev>

On Fri, Feb 27, 2026 at 09:40:12AM -0800, Ihor Solodrai wrote:
> On 12/30/25 6:50 AM, Jiri Olsa wrote:
> > Using single ftrace_ops for direct calls update instead of allocating
> > ftrace_ops object for each trampoline.
> > 
> > With single ftrace_ops object we can use update_ftrace_direct_* api
> > that allows multiple ip sites updates on single ftrace_ops object.
> > 
> > Adding HAVE_SINGLE_FTRACE_DIRECT_OPS config option to be enabled on
> > each arch that supports this.
> > 
> > At the moment we can enable this only on x86 arch, because arm relies
> > on ftrace_ops object representing just single trampoline image (stored
> > in ftrace_ops::direct_call). Archs that do not support this will continue
> > to use *_ftrace_direct api.
> > 
> > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> 
> Hi Jiri,
> 
> Me and Kumar stumbled on kernel splats with "ftrace failed to modify",
> and if running with KASAN:
> 
>   BUG: KASAN: slab-use-after-free in __get_valid_kprobe+0x224/0x2a0
> 
> Pasting a full splat example at the bottom.
> 
> I was able to create a reproducer with AI, and then used it to bisect
> to this patch. You can run it with ./test_progs -t ftrace_direct_race
> 
> Below is my (human-generated, haha) summary of AI's analysis of what's
> happening. It makes sense to me conceptually, but I don't know enough
> details here to call bullshit. Please take a look:

hi, nice :)

> 
>     With CONFIG_HAVE_SINGLE_FTRACE_DIRECT_OPS ftrace_replace_code()
>     operates on all call sites in the shared ops. Then if a concurrent
>     ftrace user (like kprobe) modifies a call site in between
>     ftrace_replace_code's verify pass and its patch pass, then ftrace_bug
>     fires and sets ftrace_disabled to 1.

hum, I'd think that's all under ftrace_lock/direct_mutex,
but we might be missing some paths

> 
>     Once ftrace is disabled, direct_ops_del silently fails to unregister
>     the direct call, and the call site still redirects to the stale
>     trampoline. After the BPF program is freed, we'll get use-after-free
>     on the next trace hit.
> 
> The reproducer is not great, because if everything is fine it just hangs.
> But with the bug the kernel crashes pretty fast.

perfect, I reproduced it on first run.. will check

> Maybe it makes sense to refine it to a proper "stress" selftest?

it might, let's see what's the problem


great report, thanks a lot for all the details and reproducer,

jirka


> 
> Reproducer patch:
> 
> From c595ef5a0ad9bc62d768080ff09502bc982c40e6 Mon Sep 17 00:00:00 2001
> From: Ihor Solodrai <ihor.solodrai@linux.dev>
> Date: Thu, 26 Feb 2026 17:00:39 -0800
> Subject: [PATCH] reproducer
> 
> ---
>  .../bpf/prog_tests/ftrace_direct_race.c       | 243 ++++++++++++++++++
>  1 file changed, 243 insertions(+)
>  create mode 100644 tools/testing/selftests/bpf/prog_tests/ftrace_direct_race.c
> 
> diff --git a/tools/testing/selftests/bpf/prog_tests/ftrace_direct_race.c b/tools/testing/selftests/bpf/prog_tests/ftrace_direct_race.c
> new file mode 100644
> index 000000000000..369c55364d05
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/prog_tests/ftrace_direct_race.c
> @@ -0,0 +1,243 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */
> +
> +/* Test to reproduce ftrace race between BPF trampoline attach/detach
> + * and kprobe attach/detach on the same function.
> + *
> + * With CONFIG_HAVE_SINGLE_FTRACE_DIRECT_OPS, all BPF trampolines share
> + * a single ftrace_ops. Concurrent modifications (BPF trampoline vs kprobe)
> + * can race in ftrace_replace_code's verify-then-patch sequence, causing
> + * ftrace to become permanently disabled and leaving stale trampolines
> + * that reference freed BPF programs.
> + *
> + * Run with: ./test_progs -t ftrace_direct_race
> + */
> +#include <test_progs.h>
> +#include <bpf/libbpf.h>
> +#include <pthread.h>
> +#include <sys/ioctl.h>
> +#include <linux/perf_event.h>
> +#include <sys/syscall.h>
> +
> +#include "fentry_test.lskel.h"
> +
> +#define NUM_ITERATIONS	200
> +
> +static volatile bool stop;
> +
> +/* Thread 1: Rapidly attach and detach fentry BPF trampolines */
> +static void *fentry_thread_fn(void *arg)
> +{
> +	int i;
> +
> +	for (i = 0; i < NUM_ITERATIONS && !stop; i++) {
> +		struct fentry_test_lskel *skel;
> +		int err;
> +
> +		skel = fentry_test_lskel__open();
> +		if (!skel)
> +			continue;
> +
> +		skel->keyring_id = KEY_SPEC_SESSION_KEYRING;
> +		err = fentry_test_lskel__load(skel);
> +		if (err) {
> +			fentry_test_lskel__destroy(skel);
> +			continue;
> +		}
> +
> +		err = fentry_test_lskel__attach(skel);
> +		if (err) {
> +			fentry_test_lskel__destroy(skel);
> +			continue;
> +		}
> +
> +		/* Brief sleep to let the trampoline be live while kprobes race */
> +		usleep(100 + rand() % 500);
> +
> +		fentry_test_lskel__detach(skel);
> +		fentry_test_lskel__destroy(skel);
> +	}
> +
> +	return NULL;
> +}
> +
> +/* Thread 2: Rapidly create and destroy kprobes via tracefs on
> + * bpf_fentry_test* functions (the same functions the fentry thread targets).
> + * Creating/removing kprobe events goes through the ftrace code patching
> + * path that can race with BPF trampoline direct call operations.
> + */
> +static void *kprobe_thread_fn(void *arg)
> +{
> +	const char *funcs[] = {
> +		"bpf_fentry_test1",
> +		"bpf_fentry_test2",
> +		"bpf_fentry_test3",
> +		"bpf_fentry_test4",
> +		"bpf_fentry_test5",
> +		"bpf_fentry_test6",
> +	};
> +	int i;
> +
> +	for (i = 0; i < NUM_ITERATIONS && !stop; i++) {
> +		int j;
> +
> +		for (j = 0; j < 6 && !stop; j++) {
> +			char cmd[256];
> +
> +			/* Create kprobe via tracefs */
> +			snprintf(cmd, sizeof(cmd),
> +				 "echo 'p:kprobe_race_%d %s' >> /sys/kernel/debug/tracing/kprobe_events 2>/dev/null",
> +				 j, funcs[j]);
> +			system(cmd);
> +
> +			/* Small delay */
> +			usleep(50 + rand() % 200);
> +
> +			/* Remove kprobe */
> +			snprintf(cmd, sizeof(cmd),
> +				 "echo '-:kprobe_race_%d' >> /sys/kernel/debug/tracing/kprobe_events 2>/dev/null",
> +				 j);
> +			system(cmd);
> +		}
> +	}
> +
> +	return NULL;
> +}
> +
> +/* Thread 3: Create kprobes via perf_event_open (the ftrace-based kind)
> + * which go through the arm_kprobe / disarm_kprobe ftrace path.
> + */
> +static void *perf_kprobe_thread_fn(void *arg)
> +{
> +	const char *funcs[] = {
> +		"bpf_fentry_test1",
> +		"bpf_fentry_test2",
> +		"bpf_fentry_test3",
> +	};
> +	int i;
> +
> +	for (i = 0; i < NUM_ITERATIONS && !stop; i++) {
> +		int fds[3] = {-1, -1, -1};
> +		int j;
> +
> +		for (j = 0; j < 3 && !stop; j++) {
> +			struct perf_event_attr attr = {};
> +			char path[256];
> +			char buf[32];
> +			char cmd[256];
> +			int id_fd, id;
> +
> +			/* Create kprobe event */
> +			snprintf(cmd, sizeof(cmd),
> +				 "echo 'p:perf_race_%d %s' >> /sys/kernel/debug/tracing/kprobe_events 2>/dev/null",
> +				 j, funcs[j]);
> +			system(cmd);
> +
> +			/* Try to get the event id */
> +			snprintf(path, sizeof(path),
> +				 "/sys/kernel/debug/tracing/events/kprobes/perf_race_%d/id", j);
> +			id_fd = open(path, O_RDONLY);
> +			if (id_fd < 0)
> +				continue;
> +
> +			memset(buf, 0, sizeof(buf));
> +			if (read(id_fd, buf, sizeof(buf) - 1) > 0)
> +				id = atoi(buf);
> +			else
> +				id = -1;
> +			close(id_fd);
> +
> +			if (id < 0)
> +				continue;
> +
> +			/* Open perf event to arm the kprobe via ftrace */
> +			attr.type = PERF_TYPE_TRACEPOINT;
> +			attr.size = sizeof(attr);
> +			attr.config = id;
> +			attr.sample_type = PERF_SAMPLE_RAW;
> +			attr.sample_period = 1;
> +			attr.wakeup_events = 1;
> +
> +			fds[j] = syscall(__NR_perf_event_open, &attr, -1, 0, -1, 0);
> +			if (fds[j] >= 0)
> +				ioctl(fds[j], PERF_EVENT_IOC_ENABLE, 0);
> +		}
> +
> +		usleep(100 + rand() % 300);
> +
> +		/* Close perf events (disarms kprobes via ftrace) */
> +		for (j = 0; j < 3; j++) {
> +			char cmd[256];
> +
> +			if (fds[j] >= 0)
> +				close(fds[j]);
> +
> +			snprintf(cmd, sizeof(cmd),
> +				 "echo '-:perf_race_%d' >> /sys/kernel/debug/tracing/kprobe_events 2>/dev/null",
> +				 j);
> +			system(cmd);
> +		}
> +	}
> +
> +	return NULL;
> +}
> +
> +void test_ftrace_direct_race(void)
> +{
> +	pthread_t fentry_tid, kprobe_tid, perf_kprobe_tid;
> +	int err;
> +
> +	/* Check if ftrace is currently operational */
> +	if (!ASSERT_OK(access("/sys/kernel/debug/tracing/kprobe_events", W_OK),
> +		       "tracefs_access"))
> +		return;
> +
> +	stop = false;
> +
> +	err = pthread_create(&fentry_tid, NULL, fentry_thread_fn, NULL);
> +	if (!ASSERT_OK(err, "create_fentry_thread"))
> +		return;
> +
> +	err = pthread_create(&kprobe_tid, NULL, kprobe_thread_fn, NULL);
> +	if (!ASSERT_OK(err, "create_kprobe_thread")) {
> +		stop = true;
> +		pthread_join(fentry_tid, NULL);
> +		return;
> +	}
> +
> +	err = pthread_create(&perf_kprobe_tid, NULL, perf_kprobe_thread_fn, NULL);
> +	if (!ASSERT_OK(err, "create_perf_kprobe_thread")) {
> +		stop = true;
> +		pthread_join(fentry_tid, NULL);
> +		pthread_join(kprobe_tid, NULL);
> +		return;
> +	}
> +
> +	pthread_join(fentry_tid, NULL);
> +	pthread_join(kprobe_tid, NULL);
> +	pthread_join(perf_kprobe_tid, NULL);
> +
> +	/* If we get here without a kernel panic/oops, the test passed.
> +	 * The real check is in dmesg: look for
> +	 *   "WARNING: arch/x86/kernel/ftrace.c" or
> +	 *   "BUG: KASAN: vmalloc-out-of-bounds in __bpf_prog_enter_recur"
> +	 *
> +	 * A more robust check: verify ftrace is still operational.
> +	 */
> +	ASSERT_OK(access("/sys/kernel/debug/tracing/kprobe_events", W_OK),
> +		  "ftrace_still_operational");
> +
> +	/* Check that ftrace wasn't disabled */
> +	{
> +		char buf[64] = {};
> +		int fd = open("/proc/sys/kernel/ftrace_enabled", O_RDONLY);
> +
> +		if (ASSERT_GE(fd, 0, "open_ftrace_enabled")) {
> +			int n = read(fd, buf, sizeof(buf) - 1);
> +
> +			close(fd);
> +			if (n > 0)
> +				ASSERT_EQ(atoi(buf), 1, "ftrace_enabled");
> +		}
> +	}
> +}
> -- 
> 2.47.3
> 
> 
> ----
> 
> Splat:
> 
> [   24.170803] ------------[ cut here ]------------                                                                                                              
> [   24.171055] WARNING: kernel/trace/ftrace.c:2715 at ftrace_get_addr_curr+0x149/0x190, CPU#13: kworker/13:6/873                                                 
> [   24.171315] Modules linked in: bpf_test_modorder_y(OE+) bpf_test_modorder_x(OE) bpf_testmod(OE)                                                               
> [   24.171561] CPU: 13 UID: 0 PID: 873 Comm: kworker/13:6 Tainted: G           OE       7.0.0-rc1-gda78c0a81eea #83 PREEMPT(full)                                
> [   24.171827] Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE                                                                                                      
> [   24.171941] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-5.el9 11/05/2023                                                               
> [   24.172132] Workqueue: events bpf_link_put_deferred                                                                                                           
> [   24.172261] RIP: 0010:ftrace_get_addr_curr+0x149/0x190                                                                                                        
> [   24.172376] Code: 00 4c 89 f7 e8 88 f8 ff ff 84 c0 75 92 4d 8b 7f 08 e8 fb b3 c1 00 4d 85 ff 0f 94 c0 49 81 ff b0 1c 6e 83 0f 94 c1 08 c1 74 96 <0f> 0b c6 05 
> 62 e8 2b 02 01 c7 05 54 e8 2b 02 00 00 00 00 48 c7 05                                                                                                            
> [   24.172745] RSP: 0018:ffa0000504cafb78 EFLAGS: 00010202                                                                                                       
> [   24.172861] RAX: 0000000000000000 RBX: ff110001000e48d0 RCX: ff1100011cd3a201                                                                                 
> [   24.173034] RDX: 6e21cb51d943709c RSI: 0000000000000000 RDI: ffffffff81d416d4                                                                                 
> [   24.173194] RBP: 0000000000000001 R08: 0000000080000000 R09: ffffffffffffffff                                                                                 
> [   24.173366] R10: ffffffff81285522 R11: 0000000000000000 R12: ff110001000e48d0                                                                                 
> [   24.173530] R13: ffffffff81d416d4 R14: ffffffff81d416d4 R15: ffffffff836e1cb0                                                                                 
> [   24.173691] FS:  0000000000000000(0000) GS:ff1100203becc000(0000) knlGS:0000000000000000                                                                      
> [   24.173849] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033                                                                                                 
> [   24.173995] CR2: 00007f615e966270 CR3: 000000010bd9d005 CR4: 0000000000771ef0                                                                                 
> [   24.174155] PKRU: 55555554                                                                                                                                    
> [   24.174214] Call Trace:                                                                                                                                       
> [   24.174285]  <TASK>                                                                                                                                           
> [   24.174348]  ftrace_replace_code+0x7e/0x210                                                                                                                   
> [   24.174443]  ftrace_modify_all_code+0x59/0x110                                                                                                                
> [   24.174553]  __ftrace_hash_move_and_update_ops+0x227/0x2c0                                                                                                    
> [   24.174659]  ? kfree+0x1ac/0x4c0                                                                                                                              
> [   24.174751]  ? srso_return_thunk+0x5/0x5f                                                                                                                     
> [   24.174834]  ? kfree+0x250/0x4c0                                                                                                                              
> [   24.174926]  ? kfree+0x1ac/0x4c0                                                                                                                              
> [   24.175010]  ? bpf_lsm_sk_alloc_security+0x4/0x20                                                                                                             
> [   24.175132]  ftrace_update_ops+0x40/0x80                                                                                                                      
> [   24.175217]  update_ftrace_direct_del+0x263/0x290                                                                                                             
> [   24.175341]  ? bpf_lsm_sk_alloc_security+0x4/0x20                                                                                                             
> [   24.175456]  ? 0xffffffffc0006a80                                                                                                                             
> [   24.175543]  bpf_trampoline_update+0x1fb/0x810                                                                                                                
> [   24.175654]  bpf_trampoline_unlink_prog+0x103/0x1a0                                                                                                           
> [   24.175767]  ? process_scheduled_works+0x271/0x640                                                                                                            
> [   24.175886]  bpf_shim_tramp_link_release+0x20/0x40                                                                                                            
> [   24.176001]  bpf_link_free+0x54/0xd0                                                                                                                          
> [   24.176092]  process_scheduled_works+0x2c2/0x640                             
> [   24.176222]  worker_thread+0x22a/0x340                                                                                                    21:11:27 [422/10854]
> [   24.176319]  ? srso_return_thunk+0x5/0x5f
> [   24.176405]  ? __pfx_worker_thread+0x10/0x10
> [   24.176522]  kthread+0x10c/0x140
> [   24.176611]  ? __pfx_kthread+0x10/0x10
> [   24.176698]  ret_from_fork+0x148/0x290
> [   24.176785]  ? __pfx_kthread+0x10/0x10
> [   24.176872]  ret_from_fork_asm+0x1a/0x30
> [   24.176985]  </TASK>
> [   24.177043] irq event stamp: 6965
> [   24.177126] hardirqs last  enabled at (6973): [<ffffffff8136008c>] __console_unlock+0x5c/0x70
> [   24.177325] hardirqs last disabled at (6982): [<ffffffff81360071>] __console_unlock+0x41/0x70
> [   24.177520] softirqs last  enabled at (6524): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
> [   24.177675] softirqs last disabled at (6123): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
> [   24.177844] ---[ end trace 0000000000000000 ]---
> [   24.177963] Bad trampoline accounting at: 000000003143da54 (bpf_fentry_test3+0x4/0x20)
> [   24.178134] ------------[ cut here ]------------
> [   24.178261] WARNING: arch/x86/kernel/ftrace.c:105 at ftrace_replace_code+0xf7/0x210, CPU#13: kworker/13:6/873
> [   24.178476] Modules linked in: bpf_test_modorder_y(OE+) bpf_test_modorder_x(OE) bpf_testmod(OE)
> [   24.178680] CPU: 13 UID: 0 PID: 873 Comm: kworker/13:6 Tainted: G        W  OE       7.0.0-rc1-gda78c0a81eea #83 PREEMPT(full) 
> [   24.178925] Tainted: [W]=WARN, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
> [   24.179059] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-5.el9 11/05/2023
> [   24.179258] Workqueue: events bpf_link_put_deferred
> [   24.179374] RIP: 0010:ftrace_replace_code+0xf7/0x210
> [   24.179485] Code: c0 0f 85 ec 00 00 00 8b 44 24 03 41 33 45 00 0f b6 4c 24 07 41 32 4d 04 0f b6 c9 09 c1 0f 84 49 ff ff ff 4c 89 2d b9 df 8b 03 <0f> 0b bf ea 
> ff ff ff e9 c4 00 00 00 e8 f8 e5 19 00 48 85 c0 0f 84
> [   24.179847] RSP: 0018:ffa0000504cafb98 EFLAGS: 00010202
> [   24.179965] RAX: 0000000038608000 RBX: 0000000000000001 RCX: 00000000386080c1
> [   24.180126] RDX: ffffffff81d41000 RSI: 0000000000000005 RDI: ffffffff81d416d4
> [   24.180295] RBP: 0000000000000001 R08: 000000000000ffff R09: ffffffff82e98430
> [   24.180455] R10: 000000000002fffd R11: 00000000fffeffff R12: ff110001000e48d0
> [   24.180617] R13: ffffffff83ec0f2d R14: ffffffff84b43820 R15: ffa0000504cafb9b
> [   24.180777] FS:  0000000000000000(0000) GS:ff1100203becc000(0000) knlGS:0000000000000000
> [   24.180939] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [   24.181077] CR2: 00007f615e966270 CR3: 000000010bd9d005 CR4: 0000000000771ef0
> [   24.181247] PKRU: 55555554
> [   24.181303] Call Trace:
> [   24.181360]  <TASK>
> [   24.181424]  ftrace_modify_all_code+0x59/0x110
> [   24.181536]  __ftrace_hash_move_and_update_ops+0x227/0x2c0
> [   24.181650]  ? kfree+0x1ac/0x4c0
> [   24.181743]  ? srso_return_thunk+0x5/0x5f
> [   24.181828]  ? kfree+0x250/0x4c0
> [   24.181916]  ? kfree+0x1ac/0x4c0
> [   24.182004]  ? bpf_lsm_sk_alloc_security+0x4/0x20
> [   24.182123]  ftrace_update_ops+0x40/0x80
> [   24.182213]  update_ftrace_direct_del+0x263/0x290
> [   24.182337]  ? bpf_lsm_sk_alloc_security+0x4/0x20
> [   24.182455]  ? 0xffffffffc0006a80
> [   24.182543]  bpf_trampoline_update+0x1fb/0x810
> [   24.182655]  bpf_trampoline_unlink_prog+0x103/0x1a0
> [   24.182768]  ? process_scheduled_works+0x271/0x640
> [   24.182887]  bpf_shim_tramp_link_release+0x20/0x40
> [   24.183001]  bpf_link_free+0x54/0xd0
> [   24.183088]  process_scheduled_works+0x2c2/0x640
> [   24.183220]  worker_thread+0x22a/0x340                                                                                                    21:11:27 [367/10854]
> [   24.183319]  ? srso_return_thunk+0x5/0x5f        
> [   24.183405]  ? __pfx_worker_thread+0x10/0x10     
> [   24.183521]  kthread+0x10c/0x140
> [   24.183610]  ? __pfx_kthread+0x10/0x10
> [   24.183697]  ret_from_fork+0x148/0x290
> [   24.183783]  ? __pfx_kthread+0x10/0x10
> [   24.183868]  ret_from_fork_asm+0x1a/0x30
> [   24.183979]  </TASK>
> [   24.184056] irq event stamp: 7447
> [   24.184138] hardirqs last  enabled at (7455): [<ffffffff8136008c>] __console_unlock+0x5c/0x70
> [   24.184339] hardirqs last disabled at (7464): [<ffffffff81360071>] __console_unlock+0x41/0x70
> [   24.184522] softirqs last  enabled at (6524): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
> [   24.184675] softirqs last disabled at (6123): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
> [   24.184836] ---[ end trace 0000000000000000 ]---
> [   24.185177] ------------[ ftrace bug ]------------
> [   24.185310] ftrace failed to modify 
> [   24.185312] [<ffffffff81d416d4>] bpf_fentry_test3+0x4/0x20
> [   24.185544]  actual:   e8:27:29:6c:3e
> [   24.185627]  expected: e8:a7:49:54:ff
> [   24.185717] ftrace record flags: e8180000
> [   24.185798]  (0) R   tramp: ERROR!
> [   24.185798]  expected tramp: ffffffffc0404000
> [   24.185975] ------------[ cut here ]------------
> [   24.186086] WARNING: kernel/trace/ftrace.c:2254 at ftrace_bug+0x101/0x290, CPU#13: kworker/13:6/873
> [   24.186285] Modules linked in: bpf_test_modorder_y(OE+) bpf_test_modorder_x(OE) bpf_testmod(OE)
> [   24.186484] CPU: 13 UID: 0 PID: 873 Comm: kworker/13:6 Tainted: G        W  OE       7.0.0-rc1-gda78c0a81eea #83 PREEMPT(full) 
> [   24.186728] Tainted: [W]=WARN, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
> [   24.186863] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-5.el9 11/05/2023
> [   24.187057] Workqueue: events bpf_link_put_deferred
> [   24.187172] RIP: 0010:ftrace_bug+0x101/0x290
> [   24.187294] Code: 05 72 03 83 f8 02 7f 13 83 f8 01 74 46 83 f8 02 75 13 48 c7 c7 41 a3 69 82 eb 51 83 f8 03 74 3c 83 f8 04 74 40 48 85 db 75 4c <0f> 0b c6 05 
> ba eb 2b 02 01 c7 05 ac eb 2b 02 00 00 00 00 48 c7 05
> [   24.187663] RSP: 0018:ffa0000504cafb70 EFLAGS: 00010246
> [   24.187772] RAX: 0000000000000022 RBX: ff110001000e48d0 RCX: e5ff63967b168c00
> [   24.187934] RDX: 0000000000000000 RSI: 00000000fffeffff RDI: ffffffff83018490
> [   24.188096] RBP: 00000000ffffffea R08: 000000000000ffff R09: ffffffff82e98430
> [   24.188267] R10: 000000000002fffd R11: 00000000fffeffff R12: ff110001000e48d0
> [   24.188423] R13: ffffffff83ec0f2d R14: ffffffff81d416d4 R15: ffffffff836e1cb0
> [   24.188581] FS:  0000000000000000(0000) GS:ff1100203becc000(0000) knlGS:0000000000000000
> [   24.188738] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [   24.188870] CR2: 00007f615e966270 CR3: 000000010bd9d005 CR4: 0000000000771ef0
> [   24.189032] PKRU: 55555554
> [   24.189088] Call Trace:
> [   24.189144]  <TASK>
> [   24.189204]  ftrace_replace_code+0x1d6/0x210
> [   24.189335]  ftrace_modify_all_code+0x59/0x110
> [   24.189443]  __ftrace_hash_move_and_update_ops+0x227/0x2c0
> [   24.189554]  ? kfree+0x1ac/0x4c0
> [   24.189638]  ? srso_return_thunk+0x5/0x5f
> [   24.189720]  ? kfree+0x250/0x4c0
> [   24.189802]  ? kfree+0x1ac/0x4c0
> [   24.189889]  ? bpf_lsm_sk_alloc_security+0x4/0x20
> [   24.190010]  ftrace_update_ops+0x40/0x80
> [   24.190095]  update_ftrace_direct_del+0x263/0x290
> [   24.190205]  ? bpf_lsm_sk_alloc_security+0x4/0x20                                                                                         21:11:28 [312/10854]
> [   24.190335]  ? 0xffffffffc0006a80
> [   24.190422]  bpf_trampoline_update+0x1fb/0x810
> [   24.190542]  bpf_trampoline_unlink_prog+0x103/0x1a0
> [   24.190651]  ? process_scheduled_works+0x271/0x640
> [   24.190764]  bpf_shim_tramp_link_release+0x20/0x40
> [   24.190871]  bpf_link_free+0x54/0xd0
> [   24.190964]  process_scheduled_works+0x2c2/0x640
> [   24.191093]  worker_thread+0x22a/0x340
> [   24.191177]  ? srso_return_thunk+0x5/0x5f
> [   24.191274]  ? __pfx_worker_thread+0x10/0x10
> [   24.191388]  kthread+0x10c/0x140
> [   24.191478]  ? __pfx_kthread+0x10/0x10
> [   24.191565]  ret_from_fork+0x148/0x290
> [   24.191641]  ? __pfx_kthread+0x10/0x10
> [   24.191729]  ret_from_fork_asm+0x1a/0x30
> [   24.191833]  </TASK>
> [   24.191896] irq event stamp: 8043
> [   24.191979] hardirqs last  enabled at (8051): [<ffffffff8136008c>] __console_unlock+0x5c/0x70
> [   24.192167] hardirqs last disabled at (8058): [<ffffffff81360071>] __console_unlock+0x41/0x70
> [   24.192368] softirqs last  enabled at (7828): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
> [   24.192528] softirqs last disabled at (7817): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
> [   24.192689] ---[ end trace 0000000000000000 ]---
> [   24.193549] ------------[ cut here ]------------
> [   24.193773] WARNING: kernel/trace/ftrace.c:2709 at ftrace_get_addr_curr+0x6c/0x190, CPU#10: test_progs/311
> [   24.193973] Modules linked in: bpf_test_modorder_y(OE+) bpf_test_modorder_x(OE) bpf_testmod(OE)
> [   24.194206] CPU: 10 UID: 0 PID: 311 Comm: test_progs Tainted: G        W  OE       7.0.0-rc1-gda78c0a81eea #83 PREEMPT(full) 
> [   24.194461] Tainted: [W]=WARN, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
> [   24.194594] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-5.el9 11/05/2023
> [   24.194778] RIP: 0010:ftrace_get_addr_curr+0x6c/0x190
> [   24.194891] Code: 48 0f 44 ce 4c 8b 3c c8 e8 e1 b4 c1 00 4d 85 ff 74 18 4d 39 77 10 74 05 4d 8b 3f eb eb 49 8b 47 18 48 85 c0 0f 85 19 01 00 00 <0f> 0b 48 8b 
> 43 08 a9 00 00 00 08 75 1c a9 00 00 00 20 48 c7 c1 80
> [   24.195270] RSP: 0018:ffa0000000d4bb38 EFLAGS: 00010246
> [   24.195381] RAX: 0000000000000001 RBX: ff11000100125710 RCX: ff1100010b28a2c0
> [   24.195540] RDX: 0000000000000003 RSI: 0000000000000003 RDI: ff11000100125710
> [   24.195698] RBP: 0000000000000001 R08: 0000000080000000 R09: ffffffffffffffff
> [   24.195863] R10: ffffffff82046a38 R11: 0000000000000000 R12: ff11000100125710
> [   24.196033] R13: ffffffff81529fc4 R14: ffffffff81529fc4 R15: 0000000000000000
> [   24.196199] FS:  00007f46532a54c0(0000) GS:ff1100203be0c000(0000) knlGS:0000000000000000
> [   24.196374] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [   24.196509] CR2: 000055e885be1470 CR3: 000000010eef9003 CR4: 0000000000771ef0
> [   24.196663] PKRU: 55555554
> [   24.196720] Call Trace:
> [   24.196778]  <TASK>
> [   24.196844]  ftrace_replace_code+0x7e/0x210
> [   24.196948]  ftrace_modify_all_code+0x59/0x110
> [   24.197059]  __ftrace_hash_move_and_update_ops+0x227/0x2c0
> [   24.197174]  ? srso_return_thunk+0x5/0x5f
> [   24.197271]  ? __mutex_lock+0x22a/0xc60
> [   24.197360]  ? kfree+0x1ac/0x4c0
> [   24.197455]  ? srso_return_thunk+0x5/0x5f
> [   24.197538]  ? kfree+0x250/0x4c0
> [   24.197626]  ? bpf_fentry_test3+0x4/0x20
> [   24.197712]  ftrace_set_hash+0x13c/0x3d0
> [   24.197811]  ftrace_set_filter_ip+0x88/0xb0
> [   24.197909]  ? bpf_fentry_test3+0x4/0x20                                                                                                  21:11:28 [257/10854]
> [   24.198000]  disarm_kprobe_ftrace+0x83/0xd0
> [   24.198089]  __disable_kprobe+0x129/0x160
> [   24.198178]  disable_kprobe+0x27/0x60
> [   24.198272]  kprobe_register+0xa2/0xe0
> [   24.198362]  perf_trace_event_unreg+0x33/0xd0
> [   24.198473]  perf_kprobe_destroy+0x3b/0x80
> [   24.198557]  __free_event+0x119/0x290
> [   24.198640]  perf_event_release_kernel+0x1ef/0x220
> [   24.198758]  perf_release+0x12/0x20
> [   24.198843]  __fput+0x11b/0x2a0
> [   24.198946]  task_work_run+0x8b/0xc0
> [   24.199035]  exit_to_user_mode_loop+0x107/0x4d0
> [   24.199155]  do_syscall_64+0x25b/0x390
> [   24.199249]  ? entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [   24.199360]  ? trace_irq_disable+0x1d/0xc0
> [   24.199451]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [   24.199559] RIP: 0033:0x7f46530ff85b
> [   24.199675] Code: 03 00 00 00 0f 05 48 3d 00 f0 ff ff 77 41 c3 48 83 ec 18 89 7c 24 0c e8 e3 83 f8 ff 8b 7c 24 0c 41 89 c0 b8 03 00 00 00 0f 05 <48> 3d 00 f0 
> ff ff 77 35 44 89 c7 89 44 24 0c e8 41 84 f8 ff 8b 44
> [   24.200034] RSP: 002b:00007ffc40859770 EFLAGS: 00000293 ORIG_RAX: 0000000000000003
> [   24.200192] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00007f46530ff85b
> [   24.200382] RDX: 0000000000000002 RSI: 0000000000000002 RDI: 0000000000000019
> [   24.200552] RBP: 00007ffc408597c0 R08: 0000000000000000 R09: 00007ffc40859757
> [   24.200702] R10: 0000000000000000 R11: 0000000000000293 R12: 00007ffc4085ddc8
> [   24.200855] R13: 000055e8800de120 R14: 000055e88118d390 R15: 00007f46533de000
> [   24.201035]  </TASK>
> [   24.201091] irq event stamp: 200379
> [   24.201208] hardirqs last  enabled at (200387): [<ffffffff8136008c>] __console_unlock+0x5c/0x70
> [   24.201453] hardirqs last disabled at (200396): [<ffffffff81360071>] __console_unlock+0x41/0x70
> [   24.201667] softirqs last  enabled at (200336): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
> [   24.201890] softirqs last disabled at (200329): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
> [   24.202121] ---[ end trace 0000000000000000 ]---
> [   24.202398] ------------[ cut here ]------------
> [   24.202534] WARNING: kernel/trace/ftrace.c:2715 at ftrace_get_addr_curr+0x149/0x190, CPU#10: test_progs/311
> [   24.202753] Modules linked in: bpf_test_modorder_y(OE+) bpf_test_modorder_x(OE) bpf_testmod(OE)
> [   24.202962] CPU: 10 UID: 0 PID: 311 Comm: test_progs Tainted: G        W  OE       7.0.0-rc1-gda78c0a81eea #83 PREEMPT(full) 
> [   24.203203] Tainted: [W]=WARN, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
> [   24.203344] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-5.el9 11/05/2023
> [   24.203526] RIP: 0010:ftrace_get_addr_curr+0x149/0x190
> [   24.203629] Code: 00 4c 89 f7 e8 88 f8 ff ff 84 c0 75 92 4d 8b 7f 08 e8 fb b3 c1 00 4d 85 ff 0f 94 c0 49 81 ff b0 1c 6e 83 0f 94 c1 08 c1 74 96 <0f> 0b c6 05 
> 62 e8 2b 02 01 c7 05 54 e8 2b 02 00 00 00 00 48 c7 05
> [   24.203996] RSP: 0018:ffa0000000d4bb38 EFLAGS: 00010202
> [   24.204110] RAX: 0000000000000000 RBX: ff11000100125710 RCX: ff1100010b28a201
> [   24.204280] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffffffff81529fc4
> [   24.204437] RBP: 0000000000000001 R08: 0000000080000000 R09: ffffffffffffffff
> [   24.204595] R10: ffffffff82046a38 R11: 0000000000000000 R12: ff11000100125710
> [   24.204755] R13: ffffffff81529fc4 R14: ffffffff81529fc4 R15: ffffffff836e1cb0
> [   24.204914] FS:  00007f46532a54c0(0000) GS:ff1100203be0c000(0000) knlGS:0000000000000000
> [   24.205072] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [   24.205204] CR2: 000055e885be1470 CR3: 000000010eef9003 CR4: 0000000000771ef0
> [   24.205386] PKRU: 55555554
> [   24.205443] Call Trace:
> [   24.205503]  <TASK>
> [   24.205565]  ftrace_replace_code+0x7e/0x210
> [   24.205669]  ftrace_modify_all_code+0x59/0x110                                                                                            21:11:28 [202/10854]
> [   24.205784]  __ftrace_hash_move_and_update_ops+0x227/0x2c0
> [   24.205902]  ? srso_return_thunk+0x5/0x5f
> [   24.205987]  ? __mutex_lock+0x22a/0xc60
> [   24.206072]  ? kfree+0x1ac/0x4c0
> [   24.206163]  ? srso_return_thunk+0x5/0x5f
> [   24.206254]  ? kfree+0x250/0x4c0
> [   24.206344]  ? bpf_fentry_test3+0x4/0x20
> [   24.206428]  ftrace_set_hash+0x13c/0x3d0
> [   24.206523]  ftrace_set_filter_ip+0x88/0xb0
> [   24.206614]  ? bpf_fentry_test3+0x4/0x20
> [   24.206703]  disarm_kprobe_ftrace+0x83/0xd0
> [   24.206789]  __disable_kprobe+0x129/0x160
> [   24.206880]  disable_kprobe+0x27/0x60
> [   24.206972]  kprobe_register+0xa2/0xe0
> [   24.207057]  perf_trace_event_unreg+0x33/0xd0
> [   24.207169]  perf_kprobe_destroy+0x3b/0x80
> [   24.207262]  __free_event+0x119/0x290
> [   24.207348]  perf_event_release_kernel+0x1ef/0x220
> [   24.207461]  perf_release+0x12/0x20
> [   24.207543]  __fput+0x11b/0x2a0
> [   24.207626]  task_work_run+0x8b/0xc0
> [   24.207711]  exit_to_user_mode_loop+0x107/0x4d0
> [   24.207827]  do_syscall_64+0x25b/0x390
> [   24.207915]  ? entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [   24.208021]  ? trace_irq_disable+0x1d/0xc0
> [   24.208110]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [   24.208215] RIP: 0033:0x7f46530ff85b
> [   24.208307] Code: 03 00 00 00 0f 05 48 3d 00 f0 ff ff 77 41 c3 48 83 ec 18 89 7c 24 0c e8 e3 83 f8 ff 8b 7c 24 0c 41 89 c0 b8 03 00 00 00 0f 05 <48> 3d 00 f0 
> ff ff 77 35 44 89 c7 89 44 24 0c e8 41 84 f8 ff 8b 44
> [   24.208657] RSP: 002b:00007ffc40859770 EFLAGS: 00000293 ORIG_RAX: 0000000000000003
> [   24.208816] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00007f46530ff85b
> [   24.208978] RDX: 0000000000000002 RSI: 0000000000000002 RDI: 0000000000000019
> [   24.209133] RBP: 00007ffc408597c0 R08: 0000000000000000 R09: 00007ffc40859757
> [   24.209300] R10: 0000000000000000 R11: 0000000000000293 R12: 00007ffc4085ddc8
> [   24.209457] R13: 000055e8800de120 R14: 000055e88118d390 R15: 00007f46533de000
> [   24.209633]  </TASK>
> [   24.209689] irq event stamp: 200963
> [   24.209770] hardirqs last  enabled at (200971): [<ffffffff8136008c>] __console_unlock+0x5c/0x70
> [   24.209971] hardirqs last disabled at (200978): [<ffffffff81360071>] __console_unlock+0x41/0x70
> [   24.210156] softirqs last  enabled at (200568): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
> [   24.210370] softirqs last disabled at (200557): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
> [   24.210554] ---[ end trace 0000000000000000 ]---
> [   24.210665] Bad trampoline accounting at: 00000000ab641fec (bpf_lsm_sk_alloc_security+0x4/0x20)
> [   24.210866] ------------[ cut here ]------------
> [   24.210993] WARNING: arch/x86/kernel/ftrace.c:105 at ftrace_replace_code+0xf7/0x210, CPU#10: test_progs/311
> [   24.211182] Modules linked in: bpf_test_modorder_y(OE+) bpf_test_modorder_x(OE) bpf_testmod(OE)
> [   24.211412] CPU: 10 UID: 0 PID: 311 Comm: test_progs Tainted: G        W  OE       7.0.0-rc1-gda78c0a81eea #83 PREEMPT(full) 
> [   24.211656] Tainted: [W]=WARN, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
> [   24.211788] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-5.el9 11/05/2023
> [   24.211980] RIP: 0010:ftrace_replace_code+0xf7/0x210
> [   24.212091] Code: c0 0f 85 ec 00 00 00 8b 44 24 03 41 33 45 00 0f b6 4c 24 07 41 32 4d 04 0f b6 c9 09 c1 0f 84 49 ff ff ff 4c 89 2d b9 df 8b 03 <0f> 0b bf ea 
> ff ff ff e9 c4 00 00 00 e8 f8 e5 19 00 48 85 c0 0f 84
> [   24.212503] RSP: 0018:ffa0000000d4bb58 EFLAGS: 00010202
> [   24.212628] RAX: 00000000780a0001 RBX: 0000000000000001 RCX: 00000000780a00c1
> [   24.212798] RDX: ffffffff81529000 RSI: 0000000000000005 RDI: ffffffff81529fc4
> [   24.212970] RBP: 0000000000000001 R08: 000000000000ffff R09: ffffffff82e98430
> [   24.213130] R10: 000000000002fffd R11: 00000000fffeffff R12: ff11000100125710
> [   24.213317] R13: ffffffff83ec0f2d R14: ffffffff84b43820 R15: ffa0000000d4bb5b
> [   24.213488] FS:  00007f46532a54c0(0000) GS:ff1100203be0c000(0000) knlGS:0000000000000000
> [   24.213674] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [   24.213813] CR2: 000055e885be1470 CR3: 000000010eef9003 CR4: 0000000000771ef0
> [   24.213986] PKRU: 55555554
> [   24.214044] Call Trace:
> [   24.214100]  <TASK>
> [   24.214167]  ftrace_modify_all_code+0x59/0x110
> [   24.214301]  __ftrace_hash_move_and_update_ops+0x227/0x2c0
> [   24.214415]  ? srso_return_thunk+0x5/0x5f
> [   24.214502]  ? __mutex_lock+0x22a/0xc60
> [   24.214588]  ? kfree+0x1ac/0x4c0
> [   24.214682]  ? srso_return_thunk+0x5/0x5f
> [   24.214765]  ? kfree+0x250/0x4c0
> [   24.214855]  ? bpf_fentry_test3+0x4/0x20
> [   24.214943]  ftrace_set_hash+0x13c/0x3d0
> [   24.215041]  ftrace_set_filter_ip+0x88/0xb0
> [   24.215132]  ? bpf_fentry_test3+0x4/0x20
> [   24.215221]  disarm_kprobe_ftrace+0x83/0xd0
> [   24.215328]  __disable_kprobe+0x129/0x160
> [   24.215418]  disable_kprobe+0x27/0x60
> [   24.215507]  kprobe_register+0xa2/0xe0
> [   24.215594]  perf_trace_event_unreg+0x33/0xd0
> [   24.215701]  perf_kprobe_destroy+0x3b/0x80
> [   24.215790]  __free_event+0x119/0x290
> [   24.215888]  perf_event_release_kernel+0x1ef/0x220
> [   24.216007]  perf_release+0x12/0x20
> [   24.216091]  __fput+0x11b/0x2a0
> [   24.216183]  task_work_run+0x8b/0xc0
> [   24.216293]  exit_to_user_mode_loop+0x107/0x4d0
> [   24.216411]  do_syscall_64+0x25b/0x390
> [   24.216497]  ? entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [   24.216606]  ? trace_irq_disable+0x1d/0xc0
> [   24.216699]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [   24.216807] RIP: 0033:0x7f46530ff85b
> [   24.216895] Code: 03 00 00 00 0f 05 48 3d 00 f0 ff ff 77 41 c3 48 83 ec 18 89 7c 24 0c e8 e3 83 f8 ff 8b 7c 24 0c 41 89 c0 b8 03 00 00 00 0f 05 <48> 3d 00 f0 
> ff ff 77 35 44 89 c7 89 44 24 0c e8 41 84 f8 ff 8b 44
> [   24.217293] RSP: 002b:00007ffc40859770 EFLAGS: 00000293 ORIG_RAX: 0000000000000003
> [   24.217461] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00007f46530ff85b
> [   24.217627] RDX: 0000000000000002 RSI: 0000000000000002 RDI: 0000000000000019
> [   24.217785] RBP: 00007ffc408597c0 R08: 0000000000000000 R09: 00007ffc40859757
> [   24.217950] R10: 0000000000000000 R11: 0000000000000293 R12: 00007ffc4085ddc8
> [   24.218107] R13: 000055e8800de120 R14: 000055e88118d390 R15: 00007f46533de000
> [   24.218306]  </TASK>
> [   24.218363] irq event stamp: 201623
> [   24.218445] hardirqs last  enabled at (201631): [<ffffffff8136008c>] __console_unlock+0x5c/0x70
> [   24.218625] hardirqs last disabled at (201638): [<ffffffff81360071>] __console_unlock+0x41/0x70
> [   24.218810] softirqs last  enabled at (201612): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
> [   24.219012] softirqs last disabled at (201601): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
> [   24.219208] ---[ end trace 0000000000000000 ]---
> [   24.219693] ------------[ ftrace bug ]------------
> [   24.219801] ftrace failed to modify 
> [   24.219804] [<ffffffff81529fc4>] bpf_lsm_sk_alloc_security+0x4/0x20
> [   24.220022]  actual:   e9:b7:ca:ad:3e
> [   24.220113]  expected: e8:b7:c0:d5:ff
> [   24.220203] ftrace record flags: e8980000
> [   24.220307]  (0) R   tramp: ERROR!
> [   24.220321] ------------[ cut here ]------------
> [   24.220507] WARNING: kernel/trace/ftrace.c:2715 at ftrace_get_addr_curr+0x149/0x190, CPU#10: test_progs/311
> [   24.220693] Modules linked in: bpf_test_modorder_y(OE+) bpf_test_modorder_x(OE) bpf_testmod(OE)
> [   24.220895] CPU: 10 UID: 0 PID: 311 Comm: test_progs Tainted: G        W  OE       7.0.0-rc1-gda78c0a81eea #83 PREEMPT(full) 
> [   24.221135] Tainted: [W]=WARN, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
> [   24.221284] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-5.el9 11/05/2023
> [   24.221467] RIP: 0010:ftrace_get_addr_curr+0x149/0x190
> [   24.221577] Code: 00 4c 89 f7 e8 88 f8 ff ff 84 c0 75 92 4d 8b 7f 08 e8 fb b3 c1 00 4d 85 ff 0f 94 c0 49 81 ff b0 1c 6e 83 0f 94 c1 08 c1 74 96 <0f> 0b c6 05 
> 62 e8 2b 02 01 c7 05 54 e8 2b 02 00 00 00 00 48 c7 05
> [   24.221938] RSP: 0018:ffa0000000d4bb10 EFLAGS: 00010202
> [   24.222052] RAX: 0000000000000000 RBX: ff11000100125710 RCX: ff1100010b28a201
> [   24.222205] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffffffff81529fc4
> [   24.222384] RBP: 00000000ffffffea R08: 000000000000ffff R09: ffffffff82e98430
> [   24.222542] R10: 000000000002fffd R11: 00000000fffeffff R12: ff11000100125710
> [   24.222708] R13: ffffffff83ec0f2d R14: ffffffff81529fc4 R15: ffffffff836e1cb0
> [   24.222866] FS:  00007f46532a54c0(0000) GS:ff1100203be0c000(0000) knlGS:0000000000000000
> [   24.223034] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [   24.223171] CR2: 000055e885be1470 CR3: 000000010eef9003 CR4: 0000000000771ef0
> [   24.223341] PKRU: 55555554
> [   24.223397] Call Trace:
> [   24.223454]  <TASK>
> [   24.223511]  ? bpf_lsm_sk_alloc_security+0x4/0x20
> [   24.223623]  ftrace_bug+0x1ff/0x290
> [   24.223710]  ftrace_replace_code+0x1d6/0x210
> [   24.223829]  ftrace_modify_all_code+0x59/0x110
> [   24.223946]  __ftrace_hash_move_and_update_ops+0x227/0x2c0
> [   24.224060]  ? srso_return_thunk+0x5/0x5f
> [   24.224148]  ? __mutex_lock+0x22a/0xc60
> [   24.224245]  ? kfree+0x1ac/0x4c0
> [   24.224337]  ? srso_return_thunk+0x5/0x5f
> [   24.224420]  ? kfree+0x250/0x4c0
> [   24.224512]  ? bpf_fentry_test3+0x4/0x20
> [   24.224597]  ftrace_set_hash+0x13c/0x3d0
> [   24.224690]  ftrace_set_filter_ip+0x88/0xb0
> [   24.224776]  ? bpf_fentry_test3+0x4/0x20
> [   24.224869]  disarm_kprobe_ftrace+0x83/0xd0
> [   24.224965]  __disable_kprobe+0x129/0x160
> [   24.225051]  disable_kprobe+0x27/0x60
> [   24.225136]  kprobe_register+0xa2/0xe0
> [   24.225223]  perf_trace_event_unreg+0x33/0xd0
> [   24.225346]  perf_kprobe_destroy+0x3b/0x80
> [   24.225431]  __free_event+0x119/0x290
> [   24.225518]  perf_event_release_kernel+0x1ef/0x220
> [   24.225631]  perf_release+0x12/0x20
> [   24.225715]  __fput+0x11b/0x2a0
> [   24.225804]  task_work_run+0x8b/0xc0
> [   24.225895]  exit_to_user_mode_loop+0x107/0x4d0
> [   24.226016]  do_syscall_64+0x25b/0x390
> [   24.226099]  ? entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [   24.226207]  ? trace_irq_disable+0x1d/0xc0
> [   24.226308]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [   24.226415] RIP: 0033:0x7f46530ff85b
> [   24.226498] Code: 03 00 00 00 0f 05 48 3d 00 f0 ff ff 77 41 c3 48 83 ec 18 89 7c 24 0c e8 e3 83 f8 ff 8b 7c 24 0c 41 89 c0 b8 03 00 00 00 0f 05 <48> 3d 00 f0 
> ff ff 77 35 44 89 c7 89 44 24 0c e8 41 84 f8 ff 8b 44
> [   24.226851] RSP: 002b:00007ffc40859770 EFLAGS: 00000293 ORIG_RAX: 0000000000000003
> [   24.227016] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00007f46530ff85b
> [   24.227173] RDX: 0000000000000002 RSI: 0000000000000002 RDI: 0000000000000019
> [   24.227341] RBP: 00007ffc408597c0 R08: 0000000000000000 R09: 00007ffc40859757
> [   24.227500] R10: 0000000000000000 R11: 0000000000000293 R12: 00007ffc4085ddc8
> [   24.227652] R13: 000055e8800de120 R14: 000055e88118d390 R15: 00007f46533de000
> [   24.227830]  </TASK>
> [   24.227891] irq event stamp: 202299
> [   24.227974] hardirqs last  enabled at (202307): [<ffffffff8136008c>] __console_unlock+0x5c/0x70
> [   24.228162] hardirqs last disabled at (202314): [<ffffffff81360071>] __console_unlock+0x41/0x70
> [   24.228357] softirqs last  enabled at (201682): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
> [   24.228540] softirqs last disabled at (201671): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
> [   24.228716] ---[ end trace 0000000000000000 ]---
> [   24.228834] Bad trampoline accounting at: 00000000ab641fec (bpf_lsm_sk_alloc_security+0x4/0x20)
> [   24.229029] 
> [   24.229029]  expected tramp: ffffffff81286080
> [   24.261301] BUG: unable to handle page fault for address: ffa00000004b9050
> [   24.261436] #PF: supervisor read access in kernel mode
> [   24.261528] #PF: error_code(0x0000) - not-present page
> [   24.261621] PGD 100000067 P4D 100832067 PUD 100833067 PMD 100efb067 PTE 0
> [   24.261745] Oops: Oops: 0000 [#1] SMP NOPTI
> [   24.261821] CPU: 9 UID: 0 PID: 1338 Comm: ip Tainted: G        W  OE       7.0.0-rc1-gda78c0a81eea #83 PREEMPT(full) 
> [   24.262006] Tainted: [W]=WARN, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
> [   24.262119] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-5.el9 11/05/2023
> [   24.262281] RIP: 0010:__cgroup_bpf_run_lsm_current+0xc5/0x2f0
> [   24.262393] Code: a6 6f 1a 02 01 48 c7 c7 31 5b 71 82 be bf 01 00 00 48 c7 c2 d3 70 65 82 e8 d8 53 ce ff 4d 8b 7f 60 4d 85 ff 0f 84 14 02 00 00 <49> 8b 46 f0 
> 4c 63 b0 34 05 00 00 c7 44 24 10 00 00 00 00 41 0f b7
> [   24.262693] RSP: 0018:ffa0000004dfbc98 EFLAGS: 00010282
> [   24.262784] RAX: 0000000000000001 RBX: ffa0000004dfbd10 RCX: 0000000000000001
> [   24.262923] RDX: 00000000d7c4159d RSI: ffffffff8359b368 RDI: ff1100011b5c50c8
> [   24.263055] RBP: ffa0000004dfbd30 R08: 0000000000020000 R09: ffffffffffffffff
> [   24.263187] R10: ffffffff814f76b3 R11: 0000000000000000 R12: ff1100011b5c4580
> [   24.263325] R13: 0000000000000000 R14: ffa00000004b9060 R15: ffffffff835b3040
> [   24.263465] FS:  00007f0007064800(0000) GS:ff1100203bdcc000(0000) knlGS:0000000000000000
> [   24.263599] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [   24.263709] CR2: ffa00000004b9050 CR3: 0000000120f4d002 CR4: 0000000000771ef0
> [   24.263841] PKRU: 55555554
> [   24.263890] Call Trace:
> [   24.263938]  <TASK>
> [   24.263992]  bpf_trampoline_6442513766+0x6a/0x10d
> [   24.264088]  security_sk_alloc+0x83/0xd0
> [   24.264162]  sk_prot_alloc+0xf4/0x150
> [   24.264236]  sk_alloc+0x34/0x2a0
> [   24.264305]  ? srso_return_thunk+0x5/0x5f
> [   24.264375]  ? _raw_spin_unlock_irqrestore+0x35/0x50
> [   24.264465]  ? srso_return_thunk+0x5/0x5f
> [   24.264533]  ? __wake_up_common_lock+0xa8/0xd0
> [   24.264625]  __netlink_create+0x2f/0xf0
> [   24.264695]  netlink_create+0x1c4/0x230
> [   24.264765]  ? __pfx_rtnetlink_bind+0x10/0x10
> [   24.264858]  __sock_create+0x21d/0x400
> [   24.264937]  __sys_socket+0x65/0x100
> [   24.265007]  ? srso_return_thunk+0x5/0x5f
> [   24.265077]  __x64_sys_socket+0x19/0x30
> [   24.265146]  do_syscall_64+0xde/0x390
> [   24.265216]  ? entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [   24.265307]  ? trace_irq_disable+0x1d/0xc0
> [   24.265379]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [   24.265469] RIP: 0033:0x7f0006f112ab
> [   24.265538] Code: 73 01 c3 48 8b 0d 6d 8b 0e 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 29 00 00 00 0f 05 <48> 3d 01 f0 
> ff ff 73 01 c3 48 8b 0d 3d 8b 0e 00 f7 d8 64 89 01 48
> [   24.265822] RSP: 002b:00007ffd8ecb3be8 EFLAGS: 00000246 ORIG_RAX: 0000000000000029
> [   24.265960] RAX: ffffffffffffffda RBX: 000056212b30d040 RCX: 00007f0006f112ab
> [   24.266088] RDX: 0000000000000000 RSI: 0000000000080003 RDI: 0000000000000010
> [   24.266217] RBP: 0000000000000000 R08: 00007ffd8ecb3bc0 R09: 0000000000000000
> [   24.266346] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
> [   24.266474] R13: 000056212b30d040 R14: 00007ffd8ecb3d88 R15: 0000000000000004
> [   24.266617]  </TASK>
> [   24.266663] Modules linked in: bpf_test_modorder_y(OE+) bpf_test_modorder_x(OE) bpf_testmod(OE)
> [   24.266824] CR2: ffa00000004b9050
> [   24.266897] ---[ end trace 0000000000000000 ]---
> [   24.266989] RIP: 0010:__cgroup_bpf_run_lsm_current+0xc5/0x2f0
> [   24.267101] Code: a6 6f 1a 02 01 48 c7 c7 31 5b 71 82 be bf 01 00 00 48 c7 c2 d3 70 65 82 e8 d8 53 ce ff 4d 8b 7f 60 4d 85 ff 0f 84 14 02 00 00 <49> 8b 46 f0 
> 4c 63 b0 34 05 00 00 c7 44 24 10 00 00 00 00 41 0f b7
> [   24.267406] RSP: 0018:ffa0000004dfbc98 EFLAGS: 00010282
> [   24.267499] RAX: 0000000000000001 RBX: ffa0000004dfbd10 RCX: 0000000000000001
> [   24.267629] RDX: 00000000d7c4159d RSI: ffffffff8359b368 RDI: ff1100011b5c50c8
> [   24.267758] RBP: ffa0000004dfbd30 R08: 0000000000020000 R09: ffffffffffffffff
> [   24.267897] R10: ffffffff814f76b3 R11: 0000000000000000 R12: ff1100011b5c4580
> [   24.268030] R13: 0000000000000000 R14: ffa00000004b9060 R15: ffffffff835b3040
> [   24.268167] FS:  00007f0007064800(0000) GS:ff1100203bdcc000(0000) knlGS:0000000000000000
> [   24.268311] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [   24.268428] CR2: ffa00000004b9050 CR3: 0000000120f4d002 CR4: 0000000000771ef0
> [   24.268565] PKRU: 55555554
> [   24.268613] Kernel panic - not syncing: Fatal exception
> [   24.268977] Kernel Offset: disabled
> [   24.269046] ---[ end Kernel panic - not syncing: Fatal exception ]---
> 
> 
> 
> > ---
> >  arch/x86/Kconfig        |   1 +
> >  kernel/bpf/trampoline.c | 220 ++++++++++++++++++++++++++++++++++------
> >  kernel/trace/Kconfig    |   3 +
> >  kernel/trace/ftrace.c   |   7 +-
> >  4 files changed, 200 insertions(+), 31 deletions(-)
> > 
> > [...]

^ permalink raw reply

* Re: [PATCH v4 1/5] mm: introduce zone lock wrappers
From: David Hildenbrand (Arm) @ 2026-02-27 20:36 UTC (permalink / raw)
  To: Dmitry Ilvokhin, Andrew Morton, Lorenzo Stoakes, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Axel Rasmussen, Yuanchu Xie, Wei Xu, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, Rafael J. Wysocki,
	Pavel Machek, Len Brown, Brendan Jackman, Johannes Weiner, Zi Yan,
	Oscar Salvador, Qi Zheng, Shakeel Butt
  Cc: linux-kernel, linux-mm, linux-trace-kernel, linux-pm,
	"linux-cxl
In-Reply-To: <849dee9c47df1e6fba97c9933af0d5a08b8e15d3.1772206930.git.d@ilvokhin.com>

On 2/27/26 17:00, Dmitry Ilvokhin wrote:
> Add thin wrappers around zone lock acquire/release operations. This
> prepares the code for future tracepoint instrumentation without
> modifying individual call sites.
> 
> Centralizing zone lock operations behind wrappers allows future
> instrumentation or debugging hooks to be added without touching
> all users.
> 
> No functional change intended. The wrappers are introduced in
> preparation for subsequent patches and are not yet used.
> 
> Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
> Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
> ---

Acked-by: David Hildenbrand (Arm) <david@kernel.org>

-- 
Cheers,

David

^ permalink raw reply

* Re: [PATCH] tracefs: Simplify get_dname() with kmemdup_nul()
From: Al Viro @ 2026-02-27 20:18 UTC (permalink / raw)
  To: AnishMulay
  Cc: rostedt, mhiramat, mathieu.desnoyers, linux-trace-kernel,
	linux-kernel
In-Reply-To: <20260227194453.213095-1-anishm7030@gmail.com>

On Fri, Feb 27, 2026 at 02:44:53PM -0500, AnishMulay wrote:
> index d9d8932a7b9c9..86ba8dc25aaef 100644
> --- a/fs/tracefs/inode.c
> +++ b/fs/tracefs/inode.c
> @@ -96,17 +96,7 @@ static struct tracefs_dir_ops {
>  
>  static char *get_dname(struct dentry *dentry)
>  {
> -	const char *dname;
> -	char *name;
> -	int len = dentry->d_name.len;
> -
> -	dname = dentry->d_name.name;
> -	name = kmalloc(len + 1, GFP_KERNEL);
> -	if (!name)
> -		return NULL;
> -	memcpy(name, dname, len);
> -	name[len] = 0;
> -	return name;
> +	return kmemdup_nul(dentry->d_name.name, dentry->d_name.len, GFP_KERNEL);
>  }

Why not have the callers use {take,release}_dentry_name_snapshot()
instead of doing any allocations at all?

I mean,
static struct dentry *tracefs_syscall_mkdir(struct mnt_idmap *idmap,
                                            struct inode *inode, struct dentry *dentry,
                                            umode_t mode)
{
        struct tracefs_inode *ti;
        struct name_snapshot s;
        int ret;
 
        take_dentry_name_snapshot(&s, dentry);
	...
        ret = tracefs_ops.mkdir(s.name.name);
	release_dentry_name_snapshot(&s);
	...
}

and similar on the rmdir side.  Then remove get_dname()...

^ permalink raw reply

* Re: [PATCH v4 5/5] mm: add tracepoints for zone lock
From: Steven Rostedt @ 2026-02-27 19:46 UTC (permalink / raw)
  To: Dmitry Ilvokhin
  Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Axel Rasmussen, Yuanchu Xie,
	Wei Xu, Masami Hiramatsu, Mathieu Desnoyers, Rafael J. Wysocki,
	Pavel Machek, Len Brown, Brendan Jackman, Johannes Weiner, Zi Yan,
	Oscar Salvador, Qi Zheng, Shakeel Butt, linux-kernel, linux-mm,
	linux-trace-kernel, linux-pm, "linux-cxl
In-Reply-To: <ae145fe890f028409f727b4921904b547346fa0b.1772206930.git.d@ilvokhin.com>

On Fri, 27 Feb 2026 16:00:27 +0000
Dmitry Ilvokhin <d@ilvokhin.com> wrote:

>  static inline void zone_lock_init(struct zone *zone)
>  {
> @@ -12,26 +59,41 @@ static inline void zone_lock_init(struct zone *zone)
>  
>  #define zone_lock_irqsave(zone, flags)				\
>  do {								\
> +	bool success = true;					\
> +								\
> +	__zone_lock_trace_start_locking(zone);			\
>  	spin_lock_irqsave(&(zone)->_lock, flags);		\
> +	__zone_lock_trace_acquire_returned(zone, success);	\

Why the "success" variable and not just:

	__zone_lock_trace_acquire_returned(zone, true);

 ?


>  } while (0)
>  
>  #define zone_trylock_irqsave(zone, flags)			\
>  ({								\
> -	spin_trylock_irqsave(&(zone)->_lock, flags);		\
> +	bool success;						\
> +								\
> +	__zone_lock_trace_start_locking(zone);			\
> +	success = spin_trylock_irqsave(&(zone)->_lock, flags);	\
> +	__zone_lock_trace_acquire_returned(zone, success);	\
> +	success;						\
>  })
>  
>  static inline void zone_unlock_irqrestore(struct zone *zone, unsigned long flags)
>  {
> +	__zone_lock_trace_released(zone);
>  	spin_unlock_irqrestore(&zone->_lock, flags);
>  }
>  
>  static inline void zone_lock_irq(struct zone *zone)
>  {
> +	bool success = true;
> +
> +	__zone_lock_trace_start_locking(zone);
>  	spin_lock_irq(&zone->_lock);
> +	__zone_lock_trace_acquire_returned(zone, success);

Same here.

>  }
>  
>  static inline void zone_unlock_irq(struct zone *zone)
>  {
> +	__zone_lock_trace_released(zone);
>  	spin_unlock_irq(&zone->_lock);
>  }
>

-- Steve


^ permalink raw reply

* [PATCH] tracefs: Simplify get_dname() with kmemdup_nul()
From: AnishMulay @ 2026-02-27 19:44 UTC (permalink / raw)
  To: rostedt, mhiramat
  Cc: mathieu.desnoyers, linux-trace-kernel, linux-kernel, AnishMulay

In fs/tracefs/inode.c, get_dname() allocates a buffer with kmalloc()
to hold a dentry name, followed by a memcpy() and manual
null-termination.

Replace this open-coded pattern with the standard kmemdup_nul() helper.
Additionally, remove the now single-use local variables `dname` and
`len`. This simplifies the function to a single line, reducing visual
clutter and making the memory-safety intent immediately obvious without
changing any functional behavior.

Testing:
Booted a custom kernel natively in virtme-ng (ARM64). Triggered tracefs
inode and dentry allocation by creating and removing a custom directory
under a temporary tracefs mount. Verified that the instance is created
successfully and that no memory errors or warnings are emitted in dmesg.

Signed-off-by: AnishMulay <anishm7030@gmail.com>
---
 fs/tracefs/inode.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
index d9d8932a7b9c9..86ba8dc25aaef 100644
--- a/fs/tracefs/inode.c
+++ b/fs/tracefs/inode.c
@@ -96,17 +96,7 @@ static struct tracefs_dir_ops {
 
 static char *get_dname(struct dentry *dentry)
 {
-	const char *dname;
-	char *name;
-	int len = dentry->d_name.len;
-
-	dname = dentry->d_name.name;
-	name = kmalloc(len + 1, GFP_KERNEL);
-	if (!name)
-		return NULL;
-	memcpy(name, dname, len);
-	name[len] = 0;
-	return name;
+	return kmemdup_nul(dentry->d_name.name, dentry->d_name.len, GFP_KERNEL);
 }
 
 static struct dentry *tracefs_syscall_mkdir(struct mnt_idmap *idmap,
-- 
2.51.0


^ permalink raw reply related

* Re: [PATCH 00/61] vfs: change inode->i_ino from unsigned long to u64
From: Jeff Layton @ 2026-02-27 19:35 UTC (permalink / raw)
  To: Mathieu Desnoyers, Matthew Wilcox
  Cc: Alexander Viro, Christian Brauner, Jan Kara, Steven Rostedt,
	Masami Hiramatsu, Dan Williams, Eric Biggers,
	Theodore Y. Ts'o, Muchun Song, Oscar Salvador,
	David Hildenbrand, David Howells, Paulo Alcantara, Andreas Dilger,
	Jan Kara, Jaegeuk Kim, Chao Yu, Trond Myklebust, Anna Schumaker,
	Chuck Lever, NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey,
	Steve French, Ronnie Sahlberg, Shyam Prasad N, Bharath SM,
	Alexander Aring, Ryusuke Konishi, Viacheslav Dubeyko,
	Eric Van Hensbergen, Latchesar Ionkov, Dominique Martinet,
	Christian Schoenebeck, David Sterba, Marc Dionne, Ian Kent,
	Luis de Bethencourt, Salah Triki, Tigran A. Aivazian,
	Ilya Dryomov, Alex Markuze, Jan Harkes, coda, Nicolas Pitre,
	Tyler Hicks, Amir Goldstein, Christoph Hellwig,
	John Paul Adrian Glaubitz, Yangtao Li, Mikulas Patocka,
	David Woodhouse, Richard Weinberger, Dave Kleikamp,
	Konstantin Komarov, Mark Fasheh, Joel Becker, Joseph Qi,
	Mike Marshall, Martin Brandenburg, Miklos Szeredi, Anders Larsen,
	Zhihao Cheng, Damien Le Moal, Naohiro Aota, Johannes Thumshirn,
	John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
	Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg, Fan Wu,
	Stephen Smalley, Ondrej Mosnacek, Casey Schaufler, Alex Deucher,
	Christian König, David Airlie, Simona Vetter, Sumit Semwal,
	Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
	David S. Miller, Jakub Kicinski, Simon Horman, Oleg Nesterov,
	Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Ian Rogers, Adrian Hunter, James Clark, Darrick J. Wong,
	Martin Schiller, linux-fsdevel, linux-kernel, linux-trace-kernel,
	nvdimm, fsverity, linux-mm, netfs, linux-ext4, linux-f2fs-devel,
	linux-nfs, linux-cifs, samba-technical, linux-nilfs, v9fs,
	linux-afs, autofs, ceph-devel, codalist, ecryptfs, linux-mtd,
	jfs-discussion, ntfs3, ocfs2-devel, devel, linux-unionfs,
	apparmor, linux-security-module, linux-integrity, selinux,
	amd-gfx, dri-devel, linux-media, linaro-mm-sig, netdev,
	linux-perf-users, linux-fscrypt, linux-xfs, linux-hams, linux-x25
In-Reply-To: <b808e186-3eeb-46ed-9826-b0ae6cdcdb8b@efficios.com>

On Fri, 2026-02-27 at 14:01 -0500, Mathieu Desnoyers wrote:
> On 2026-02-27 12:19, Jeff Layton wrote:
> > On Thu, 2026-02-26 at 16:49 +0000, Matthew Wilcox wrote:
> > > On Thu, Feb 26, 2026 at 10:55:02AM -0500, Jeff Layton wrote:
> > > > The bulk of the changes are to format strings and tracepoints, since the
> > > > kernel itself doesn't care that much about the i_ino field. The first
> > > > patch changes some vfs function arguments, so check that one out
> > > > carefully.
> > > 
> > > Why are the format strings all done as separate patches?  Don't we get
> > > bisection hazards by splitting it apart this way?
> > 
> > Circling back to this...
> > 
> > I have a v2 series (~107 patches) that I'm testing now that does this
> > more bisectably with the typedef and macro scaffolding that Mathieu
> > suggested. I'll probably send it early next week.
> > 
> > I had done it this way originally since I figured it was best to break
> > this up by subsystem. Should I continue with this series as a set of
> > patches broken up this way, or is it preferable to combine the pile of
> > format changes into fewer patches?
> 
> Here is the approach I would recommend to maximize signal over noise
> for the follow up email thread discussions:
> 
> Now that your series is bisectable, you could post a [RFC PATCH v2]
> series with the following:
> 
> - Patch 00 introduces the series, points to your git branch implementing
>    the whole series,
> - The first few patches introduce the new type (kino_t) and macro to
>    do the format string transition. Initially kino_t would typedef to
>    unsigned long (no changes).
> - Followed by patches implementing the type + format string changes for
>    a few key subsystems.
> - The final patch would change kino_t and the format string macro to
>    64-bit integers.
> 

That's pretty much the approach the set I have takes. The current set
is here:

    https://git.kernel.org/pub/scm/linux/kernel/git/jlayton/linux.git/log/?h=iino-u64

My question was more about whether I should batch some of the changes
together. My inclination is that doing it in small, incremental patches
is a good thing, but I figured I'd ask before I spam everyone with a
100+ patch series.

> Once everyone agree on those core changes, you could proceed to post
> patches that change additional subsystems in a subsequent round.
> 
> One more comment: have you tried using Coccinelle to do this kind of
> semantic code change ?

I've use coccinelle before for this sort of change, but my skills with
it are pretty primitive. The problem I saw with using it here is that
the main set of changes involved format strings, and that didn't look
straightforward to do with coccinelle. The LLM seems to have sorted it
out with no trouble though.

On a related note, has anyone has taught an LLM how to use Coccinelle.
I wonder if it might give it a better tool for its toolbox, since
Claude at least seems to mostly use bash, perl or python to make
changes across the tree.
-- 
Jeff Layton <jlayton@kernel.org>

^ permalink raw reply

* Re: [PATCH] blktrace: fix __this_cpu_read/write in preemptible context
From: Steven Rostedt @ 2026-02-27 19:19 UTC (permalink / raw)
  To: Chaitanya Kulkarni
  Cc: axboe, mhiramat, mathieu.desnoyers, shinichiro.kawasaki,
	linux-block, linux-trace-kernel
In-Reply-To: <20260227050303.10945-1-kch@nvidia.com>

On Thu, 26 Feb 2026 21:03:03 -0800
Chaitanya Kulkarni <kch@nvidia.com> wrote:

> diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
> index 3b7c102a6eb3..488552036583 100644
> --- a/kernel/trace/blktrace.c
> +++ b/kernel/trace/blktrace.c
> @@ -383,7 +383,9 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
>  	cpu = raw_smp_processor_id();
>  
>  	if (blk_tracer) {
> +		preempt_disable_notrace();
>  		tracing_record_cmdline(current);
> +		preempt_enable_notrace();
>  
>  		buffer = blk_tr->array_buffer.buffer;
>  		trace_ctx = tracing_gen_ctx_flags(0);

Do you know when this started? rcu_read_lock() doesn't disable preemption
in PREEMPT environments, and hasn't for a very long time. I'm surprised it
took this long to detect this? Perhaps this was a bug from day one?

Anyway, the tracing_record_cmdline() is to update the COMM cache so that
the trace has way to show the task->comm based on the saved PID in the
trace. It sets a flag to record the COMM from the sched_switch event if a
trace event happened. It's not needed if no trace event occurred. That
means, instead of adding preempt_disable() here, just move it after the
ring buffer event is reserved, as that means preemption is disabled until
the event is committed.

i.e.

diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index e6988929ead2..3735cbc1f99f 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -383,8 +383,6 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
 	cpu = raw_smp_processor_id();
 
 	if (blk_tracer) {
-		tracing_record_cmdline(current);
-
 		buffer = blk_tr->array_buffer.buffer;
 		trace_ctx = tracing_gen_ctx_flags(0);
 		switch (bt->version) {
@@ -419,6 +417,8 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
 		if (!event)
 			return;
 
+		tracing_record_cmdline(current);
+
 		switch (bt->version) {
 		case 1:
 			record_blktrace_event(ring_buffer_event_data(event),

-- Steve

^ permalink raw reply related

* Re: [PATCH 00/61] vfs: change inode->i_ino from unsigned long to u64
From: Mathieu Desnoyers @ 2026-02-27 19:01 UTC (permalink / raw)
  To: Jeff Layton, Matthew Wilcox
  Cc: Alexander Viro, Christian Brauner, Jan Kara, Steven Rostedt,
	Masami Hiramatsu, Dan Williams, Eric Biggers,
	Theodore Y. Ts'o, Muchun Song, Oscar Salvador,
	David Hildenbrand, David Howells, Paulo Alcantara, Andreas Dilger,
	Jan Kara, Jaegeuk Kim, Chao Yu, Trond Myklebust, Anna Schumaker,
	Chuck Lever, NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey,
	Steve French, Ronnie Sahlberg, Shyam Prasad N, Bharath SM,
	Alexander Aring, Ryusuke Konishi, Viacheslav Dubeyko,
	Eric Van Hensbergen, Latchesar Ionkov, Dominique Martinet,
	Christian Schoenebeck, David Sterba, Marc Dionne, Ian Kent,
	Luis de Bethencourt, Salah Triki, Tigran A. Aivazian,
	Ilya Dryomov, Alex Markuze, Jan Harkes, coda, Nicolas Pitre,
	Tyler Hicks, Amir Goldstein, Christoph Hellwig,
	John Paul Adrian Glaubitz, Yangtao Li, Mikulas Patocka,
	David Woodhouse, Richard Weinberger, Dave Kleikamp,
	Konstantin Komarov, Mark Fasheh, Joel Becker, Joseph Qi,
	Mike Marshall, Martin Brandenburg, Miklos Szeredi, Anders Larsen,
	Zhihao Cheng, Damien Le Moal, Naohiro Aota, Johannes Thumshirn,
	John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
	Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg, Fan Wu,
	Stephen Smalley, Ondrej Mosnacek, Casey Schaufler, Alex Deucher,
	Christian König, David Airlie, Simona Vetter, Sumit Semwal,
	Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
	David S. Miller, Jakub Kicinski, Simon Horman, Oleg Nesterov,
	Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Ian Rogers, Adrian Hunter, James Clark, Darrick J. Wong,
	Martin Schiller, linux-fsdevel, linux-kernel, linux-trace-kernel,
	nvdimm, fsverity, linux-mm, netfs, linux-ext4, linux-f2fs-devel,
	linux-nfs, linux-cifs, samba-technical, linux-nilfs, v9fs,
	linux-afs, autofs, ceph-devel, codalist, ecryptfs, linux-mtd,
	jfs-discussion, ntfs3, ocfs2-devel, devel, linux-unionfs,
	apparmor, linux-security-module, linux-integrity, selinux,
	amd-gfx, dri-devel, linux-media, linaro-mm-sig, netdev,
	linux-perf-users, linux-fscrypt, linux-xfs, linux-hams, linux-x25
In-Reply-To: <4a462d40899698586c110add96ce3fab6ddac30b.camel@kernel.org>

On 2026-02-27 12:19, Jeff Layton wrote:
> On Thu, 2026-02-26 at 16:49 +0000, Matthew Wilcox wrote:
>> On Thu, Feb 26, 2026 at 10:55:02AM -0500, Jeff Layton wrote:
>>> The bulk of the changes are to format strings and tracepoints, since the
>>> kernel itself doesn't care that much about the i_ino field. The first
>>> patch changes some vfs function arguments, so check that one out
>>> carefully.
>>
>> Why are the format strings all done as separate patches?  Don't we get
>> bisection hazards by splitting it apart this way?
> 
> Circling back to this...
> 
> I have a v2 series (~107 patches) that I'm testing now that does this
> more bisectably with the typedef and macro scaffolding that Mathieu
> suggested. I'll probably send it early next week.
> 
> I had done it this way originally since I figured it was best to break
> this up by subsystem. Should I continue with this series as a set of
> patches broken up this way, or is it preferable to combine the pile of
> format changes into fewer patches?

Here is the approach I would recommend to maximize signal over noise
for the follow up email thread discussions:

Now that your series is bisectable, you could post a [RFC PATCH v2]
series with the following:

- Patch 00 introduces the series, points to your git branch implementing
   the whole series,
- The first few patches introduce the new type (kino_t) and macro to
   do the format string transition. Initially kino_t would typedef to
   unsigned long (no changes).
- Followed by patches implementing the type + format string changes for
   a few key subsystems.
- The final patch would change kino_t and the format string macro to
   64-bit integers.

Once everyone agree on those core changes, you could proceed to post
patches that change additional subsystems in a subsequent round.

One more comment: have you tried using Coccinelle to do this kind of
semantic code change ?

Thanks,

Mathieu

-- 
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com

^ permalink raw reply

* Re: [PATCHv6 bpf-next 9/9] bpf,x86: Use single ftrace_ops for direct calls
From: Ihor Solodrai @ 2026-02-27 17:40 UTC (permalink / raw)
  To: Jiri Olsa, Steven Rostedt, Florent Revest, Mark Rutland
  Cc: bpf, linux-kernel, linux-trace-kernel, linux-arm-kernel,
	Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Menglong Dong, Song Liu, Kumar Kartikeya Dwivedi
In-Reply-To: <20251230145010.103439-10-jolsa@kernel.org>

On 12/30/25 6:50 AM, Jiri Olsa wrote:
> Using single ftrace_ops for direct calls update instead of allocating
> ftrace_ops object for each trampoline.
> 
> With single ftrace_ops object we can use update_ftrace_direct_* api
> that allows multiple ip sites updates on single ftrace_ops object.
> 
> Adding HAVE_SINGLE_FTRACE_DIRECT_OPS config option to be enabled on
> each arch that supports this.
> 
> At the moment we can enable this only on x86 arch, because arm relies
> on ftrace_ops object representing just single trampoline image (stored
> in ftrace_ops::direct_call). Archs that do not support this will continue
> to use *_ftrace_direct api.
> 
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>

Hi Jiri,

Me and Kumar stumbled on kernel splats with "ftrace failed to modify",
and if running with KASAN:

  BUG: KASAN: slab-use-after-free in __get_valid_kprobe+0x224/0x2a0

Pasting a full splat example at the bottom.

I was able to create a reproducer with AI, and then used it to bisect
to this patch. You can run it with ./test_progs -t ftrace_direct_race

Below is my (human-generated, haha) summary of AI's analysis of what's
happening. It makes sense to me conceptually, but I don't know enough
details here to call bullshit. Please take a look:

    With CONFIG_HAVE_SINGLE_FTRACE_DIRECT_OPS ftrace_replace_code()
    operates on all call sites in the shared ops. Then if a concurrent
    ftrace user (like kprobe) modifies a call site in between
    ftrace_replace_code's verify pass and its patch pass, then ftrace_bug
    fires and sets ftrace_disabled to 1.

    Once ftrace is disabled, direct_ops_del silently fails to unregister
    the direct call, and the call site still redirects to the stale
    trampoline. After the BPF program is freed, we'll get use-after-free
    on the next trace hit.

The reproducer is not great, because if everything is fine it just hangs.
But with the bug the kernel crashes pretty fast.
Maybe it makes sense to refine it to a proper "stress" selftest?

Reproducer patch:

From c595ef5a0ad9bc62d768080ff09502bc982c40e6 Mon Sep 17 00:00:00 2001
From: Ihor Solodrai <ihor.solodrai@linux.dev>
Date: Thu, 26 Feb 2026 17:00:39 -0800
Subject: [PATCH] reproducer

---
 .../bpf/prog_tests/ftrace_direct_race.c       | 243 ++++++++++++++++++
 1 file changed, 243 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/ftrace_direct_race.c

diff --git a/tools/testing/selftests/bpf/prog_tests/ftrace_direct_race.c b/tools/testing/selftests/bpf/prog_tests/ftrace_direct_race.c
new file mode 100644
index 000000000000..369c55364d05
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/ftrace_direct_race.c
@@ -0,0 +1,243 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */
+
+/* Test to reproduce ftrace race between BPF trampoline attach/detach
+ * and kprobe attach/detach on the same function.
+ *
+ * With CONFIG_HAVE_SINGLE_FTRACE_DIRECT_OPS, all BPF trampolines share
+ * a single ftrace_ops. Concurrent modifications (BPF trampoline vs kprobe)
+ * can race in ftrace_replace_code's verify-then-patch sequence, causing
+ * ftrace to become permanently disabled and leaving stale trampolines
+ * that reference freed BPF programs.
+ *
+ * Run with: ./test_progs -t ftrace_direct_race
+ */
+#include <test_progs.h>
+#include <bpf/libbpf.h>
+#include <pthread.h>
+#include <sys/ioctl.h>
+#include <linux/perf_event.h>
+#include <sys/syscall.h>
+
+#include "fentry_test.lskel.h"
+
+#define NUM_ITERATIONS	200
+
+static volatile bool stop;
+
+/* Thread 1: Rapidly attach and detach fentry BPF trampolines */
+static void *fentry_thread_fn(void *arg)
+{
+	int i;
+
+	for (i = 0; i < NUM_ITERATIONS && !stop; i++) {
+		struct fentry_test_lskel *skel;
+		int err;
+
+		skel = fentry_test_lskel__open();
+		if (!skel)
+			continue;
+
+		skel->keyring_id = KEY_SPEC_SESSION_KEYRING;
+		err = fentry_test_lskel__load(skel);
+		if (err) {
+			fentry_test_lskel__destroy(skel);
+			continue;
+		}
+
+		err = fentry_test_lskel__attach(skel);
+		if (err) {
+			fentry_test_lskel__destroy(skel);
+			continue;
+		}
+
+		/* Brief sleep to let the trampoline be live while kprobes race */
+		usleep(100 + rand() % 500);
+
+		fentry_test_lskel__detach(skel);
+		fentry_test_lskel__destroy(skel);
+	}
+
+	return NULL;
+}
+
+/* Thread 2: Rapidly create and destroy kprobes via tracefs on
+ * bpf_fentry_test* functions (the same functions the fentry thread targets).
+ * Creating/removing kprobe events goes through the ftrace code patching
+ * path that can race with BPF trampoline direct call operations.
+ */
+static void *kprobe_thread_fn(void *arg)
+{
+	const char *funcs[] = {
+		"bpf_fentry_test1",
+		"bpf_fentry_test2",
+		"bpf_fentry_test3",
+		"bpf_fentry_test4",
+		"bpf_fentry_test5",
+		"bpf_fentry_test6",
+	};
+	int i;
+
+	for (i = 0; i < NUM_ITERATIONS && !stop; i++) {
+		int j;
+
+		for (j = 0; j < 6 && !stop; j++) {
+			char cmd[256];
+
+			/* Create kprobe via tracefs */
+			snprintf(cmd, sizeof(cmd),
+				 "echo 'p:kprobe_race_%d %s' >> /sys/kernel/debug/tracing/kprobe_events 2>/dev/null",
+				 j, funcs[j]);
+			system(cmd);
+
+			/* Small delay */
+			usleep(50 + rand() % 200);
+
+			/* Remove kprobe */
+			snprintf(cmd, sizeof(cmd),
+				 "echo '-:kprobe_race_%d' >> /sys/kernel/debug/tracing/kprobe_events 2>/dev/null",
+				 j);
+			system(cmd);
+		}
+	}
+
+	return NULL;
+}
+
+/* Thread 3: Create kprobes via perf_event_open (the ftrace-based kind)
+ * which go through the arm_kprobe / disarm_kprobe ftrace path.
+ */
+static void *perf_kprobe_thread_fn(void *arg)
+{
+	const char *funcs[] = {
+		"bpf_fentry_test1",
+		"bpf_fentry_test2",
+		"bpf_fentry_test3",
+	};
+	int i;
+
+	for (i = 0; i < NUM_ITERATIONS && !stop; i++) {
+		int fds[3] = {-1, -1, -1};
+		int j;
+
+		for (j = 0; j < 3 && !stop; j++) {
+			struct perf_event_attr attr = {};
+			char path[256];
+			char buf[32];
+			char cmd[256];
+			int id_fd, id;
+
+			/* Create kprobe event */
+			snprintf(cmd, sizeof(cmd),
+				 "echo 'p:perf_race_%d %s' >> /sys/kernel/debug/tracing/kprobe_events 2>/dev/null",
+				 j, funcs[j]);
+			system(cmd);
+
+			/* Try to get the event id */
+			snprintf(path, sizeof(path),
+				 "/sys/kernel/debug/tracing/events/kprobes/perf_race_%d/id", j);
+			id_fd = open(path, O_RDONLY);
+			if (id_fd < 0)
+				continue;
+
+			memset(buf, 0, sizeof(buf));
+			if (read(id_fd, buf, sizeof(buf) - 1) > 0)
+				id = atoi(buf);
+			else
+				id = -1;
+			close(id_fd);
+
+			if (id < 0)
+				continue;
+
+			/* Open perf event to arm the kprobe via ftrace */
+			attr.type = PERF_TYPE_TRACEPOINT;
+			attr.size = sizeof(attr);
+			attr.config = id;
+			attr.sample_type = PERF_SAMPLE_RAW;
+			attr.sample_period = 1;
+			attr.wakeup_events = 1;
+
+			fds[j] = syscall(__NR_perf_event_open, &attr, -1, 0, -1, 0);
+			if (fds[j] >= 0)
+				ioctl(fds[j], PERF_EVENT_IOC_ENABLE, 0);
+		}
+
+		usleep(100 + rand() % 300);
+
+		/* Close perf events (disarms kprobes via ftrace) */
+		for (j = 0; j < 3; j++) {
+			char cmd[256];
+
+			if (fds[j] >= 0)
+				close(fds[j]);
+
+			snprintf(cmd, sizeof(cmd),
+				 "echo '-:perf_race_%d' >> /sys/kernel/debug/tracing/kprobe_events 2>/dev/null",
+				 j);
+			system(cmd);
+		}
+	}
+
+	return NULL;
+}
+
+void test_ftrace_direct_race(void)
+{
+	pthread_t fentry_tid, kprobe_tid, perf_kprobe_tid;
+	int err;
+
+	/* Check if ftrace is currently operational */
+	if (!ASSERT_OK(access("/sys/kernel/debug/tracing/kprobe_events", W_OK),
+		       "tracefs_access"))
+		return;
+
+	stop = false;
+
+	err = pthread_create(&fentry_tid, NULL, fentry_thread_fn, NULL);
+	if (!ASSERT_OK(err, "create_fentry_thread"))
+		return;
+
+	err = pthread_create(&kprobe_tid, NULL, kprobe_thread_fn, NULL);
+	if (!ASSERT_OK(err, "create_kprobe_thread")) {
+		stop = true;
+		pthread_join(fentry_tid, NULL);
+		return;
+	}
+
+	err = pthread_create(&perf_kprobe_tid, NULL, perf_kprobe_thread_fn, NULL);
+	if (!ASSERT_OK(err, "create_perf_kprobe_thread")) {
+		stop = true;
+		pthread_join(fentry_tid, NULL);
+		pthread_join(kprobe_tid, NULL);
+		return;
+	}
+
+	pthread_join(fentry_tid, NULL);
+	pthread_join(kprobe_tid, NULL);
+	pthread_join(perf_kprobe_tid, NULL);
+
+	/* If we get here without a kernel panic/oops, the test passed.
+	 * The real check is in dmesg: look for
+	 *   "WARNING: arch/x86/kernel/ftrace.c" or
+	 *   "BUG: KASAN: vmalloc-out-of-bounds in __bpf_prog_enter_recur"
+	 *
+	 * A more robust check: verify ftrace is still operational.
+	 */
+	ASSERT_OK(access("/sys/kernel/debug/tracing/kprobe_events", W_OK),
+		  "ftrace_still_operational");
+
+	/* Check that ftrace wasn't disabled */
+	{
+		char buf[64] = {};
+		int fd = open("/proc/sys/kernel/ftrace_enabled", O_RDONLY);
+
+		if (ASSERT_GE(fd, 0, "open_ftrace_enabled")) {
+			int n = read(fd, buf, sizeof(buf) - 1);
+
+			close(fd);
+			if (n > 0)
+				ASSERT_EQ(atoi(buf), 1, "ftrace_enabled");
+		}
+	}
+}
-- 
2.47.3


----

Splat:

[   24.170803] ------------[ cut here ]------------                                                                                                              
[   24.171055] WARNING: kernel/trace/ftrace.c:2715 at ftrace_get_addr_curr+0x149/0x190, CPU#13: kworker/13:6/873                                                 
[   24.171315] Modules linked in: bpf_test_modorder_y(OE+) bpf_test_modorder_x(OE) bpf_testmod(OE)                                                               
[   24.171561] CPU: 13 UID: 0 PID: 873 Comm: kworker/13:6 Tainted: G           OE       7.0.0-rc1-gda78c0a81eea #83 PREEMPT(full)                                
[   24.171827] Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE                                                                                                      
[   24.171941] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-5.el9 11/05/2023                                                               
[   24.172132] Workqueue: events bpf_link_put_deferred                                                                                                           
[   24.172261] RIP: 0010:ftrace_get_addr_curr+0x149/0x190                                                                                                        
[   24.172376] Code: 00 4c 89 f7 e8 88 f8 ff ff 84 c0 75 92 4d 8b 7f 08 e8 fb b3 c1 00 4d 85 ff 0f 94 c0 49 81 ff b0 1c 6e 83 0f 94 c1 08 c1 74 96 <0f> 0b c6 05 
62 e8 2b 02 01 c7 05 54 e8 2b 02 00 00 00 00 48 c7 05                                                                                                            
[   24.172745] RSP: 0018:ffa0000504cafb78 EFLAGS: 00010202                                                                                                       
[   24.172861] RAX: 0000000000000000 RBX: ff110001000e48d0 RCX: ff1100011cd3a201                                                                                 
[   24.173034] RDX: 6e21cb51d943709c RSI: 0000000000000000 RDI: ffffffff81d416d4                                                                                 
[   24.173194] RBP: 0000000000000001 R08: 0000000080000000 R09: ffffffffffffffff                                                                                 
[   24.173366] R10: ffffffff81285522 R11: 0000000000000000 R12: ff110001000e48d0                                                                                 
[   24.173530] R13: ffffffff81d416d4 R14: ffffffff81d416d4 R15: ffffffff836e1cb0                                                                                 
[   24.173691] FS:  0000000000000000(0000) GS:ff1100203becc000(0000) knlGS:0000000000000000                                                                      
[   24.173849] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033                                                                                                 
[   24.173995] CR2: 00007f615e966270 CR3: 000000010bd9d005 CR4: 0000000000771ef0                                                                                 
[   24.174155] PKRU: 55555554                                                                                                                                    
[   24.174214] Call Trace:                                                                                                                                       
[   24.174285]  <TASK>                                                                                                                                           
[   24.174348]  ftrace_replace_code+0x7e/0x210                                                                                                                   
[   24.174443]  ftrace_modify_all_code+0x59/0x110                                                                                                                
[   24.174553]  __ftrace_hash_move_and_update_ops+0x227/0x2c0                                                                                                    
[   24.174659]  ? kfree+0x1ac/0x4c0                                                                                                                              
[   24.174751]  ? srso_return_thunk+0x5/0x5f                                                                                                                     
[   24.174834]  ? kfree+0x250/0x4c0                                                                                                                              
[   24.174926]  ? kfree+0x1ac/0x4c0                                                                                                                              
[   24.175010]  ? bpf_lsm_sk_alloc_security+0x4/0x20                                                                                                             
[   24.175132]  ftrace_update_ops+0x40/0x80                                                                                                                      
[   24.175217]  update_ftrace_direct_del+0x263/0x290                                                                                                             
[   24.175341]  ? bpf_lsm_sk_alloc_security+0x4/0x20                                                                                                             
[   24.175456]  ? 0xffffffffc0006a80                                                                                                                             
[   24.175543]  bpf_trampoline_update+0x1fb/0x810                                                                                                                
[   24.175654]  bpf_trampoline_unlink_prog+0x103/0x1a0                                                                                                           
[   24.175767]  ? process_scheduled_works+0x271/0x640                                                                                                            
[   24.175886]  bpf_shim_tramp_link_release+0x20/0x40                                                                                                            
[   24.176001]  bpf_link_free+0x54/0xd0                                                                                                                          
[   24.176092]  process_scheduled_works+0x2c2/0x640                             
[   24.176222]  worker_thread+0x22a/0x340                                                                                                    21:11:27 [422/10854]
[   24.176319]  ? srso_return_thunk+0x5/0x5f
[   24.176405]  ? __pfx_worker_thread+0x10/0x10
[   24.176522]  kthread+0x10c/0x140
[   24.176611]  ? __pfx_kthread+0x10/0x10
[   24.176698]  ret_from_fork+0x148/0x290
[   24.176785]  ? __pfx_kthread+0x10/0x10
[   24.176872]  ret_from_fork_asm+0x1a/0x30
[   24.176985]  </TASK>
[   24.177043] irq event stamp: 6965
[   24.177126] hardirqs last  enabled at (6973): [<ffffffff8136008c>] __console_unlock+0x5c/0x70
[   24.177325] hardirqs last disabled at (6982): [<ffffffff81360071>] __console_unlock+0x41/0x70
[   24.177520] softirqs last  enabled at (6524): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
[   24.177675] softirqs last disabled at (6123): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
[   24.177844] ---[ end trace 0000000000000000 ]---
[   24.177963] Bad trampoline accounting at: 000000003143da54 (bpf_fentry_test3+0x4/0x20)
[   24.178134] ------------[ cut here ]------------
[   24.178261] WARNING: arch/x86/kernel/ftrace.c:105 at ftrace_replace_code+0xf7/0x210, CPU#13: kworker/13:6/873
[   24.178476] Modules linked in: bpf_test_modorder_y(OE+) bpf_test_modorder_x(OE) bpf_testmod(OE)
[   24.178680] CPU: 13 UID: 0 PID: 873 Comm: kworker/13:6 Tainted: G        W  OE       7.0.0-rc1-gda78c0a81eea #83 PREEMPT(full) 
[   24.178925] Tainted: [W]=WARN, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
[   24.179059] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-5.el9 11/05/2023
[   24.179258] Workqueue: events bpf_link_put_deferred
[   24.179374] RIP: 0010:ftrace_replace_code+0xf7/0x210
[   24.179485] Code: c0 0f 85 ec 00 00 00 8b 44 24 03 41 33 45 00 0f b6 4c 24 07 41 32 4d 04 0f b6 c9 09 c1 0f 84 49 ff ff ff 4c 89 2d b9 df 8b 03 <0f> 0b bf ea 
ff ff ff e9 c4 00 00 00 e8 f8 e5 19 00 48 85 c0 0f 84
[   24.179847] RSP: 0018:ffa0000504cafb98 EFLAGS: 00010202
[   24.179965] RAX: 0000000038608000 RBX: 0000000000000001 RCX: 00000000386080c1
[   24.180126] RDX: ffffffff81d41000 RSI: 0000000000000005 RDI: ffffffff81d416d4
[   24.180295] RBP: 0000000000000001 R08: 000000000000ffff R09: ffffffff82e98430
[   24.180455] R10: 000000000002fffd R11: 00000000fffeffff R12: ff110001000e48d0
[   24.180617] R13: ffffffff83ec0f2d R14: ffffffff84b43820 R15: ffa0000504cafb9b
[   24.180777] FS:  0000000000000000(0000) GS:ff1100203becc000(0000) knlGS:0000000000000000
[   24.180939] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   24.181077] CR2: 00007f615e966270 CR3: 000000010bd9d005 CR4: 0000000000771ef0
[   24.181247] PKRU: 55555554
[   24.181303] Call Trace:
[   24.181360]  <TASK>
[   24.181424]  ftrace_modify_all_code+0x59/0x110
[   24.181536]  __ftrace_hash_move_and_update_ops+0x227/0x2c0
[   24.181650]  ? kfree+0x1ac/0x4c0
[   24.181743]  ? srso_return_thunk+0x5/0x5f
[   24.181828]  ? kfree+0x250/0x4c0
[   24.181916]  ? kfree+0x1ac/0x4c0
[   24.182004]  ? bpf_lsm_sk_alloc_security+0x4/0x20
[   24.182123]  ftrace_update_ops+0x40/0x80
[   24.182213]  update_ftrace_direct_del+0x263/0x290
[   24.182337]  ? bpf_lsm_sk_alloc_security+0x4/0x20
[   24.182455]  ? 0xffffffffc0006a80
[   24.182543]  bpf_trampoline_update+0x1fb/0x810
[   24.182655]  bpf_trampoline_unlink_prog+0x103/0x1a0
[   24.182768]  ? process_scheduled_works+0x271/0x640
[   24.182887]  bpf_shim_tramp_link_release+0x20/0x40
[   24.183001]  bpf_link_free+0x54/0xd0
[   24.183088]  process_scheduled_works+0x2c2/0x640
[   24.183220]  worker_thread+0x22a/0x340                                                                                                    21:11:27 [367/10854]
[   24.183319]  ? srso_return_thunk+0x5/0x5f        
[   24.183405]  ? __pfx_worker_thread+0x10/0x10     
[   24.183521]  kthread+0x10c/0x140
[   24.183610]  ? __pfx_kthread+0x10/0x10
[   24.183697]  ret_from_fork+0x148/0x290
[   24.183783]  ? __pfx_kthread+0x10/0x10
[   24.183868]  ret_from_fork_asm+0x1a/0x30
[   24.183979]  </TASK>
[   24.184056] irq event stamp: 7447
[   24.184138] hardirqs last  enabled at (7455): [<ffffffff8136008c>] __console_unlock+0x5c/0x70
[   24.184339] hardirqs last disabled at (7464): [<ffffffff81360071>] __console_unlock+0x41/0x70
[   24.184522] softirqs last  enabled at (6524): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
[   24.184675] softirqs last disabled at (6123): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
[   24.184836] ---[ end trace 0000000000000000 ]---
[   24.185177] ------------[ ftrace bug ]------------
[   24.185310] ftrace failed to modify 
[   24.185312] [<ffffffff81d416d4>] bpf_fentry_test3+0x4/0x20
[   24.185544]  actual:   e8:27:29:6c:3e
[   24.185627]  expected: e8:a7:49:54:ff
[   24.185717] ftrace record flags: e8180000
[   24.185798]  (0) R   tramp: ERROR!
[   24.185798]  expected tramp: ffffffffc0404000
[   24.185975] ------------[ cut here ]------------
[   24.186086] WARNING: kernel/trace/ftrace.c:2254 at ftrace_bug+0x101/0x290, CPU#13: kworker/13:6/873
[   24.186285] Modules linked in: bpf_test_modorder_y(OE+) bpf_test_modorder_x(OE) bpf_testmod(OE)
[   24.186484] CPU: 13 UID: 0 PID: 873 Comm: kworker/13:6 Tainted: G        W  OE       7.0.0-rc1-gda78c0a81eea #83 PREEMPT(full) 
[   24.186728] Tainted: [W]=WARN, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
[   24.186863] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-5.el9 11/05/2023
[   24.187057] Workqueue: events bpf_link_put_deferred
[   24.187172] RIP: 0010:ftrace_bug+0x101/0x290
[   24.187294] Code: 05 72 03 83 f8 02 7f 13 83 f8 01 74 46 83 f8 02 75 13 48 c7 c7 41 a3 69 82 eb 51 83 f8 03 74 3c 83 f8 04 74 40 48 85 db 75 4c <0f> 0b c6 05 
ba eb 2b 02 01 c7 05 ac eb 2b 02 00 00 00 00 48 c7 05
[   24.187663] RSP: 0018:ffa0000504cafb70 EFLAGS: 00010246
[   24.187772] RAX: 0000000000000022 RBX: ff110001000e48d0 RCX: e5ff63967b168c00
[   24.187934] RDX: 0000000000000000 RSI: 00000000fffeffff RDI: ffffffff83018490
[   24.188096] RBP: 00000000ffffffea R08: 000000000000ffff R09: ffffffff82e98430
[   24.188267] R10: 000000000002fffd R11: 00000000fffeffff R12: ff110001000e48d0
[   24.188423] R13: ffffffff83ec0f2d R14: ffffffff81d416d4 R15: ffffffff836e1cb0
[   24.188581] FS:  0000000000000000(0000) GS:ff1100203becc000(0000) knlGS:0000000000000000
[   24.188738] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   24.188870] CR2: 00007f615e966270 CR3: 000000010bd9d005 CR4: 0000000000771ef0
[   24.189032] PKRU: 55555554
[   24.189088] Call Trace:
[   24.189144]  <TASK>
[   24.189204]  ftrace_replace_code+0x1d6/0x210
[   24.189335]  ftrace_modify_all_code+0x59/0x110
[   24.189443]  __ftrace_hash_move_and_update_ops+0x227/0x2c0
[   24.189554]  ? kfree+0x1ac/0x4c0
[   24.189638]  ? srso_return_thunk+0x5/0x5f
[   24.189720]  ? kfree+0x250/0x4c0
[   24.189802]  ? kfree+0x1ac/0x4c0
[   24.189889]  ? bpf_lsm_sk_alloc_security+0x4/0x20
[   24.190010]  ftrace_update_ops+0x40/0x80
[   24.190095]  update_ftrace_direct_del+0x263/0x290
[   24.190205]  ? bpf_lsm_sk_alloc_security+0x4/0x20                                                                                         21:11:28 [312/10854]
[   24.190335]  ? 0xffffffffc0006a80
[   24.190422]  bpf_trampoline_update+0x1fb/0x810
[   24.190542]  bpf_trampoline_unlink_prog+0x103/0x1a0
[   24.190651]  ? process_scheduled_works+0x271/0x640
[   24.190764]  bpf_shim_tramp_link_release+0x20/0x40
[   24.190871]  bpf_link_free+0x54/0xd0
[   24.190964]  process_scheduled_works+0x2c2/0x640
[   24.191093]  worker_thread+0x22a/0x340
[   24.191177]  ? srso_return_thunk+0x5/0x5f
[   24.191274]  ? __pfx_worker_thread+0x10/0x10
[   24.191388]  kthread+0x10c/0x140
[   24.191478]  ? __pfx_kthread+0x10/0x10
[   24.191565]  ret_from_fork+0x148/0x290
[   24.191641]  ? __pfx_kthread+0x10/0x10
[   24.191729]  ret_from_fork_asm+0x1a/0x30
[   24.191833]  </TASK>
[   24.191896] irq event stamp: 8043
[   24.191979] hardirqs last  enabled at (8051): [<ffffffff8136008c>] __console_unlock+0x5c/0x70
[   24.192167] hardirqs last disabled at (8058): [<ffffffff81360071>] __console_unlock+0x41/0x70
[   24.192368] softirqs last  enabled at (7828): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
[   24.192528] softirqs last disabled at (7817): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
[   24.192689] ---[ end trace 0000000000000000 ]---
[   24.193549] ------------[ cut here ]------------
[   24.193773] WARNING: kernel/trace/ftrace.c:2709 at ftrace_get_addr_curr+0x6c/0x190, CPU#10: test_progs/311
[   24.193973] Modules linked in: bpf_test_modorder_y(OE+) bpf_test_modorder_x(OE) bpf_testmod(OE)
[   24.194206] CPU: 10 UID: 0 PID: 311 Comm: test_progs Tainted: G        W  OE       7.0.0-rc1-gda78c0a81eea #83 PREEMPT(full) 
[   24.194461] Tainted: [W]=WARN, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
[   24.194594] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-5.el9 11/05/2023
[   24.194778] RIP: 0010:ftrace_get_addr_curr+0x6c/0x190
[   24.194891] Code: 48 0f 44 ce 4c 8b 3c c8 e8 e1 b4 c1 00 4d 85 ff 74 18 4d 39 77 10 74 05 4d 8b 3f eb eb 49 8b 47 18 48 85 c0 0f 85 19 01 00 00 <0f> 0b 48 8b 
43 08 a9 00 00 00 08 75 1c a9 00 00 00 20 48 c7 c1 80
[   24.195270] RSP: 0018:ffa0000000d4bb38 EFLAGS: 00010246
[   24.195381] RAX: 0000000000000001 RBX: ff11000100125710 RCX: ff1100010b28a2c0
[   24.195540] RDX: 0000000000000003 RSI: 0000000000000003 RDI: ff11000100125710
[   24.195698] RBP: 0000000000000001 R08: 0000000080000000 R09: ffffffffffffffff
[   24.195863] R10: ffffffff82046a38 R11: 0000000000000000 R12: ff11000100125710
[   24.196033] R13: ffffffff81529fc4 R14: ffffffff81529fc4 R15: 0000000000000000
[   24.196199] FS:  00007f46532a54c0(0000) GS:ff1100203be0c000(0000) knlGS:0000000000000000
[   24.196374] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   24.196509] CR2: 000055e885be1470 CR3: 000000010eef9003 CR4: 0000000000771ef0
[   24.196663] PKRU: 55555554
[   24.196720] Call Trace:
[   24.196778]  <TASK>
[   24.196844]  ftrace_replace_code+0x7e/0x210
[   24.196948]  ftrace_modify_all_code+0x59/0x110
[   24.197059]  __ftrace_hash_move_and_update_ops+0x227/0x2c0
[   24.197174]  ? srso_return_thunk+0x5/0x5f
[   24.197271]  ? __mutex_lock+0x22a/0xc60
[   24.197360]  ? kfree+0x1ac/0x4c0
[   24.197455]  ? srso_return_thunk+0x5/0x5f
[   24.197538]  ? kfree+0x250/0x4c0
[   24.197626]  ? bpf_fentry_test3+0x4/0x20
[   24.197712]  ftrace_set_hash+0x13c/0x3d0
[   24.197811]  ftrace_set_filter_ip+0x88/0xb0
[   24.197909]  ? bpf_fentry_test3+0x4/0x20                                                                                                  21:11:28 [257/10854]
[   24.198000]  disarm_kprobe_ftrace+0x83/0xd0
[   24.198089]  __disable_kprobe+0x129/0x160
[   24.198178]  disable_kprobe+0x27/0x60
[   24.198272]  kprobe_register+0xa2/0xe0
[   24.198362]  perf_trace_event_unreg+0x33/0xd0
[   24.198473]  perf_kprobe_destroy+0x3b/0x80
[   24.198557]  __free_event+0x119/0x290
[   24.198640]  perf_event_release_kernel+0x1ef/0x220
[   24.198758]  perf_release+0x12/0x20
[   24.198843]  __fput+0x11b/0x2a0
[   24.198946]  task_work_run+0x8b/0xc0
[   24.199035]  exit_to_user_mode_loop+0x107/0x4d0
[   24.199155]  do_syscall_64+0x25b/0x390
[   24.199249]  ? entry_SYSCALL_64_after_hwframe+0x76/0x7e
[   24.199360]  ? trace_irq_disable+0x1d/0xc0
[   24.199451]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[   24.199559] RIP: 0033:0x7f46530ff85b
[   24.199675] Code: 03 00 00 00 0f 05 48 3d 00 f0 ff ff 77 41 c3 48 83 ec 18 89 7c 24 0c e8 e3 83 f8 ff 8b 7c 24 0c 41 89 c0 b8 03 00 00 00 0f 05 <48> 3d 00 f0 
ff ff 77 35 44 89 c7 89 44 24 0c e8 41 84 f8 ff 8b 44
[   24.200034] RSP: 002b:00007ffc40859770 EFLAGS: 00000293 ORIG_RAX: 0000000000000003
[   24.200192] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00007f46530ff85b
[   24.200382] RDX: 0000000000000002 RSI: 0000000000000002 RDI: 0000000000000019
[   24.200552] RBP: 00007ffc408597c0 R08: 0000000000000000 R09: 00007ffc40859757
[   24.200702] R10: 0000000000000000 R11: 0000000000000293 R12: 00007ffc4085ddc8
[   24.200855] R13: 000055e8800de120 R14: 000055e88118d390 R15: 00007f46533de000
[   24.201035]  </TASK>
[   24.201091] irq event stamp: 200379
[   24.201208] hardirqs last  enabled at (200387): [<ffffffff8136008c>] __console_unlock+0x5c/0x70
[   24.201453] hardirqs last disabled at (200396): [<ffffffff81360071>] __console_unlock+0x41/0x70
[   24.201667] softirqs last  enabled at (200336): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
[   24.201890] softirqs last disabled at (200329): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
[   24.202121] ---[ end trace 0000000000000000 ]---
[   24.202398] ------------[ cut here ]------------
[   24.202534] WARNING: kernel/trace/ftrace.c:2715 at ftrace_get_addr_curr+0x149/0x190, CPU#10: test_progs/311
[   24.202753] Modules linked in: bpf_test_modorder_y(OE+) bpf_test_modorder_x(OE) bpf_testmod(OE)
[   24.202962] CPU: 10 UID: 0 PID: 311 Comm: test_progs Tainted: G        W  OE       7.0.0-rc1-gda78c0a81eea #83 PREEMPT(full) 
[   24.203203] Tainted: [W]=WARN, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
[   24.203344] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-5.el9 11/05/2023
[   24.203526] RIP: 0010:ftrace_get_addr_curr+0x149/0x190
[   24.203629] Code: 00 4c 89 f7 e8 88 f8 ff ff 84 c0 75 92 4d 8b 7f 08 e8 fb b3 c1 00 4d 85 ff 0f 94 c0 49 81 ff b0 1c 6e 83 0f 94 c1 08 c1 74 96 <0f> 0b c6 05 
62 e8 2b 02 01 c7 05 54 e8 2b 02 00 00 00 00 48 c7 05
[   24.203996] RSP: 0018:ffa0000000d4bb38 EFLAGS: 00010202
[   24.204110] RAX: 0000000000000000 RBX: ff11000100125710 RCX: ff1100010b28a201
[   24.204280] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffffffff81529fc4
[   24.204437] RBP: 0000000000000001 R08: 0000000080000000 R09: ffffffffffffffff
[   24.204595] R10: ffffffff82046a38 R11: 0000000000000000 R12: ff11000100125710
[   24.204755] R13: ffffffff81529fc4 R14: ffffffff81529fc4 R15: ffffffff836e1cb0
[   24.204914] FS:  00007f46532a54c0(0000) GS:ff1100203be0c000(0000) knlGS:0000000000000000
[   24.205072] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   24.205204] CR2: 000055e885be1470 CR3: 000000010eef9003 CR4: 0000000000771ef0
[   24.205386] PKRU: 55555554
[   24.205443] Call Trace:
[   24.205503]  <TASK>
[   24.205565]  ftrace_replace_code+0x7e/0x210
[   24.205669]  ftrace_modify_all_code+0x59/0x110                                                                                            21:11:28 [202/10854]
[   24.205784]  __ftrace_hash_move_and_update_ops+0x227/0x2c0
[   24.205902]  ? srso_return_thunk+0x5/0x5f
[   24.205987]  ? __mutex_lock+0x22a/0xc60
[   24.206072]  ? kfree+0x1ac/0x4c0
[   24.206163]  ? srso_return_thunk+0x5/0x5f
[   24.206254]  ? kfree+0x250/0x4c0
[   24.206344]  ? bpf_fentry_test3+0x4/0x20
[   24.206428]  ftrace_set_hash+0x13c/0x3d0
[   24.206523]  ftrace_set_filter_ip+0x88/0xb0
[   24.206614]  ? bpf_fentry_test3+0x4/0x20
[   24.206703]  disarm_kprobe_ftrace+0x83/0xd0
[   24.206789]  __disable_kprobe+0x129/0x160
[   24.206880]  disable_kprobe+0x27/0x60
[   24.206972]  kprobe_register+0xa2/0xe0
[   24.207057]  perf_trace_event_unreg+0x33/0xd0
[   24.207169]  perf_kprobe_destroy+0x3b/0x80
[   24.207262]  __free_event+0x119/0x290
[   24.207348]  perf_event_release_kernel+0x1ef/0x220
[   24.207461]  perf_release+0x12/0x20
[   24.207543]  __fput+0x11b/0x2a0
[   24.207626]  task_work_run+0x8b/0xc0
[   24.207711]  exit_to_user_mode_loop+0x107/0x4d0
[   24.207827]  do_syscall_64+0x25b/0x390
[   24.207915]  ? entry_SYSCALL_64_after_hwframe+0x76/0x7e
[   24.208021]  ? trace_irq_disable+0x1d/0xc0
[   24.208110]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[   24.208215] RIP: 0033:0x7f46530ff85b
[   24.208307] Code: 03 00 00 00 0f 05 48 3d 00 f0 ff ff 77 41 c3 48 83 ec 18 89 7c 24 0c e8 e3 83 f8 ff 8b 7c 24 0c 41 89 c0 b8 03 00 00 00 0f 05 <48> 3d 00 f0 
ff ff 77 35 44 89 c7 89 44 24 0c e8 41 84 f8 ff 8b 44
[   24.208657] RSP: 002b:00007ffc40859770 EFLAGS: 00000293 ORIG_RAX: 0000000000000003
[   24.208816] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00007f46530ff85b
[   24.208978] RDX: 0000000000000002 RSI: 0000000000000002 RDI: 0000000000000019
[   24.209133] RBP: 00007ffc408597c0 R08: 0000000000000000 R09: 00007ffc40859757
[   24.209300] R10: 0000000000000000 R11: 0000000000000293 R12: 00007ffc4085ddc8
[   24.209457] R13: 000055e8800de120 R14: 000055e88118d390 R15: 00007f46533de000
[   24.209633]  </TASK>
[   24.209689] irq event stamp: 200963
[   24.209770] hardirqs last  enabled at (200971): [<ffffffff8136008c>] __console_unlock+0x5c/0x70
[   24.209971] hardirqs last disabled at (200978): [<ffffffff81360071>] __console_unlock+0x41/0x70
[   24.210156] softirqs last  enabled at (200568): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
[   24.210370] softirqs last disabled at (200557): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
[   24.210554] ---[ end trace 0000000000000000 ]---
[   24.210665] Bad trampoline accounting at: 00000000ab641fec (bpf_lsm_sk_alloc_security+0x4/0x20)
[   24.210866] ------------[ cut here ]------------
[   24.210993] WARNING: arch/x86/kernel/ftrace.c:105 at ftrace_replace_code+0xf7/0x210, CPU#10: test_progs/311
[   24.211182] Modules linked in: bpf_test_modorder_y(OE+) bpf_test_modorder_x(OE) bpf_testmod(OE)
[   24.211412] CPU: 10 UID: 0 PID: 311 Comm: test_progs Tainted: G        W  OE       7.0.0-rc1-gda78c0a81eea #83 PREEMPT(full) 
[   24.211656] Tainted: [W]=WARN, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
[   24.211788] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-5.el9 11/05/2023
[   24.211980] RIP: 0010:ftrace_replace_code+0xf7/0x210
[   24.212091] Code: c0 0f 85 ec 00 00 00 8b 44 24 03 41 33 45 00 0f b6 4c 24 07 41 32 4d 04 0f b6 c9 09 c1 0f 84 49 ff ff ff 4c 89 2d b9 df 8b 03 <0f> 0b bf ea 
ff ff ff e9 c4 00 00 00 e8 f8 e5 19 00 48 85 c0 0f 84
[   24.212503] RSP: 0018:ffa0000000d4bb58 EFLAGS: 00010202
[   24.212628] RAX: 00000000780a0001 RBX: 0000000000000001 RCX: 00000000780a00c1
[   24.212798] RDX: ffffffff81529000 RSI: 0000000000000005 RDI: ffffffff81529fc4
[   24.212970] RBP: 0000000000000001 R08: 000000000000ffff R09: ffffffff82e98430
[   24.213130] R10: 000000000002fffd R11: 00000000fffeffff R12: ff11000100125710
[   24.213317] R13: ffffffff83ec0f2d R14: ffffffff84b43820 R15: ffa0000000d4bb5b
[   24.213488] FS:  00007f46532a54c0(0000) GS:ff1100203be0c000(0000) knlGS:0000000000000000
[   24.213674] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   24.213813] CR2: 000055e885be1470 CR3: 000000010eef9003 CR4: 0000000000771ef0
[   24.213986] PKRU: 55555554
[   24.214044] Call Trace:
[   24.214100]  <TASK>
[   24.214167]  ftrace_modify_all_code+0x59/0x110
[   24.214301]  __ftrace_hash_move_and_update_ops+0x227/0x2c0
[   24.214415]  ? srso_return_thunk+0x5/0x5f
[   24.214502]  ? __mutex_lock+0x22a/0xc60
[   24.214588]  ? kfree+0x1ac/0x4c0
[   24.214682]  ? srso_return_thunk+0x5/0x5f
[   24.214765]  ? kfree+0x250/0x4c0
[   24.214855]  ? bpf_fentry_test3+0x4/0x20
[   24.214943]  ftrace_set_hash+0x13c/0x3d0
[   24.215041]  ftrace_set_filter_ip+0x88/0xb0
[   24.215132]  ? bpf_fentry_test3+0x4/0x20
[   24.215221]  disarm_kprobe_ftrace+0x83/0xd0
[   24.215328]  __disable_kprobe+0x129/0x160
[   24.215418]  disable_kprobe+0x27/0x60
[   24.215507]  kprobe_register+0xa2/0xe0
[   24.215594]  perf_trace_event_unreg+0x33/0xd0
[   24.215701]  perf_kprobe_destroy+0x3b/0x80
[   24.215790]  __free_event+0x119/0x290
[   24.215888]  perf_event_release_kernel+0x1ef/0x220
[   24.216007]  perf_release+0x12/0x20
[   24.216091]  __fput+0x11b/0x2a0
[   24.216183]  task_work_run+0x8b/0xc0
[   24.216293]  exit_to_user_mode_loop+0x107/0x4d0
[   24.216411]  do_syscall_64+0x25b/0x390
[   24.216497]  ? entry_SYSCALL_64_after_hwframe+0x76/0x7e
[   24.216606]  ? trace_irq_disable+0x1d/0xc0
[   24.216699]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[   24.216807] RIP: 0033:0x7f46530ff85b
[   24.216895] Code: 03 00 00 00 0f 05 48 3d 00 f0 ff ff 77 41 c3 48 83 ec 18 89 7c 24 0c e8 e3 83 f8 ff 8b 7c 24 0c 41 89 c0 b8 03 00 00 00 0f 05 <48> 3d 00 f0 
ff ff 77 35 44 89 c7 89 44 24 0c e8 41 84 f8 ff 8b 44
[   24.217293] RSP: 002b:00007ffc40859770 EFLAGS: 00000293 ORIG_RAX: 0000000000000003
[   24.217461] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00007f46530ff85b
[   24.217627] RDX: 0000000000000002 RSI: 0000000000000002 RDI: 0000000000000019
[   24.217785] RBP: 00007ffc408597c0 R08: 0000000000000000 R09: 00007ffc40859757
[   24.217950] R10: 0000000000000000 R11: 0000000000000293 R12: 00007ffc4085ddc8
[   24.218107] R13: 000055e8800de120 R14: 000055e88118d390 R15: 00007f46533de000
[   24.218306]  </TASK>
[   24.218363] irq event stamp: 201623
[   24.218445] hardirqs last  enabled at (201631): [<ffffffff8136008c>] __console_unlock+0x5c/0x70
[   24.218625] hardirqs last disabled at (201638): [<ffffffff81360071>] __console_unlock+0x41/0x70
[   24.218810] softirqs last  enabled at (201612): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
[   24.219012] softirqs last disabled at (201601): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
[   24.219208] ---[ end trace 0000000000000000 ]---
[   24.219693] ------------[ ftrace bug ]------------
[   24.219801] ftrace failed to modify 
[   24.219804] [<ffffffff81529fc4>] bpf_lsm_sk_alloc_security+0x4/0x20
[   24.220022]  actual:   e9:b7:ca:ad:3e
[   24.220113]  expected: e8:b7:c0:d5:ff
[   24.220203] ftrace record flags: e8980000
[   24.220307]  (0) R   tramp: ERROR!
[   24.220321] ------------[ cut here ]------------
[   24.220507] WARNING: kernel/trace/ftrace.c:2715 at ftrace_get_addr_curr+0x149/0x190, CPU#10: test_progs/311
[   24.220693] Modules linked in: bpf_test_modorder_y(OE+) bpf_test_modorder_x(OE) bpf_testmod(OE)
[   24.220895] CPU: 10 UID: 0 PID: 311 Comm: test_progs Tainted: G        W  OE       7.0.0-rc1-gda78c0a81eea #83 PREEMPT(full) 
[   24.221135] Tainted: [W]=WARN, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
[   24.221284] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-5.el9 11/05/2023
[   24.221467] RIP: 0010:ftrace_get_addr_curr+0x149/0x190
[   24.221577] Code: 00 4c 89 f7 e8 88 f8 ff ff 84 c0 75 92 4d 8b 7f 08 e8 fb b3 c1 00 4d 85 ff 0f 94 c0 49 81 ff b0 1c 6e 83 0f 94 c1 08 c1 74 96 <0f> 0b c6 05 
62 e8 2b 02 01 c7 05 54 e8 2b 02 00 00 00 00 48 c7 05
[   24.221938] RSP: 0018:ffa0000000d4bb10 EFLAGS: 00010202
[   24.222052] RAX: 0000000000000000 RBX: ff11000100125710 RCX: ff1100010b28a201
[   24.222205] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffffffff81529fc4
[   24.222384] RBP: 00000000ffffffea R08: 000000000000ffff R09: ffffffff82e98430
[   24.222542] R10: 000000000002fffd R11: 00000000fffeffff R12: ff11000100125710
[   24.222708] R13: ffffffff83ec0f2d R14: ffffffff81529fc4 R15: ffffffff836e1cb0
[   24.222866] FS:  00007f46532a54c0(0000) GS:ff1100203be0c000(0000) knlGS:0000000000000000
[   24.223034] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   24.223171] CR2: 000055e885be1470 CR3: 000000010eef9003 CR4: 0000000000771ef0
[   24.223341] PKRU: 55555554
[   24.223397] Call Trace:
[   24.223454]  <TASK>
[   24.223511]  ? bpf_lsm_sk_alloc_security+0x4/0x20
[   24.223623]  ftrace_bug+0x1ff/0x290
[   24.223710]  ftrace_replace_code+0x1d6/0x210
[   24.223829]  ftrace_modify_all_code+0x59/0x110
[   24.223946]  __ftrace_hash_move_and_update_ops+0x227/0x2c0
[   24.224060]  ? srso_return_thunk+0x5/0x5f
[   24.224148]  ? __mutex_lock+0x22a/0xc60
[   24.224245]  ? kfree+0x1ac/0x4c0
[   24.224337]  ? srso_return_thunk+0x5/0x5f
[   24.224420]  ? kfree+0x250/0x4c0
[   24.224512]  ? bpf_fentry_test3+0x4/0x20
[   24.224597]  ftrace_set_hash+0x13c/0x3d0
[   24.224690]  ftrace_set_filter_ip+0x88/0xb0
[   24.224776]  ? bpf_fentry_test3+0x4/0x20
[   24.224869]  disarm_kprobe_ftrace+0x83/0xd0
[   24.224965]  __disable_kprobe+0x129/0x160
[   24.225051]  disable_kprobe+0x27/0x60
[   24.225136]  kprobe_register+0xa2/0xe0
[   24.225223]  perf_trace_event_unreg+0x33/0xd0
[   24.225346]  perf_kprobe_destroy+0x3b/0x80
[   24.225431]  __free_event+0x119/0x290
[   24.225518]  perf_event_release_kernel+0x1ef/0x220
[   24.225631]  perf_release+0x12/0x20
[   24.225715]  __fput+0x11b/0x2a0
[   24.225804]  task_work_run+0x8b/0xc0
[   24.225895]  exit_to_user_mode_loop+0x107/0x4d0
[   24.226016]  do_syscall_64+0x25b/0x390
[   24.226099]  ? entry_SYSCALL_64_after_hwframe+0x76/0x7e
[   24.226207]  ? trace_irq_disable+0x1d/0xc0
[   24.226308]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[   24.226415] RIP: 0033:0x7f46530ff85b
[   24.226498] Code: 03 00 00 00 0f 05 48 3d 00 f0 ff ff 77 41 c3 48 83 ec 18 89 7c 24 0c e8 e3 83 f8 ff 8b 7c 24 0c 41 89 c0 b8 03 00 00 00 0f 05 <48> 3d 00 f0 
ff ff 77 35 44 89 c7 89 44 24 0c e8 41 84 f8 ff 8b 44
[   24.226851] RSP: 002b:00007ffc40859770 EFLAGS: 00000293 ORIG_RAX: 0000000000000003
[   24.227016] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00007f46530ff85b
[   24.227173] RDX: 0000000000000002 RSI: 0000000000000002 RDI: 0000000000000019
[   24.227341] RBP: 00007ffc408597c0 R08: 0000000000000000 R09: 00007ffc40859757
[   24.227500] R10: 0000000000000000 R11: 0000000000000293 R12: 00007ffc4085ddc8
[   24.227652] R13: 000055e8800de120 R14: 000055e88118d390 R15: 00007f46533de000
[   24.227830]  </TASK>
[   24.227891] irq event stamp: 202299
[   24.227974] hardirqs last  enabled at (202307): [<ffffffff8136008c>] __console_unlock+0x5c/0x70
[   24.228162] hardirqs last disabled at (202314): [<ffffffff81360071>] __console_unlock+0x41/0x70
[   24.228357] softirqs last  enabled at (201682): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
[   24.228540] softirqs last disabled at (201671): [<ffffffff812b8b97>] __irq_exit_rcu+0x47/0xc0
[   24.228716] ---[ end trace 0000000000000000 ]---
[   24.228834] Bad trampoline accounting at: 00000000ab641fec (bpf_lsm_sk_alloc_security+0x4/0x20)
[   24.229029] 
[   24.229029]  expected tramp: ffffffff81286080
[   24.261301] BUG: unable to handle page fault for address: ffa00000004b9050
[   24.261436] #PF: supervisor read access in kernel mode
[   24.261528] #PF: error_code(0x0000) - not-present page
[   24.261621] PGD 100000067 P4D 100832067 PUD 100833067 PMD 100efb067 PTE 0
[   24.261745] Oops: Oops: 0000 [#1] SMP NOPTI
[   24.261821] CPU: 9 UID: 0 PID: 1338 Comm: ip Tainted: G        W  OE       7.0.0-rc1-gda78c0a81eea #83 PREEMPT(full) 
[   24.262006] Tainted: [W]=WARN, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
[   24.262119] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-5.el9 11/05/2023
[   24.262281] RIP: 0010:__cgroup_bpf_run_lsm_current+0xc5/0x2f0
[   24.262393] Code: a6 6f 1a 02 01 48 c7 c7 31 5b 71 82 be bf 01 00 00 48 c7 c2 d3 70 65 82 e8 d8 53 ce ff 4d 8b 7f 60 4d 85 ff 0f 84 14 02 00 00 <49> 8b 46 f0 
4c 63 b0 34 05 00 00 c7 44 24 10 00 00 00 00 41 0f b7
[   24.262693] RSP: 0018:ffa0000004dfbc98 EFLAGS: 00010282
[   24.262784] RAX: 0000000000000001 RBX: ffa0000004dfbd10 RCX: 0000000000000001
[   24.262923] RDX: 00000000d7c4159d RSI: ffffffff8359b368 RDI: ff1100011b5c50c8
[   24.263055] RBP: ffa0000004dfbd30 R08: 0000000000020000 R09: ffffffffffffffff
[   24.263187] R10: ffffffff814f76b3 R11: 0000000000000000 R12: ff1100011b5c4580
[   24.263325] R13: 0000000000000000 R14: ffa00000004b9060 R15: ffffffff835b3040
[   24.263465] FS:  00007f0007064800(0000) GS:ff1100203bdcc000(0000) knlGS:0000000000000000
[   24.263599] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   24.263709] CR2: ffa00000004b9050 CR3: 0000000120f4d002 CR4: 0000000000771ef0
[   24.263841] PKRU: 55555554
[   24.263890] Call Trace:
[   24.263938]  <TASK>
[   24.263992]  bpf_trampoline_6442513766+0x6a/0x10d
[   24.264088]  security_sk_alloc+0x83/0xd0
[   24.264162]  sk_prot_alloc+0xf4/0x150
[   24.264236]  sk_alloc+0x34/0x2a0
[   24.264305]  ? srso_return_thunk+0x5/0x5f
[   24.264375]  ? _raw_spin_unlock_irqrestore+0x35/0x50
[   24.264465]  ? srso_return_thunk+0x5/0x5f
[   24.264533]  ? __wake_up_common_lock+0xa8/0xd0
[   24.264625]  __netlink_create+0x2f/0xf0
[   24.264695]  netlink_create+0x1c4/0x230
[   24.264765]  ? __pfx_rtnetlink_bind+0x10/0x10
[   24.264858]  __sock_create+0x21d/0x400
[   24.264937]  __sys_socket+0x65/0x100
[   24.265007]  ? srso_return_thunk+0x5/0x5f
[   24.265077]  __x64_sys_socket+0x19/0x30
[   24.265146]  do_syscall_64+0xde/0x390
[   24.265216]  ? entry_SYSCALL_64_after_hwframe+0x76/0x7e
[   24.265307]  ? trace_irq_disable+0x1d/0xc0
[   24.265379]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[   24.265469] RIP: 0033:0x7f0006f112ab
[   24.265538] Code: 73 01 c3 48 8b 0d 6d 8b 0e 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 29 00 00 00 0f 05 <48> 3d 01 f0 
ff ff 73 01 c3 48 8b 0d 3d 8b 0e 00 f7 d8 64 89 01 48
[   24.265822] RSP: 002b:00007ffd8ecb3be8 EFLAGS: 00000246 ORIG_RAX: 0000000000000029
[   24.265960] RAX: ffffffffffffffda RBX: 000056212b30d040 RCX: 00007f0006f112ab
[   24.266088] RDX: 0000000000000000 RSI: 0000000000080003 RDI: 0000000000000010
[   24.266217] RBP: 0000000000000000 R08: 00007ffd8ecb3bc0 R09: 0000000000000000
[   24.266346] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
[   24.266474] R13: 000056212b30d040 R14: 00007ffd8ecb3d88 R15: 0000000000000004
[   24.266617]  </TASK>
[   24.266663] Modules linked in: bpf_test_modorder_y(OE+) bpf_test_modorder_x(OE) bpf_testmod(OE)
[   24.266824] CR2: ffa00000004b9050
[   24.266897] ---[ end trace 0000000000000000 ]---
[   24.266989] RIP: 0010:__cgroup_bpf_run_lsm_current+0xc5/0x2f0
[   24.267101] Code: a6 6f 1a 02 01 48 c7 c7 31 5b 71 82 be bf 01 00 00 48 c7 c2 d3 70 65 82 e8 d8 53 ce ff 4d 8b 7f 60 4d 85 ff 0f 84 14 02 00 00 <49> 8b 46 f0 
4c 63 b0 34 05 00 00 c7 44 24 10 00 00 00 00 41 0f b7
[   24.267406] RSP: 0018:ffa0000004dfbc98 EFLAGS: 00010282
[   24.267499] RAX: 0000000000000001 RBX: ffa0000004dfbd10 RCX: 0000000000000001
[   24.267629] RDX: 00000000d7c4159d RSI: ffffffff8359b368 RDI: ff1100011b5c50c8
[   24.267758] RBP: ffa0000004dfbd30 R08: 0000000000020000 R09: ffffffffffffffff
[   24.267897] R10: ffffffff814f76b3 R11: 0000000000000000 R12: ff1100011b5c4580
[   24.268030] R13: 0000000000000000 R14: ffa00000004b9060 R15: ffffffff835b3040
[   24.268167] FS:  00007f0007064800(0000) GS:ff1100203bdcc000(0000) knlGS:0000000000000000
[   24.268311] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   24.268428] CR2: ffa00000004b9050 CR3: 0000000120f4d002 CR4: 0000000000771ef0
[   24.268565] PKRU: 55555554
[   24.268613] Kernel panic - not syncing: Fatal exception
[   24.268977] Kernel Offset: disabled
[   24.269046] ---[ end Kernel panic - not syncing: Fatal exception ]---



> ---
>  arch/x86/Kconfig        |   1 +
>  kernel/bpf/trampoline.c | 220 ++++++++++++++++++++++++++++++++++------
>  kernel/trace/Kconfig    |   3 +
>  kernel/trace/ftrace.c   |   7 +-
>  4 files changed, 200 insertions(+), 31 deletions(-)
> 
> [...]

^ permalink raw reply related

* Re: [PATCH 00/61] vfs: change inode->i_ino from unsigned long to u64
From: Jeff Layton @ 2026-02-27 17:19 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Alexander Viro, Christian Brauner, Jan Kara, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, Dan Williams, Eric Biggers,
	Theodore Y. Ts'o, Muchun Song, Oscar Salvador,
	David Hildenbrand, David Howells, Paulo Alcantara, Andreas Dilger,
	Jan Kara, Jaegeuk Kim, Chao Yu, Trond Myklebust, Anna Schumaker,
	Chuck Lever, NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey,
	Steve French, Ronnie Sahlberg, Shyam Prasad N, Bharath SM,
	Alexander Aring, Ryusuke Konishi, Viacheslav Dubeyko,
	Eric Van Hensbergen, Latchesar Ionkov, Dominique Martinet,
	Christian Schoenebeck, David Sterba, Marc Dionne, Ian Kent,
	Luis de Bethencourt, Salah Triki, Tigran A. Aivazian,
	Ilya Dryomov, Alex Markuze, Jan Harkes, coda, Nicolas Pitre,
	Tyler Hicks, Amir Goldstein, Christoph Hellwig,
	John Paul Adrian Glaubitz, Yangtao Li, Mikulas Patocka,
	David Woodhouse, Richard Weinberger, Dave Kleikamp,
	Konstantin Komarov, Mark Fasheh, Joel Becker, Joseph Qi,
	Mike Marshall, Martin Brandenburg, Miklos Szeredi, Anders Larsen,
	Zhihao Cheng, Damien Le Moal, Naohiro Aota, Johannes Thumshirn,
	John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
	Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg, Fan Wu,
	Stephen Smalley, Ondrej Mosnacek, Casey Schaufler, Alex Deucher,
	Christian König, David Airlie, Simona Vetter, Sumit Semwal,
	Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
	David S. Miller, Jakub Kicinski, Simon Horman, Oleg Nesterov,
	Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Ian Rogers, Adrian Hunter, James Clark, Darrick J. Wong,
	Martin Schiller, linux-fsdevel, linux-kernel, linux-trace-kernel,
	nvdimm, fsverity, linux-mm, netfs, linux-ext4, linux-f2fs-devel,
	linux-nfs, linux-cifs, samba-technical, linux-nilfs, v9fs,
	linux-afs, autofs, ceph-devel, codalist, ecryptfs, linux-mtd,
	jfs-discussion, ntfs3, ocfs2-devel, devel, linux-unionfs,
	apparmor, linux-security-module, linux-integrity, selinux,
	amd-gfx, dri-devel, linux-media, linaro-mm-sig, netdev,
	linux-perf-users, linux-fscrypt, linux-xfs, linux-hams, linux-x25
In-Reply-To: <aaB5lgKd8FOIizPg@casper.infradead.org>

On Thu, 2026-02-26 at 16:49 +0000, Matthew Wilcox wrote:
> On Thu, Feb 26, 2026 at 10:55:02AM -0500, Jeff Layton wrote:
> > The bulk of the changes are to format strings and tracepoints, since the
> > kernel itself doesn't care that much about the i_ino field. The first
> > patch changes some vfs function arguments, so check that one out
> > carefully.
> 
> Why are the format strings all done as separate patches?  Don't we get
> bisection hazards by splitting it apart this way?

Circling back to this...

I have a v2 series (~107 patches) that I'm testing now that does this
more bisectably with the typedef and macro scaffolding that Mathieu
suggested. I'll probably send it early next week.

I had done it this way originally since I figured it was best to break
this up by subsystem. Should I continue with this series as a set of
patches broken up this way, or is it preferable to combine the pile of
format changes into fewer patches?
-- 
Jeff Layton <jlayton@kernel.org>

^ permalink raw reply

* Re: [RFC PATCH bpf-next v2 1/3] libbpf: Optimize kprobe.session attachment for exact function names
From: Jiri Olsa @ 2026-02-27 17:08 UTC (permalink / raw)
  To: Andrey Grodzovsky
  Cc: bpf, linux-open-source, ast, daniel, andrii, rostedt,
	linux-trace-kernel
In-Reply-To: <20260226173342.3565919-2-andrey.grodzovsky@crowdstrike.com>

On Thu, Feb 26, 2026 at 12:33:40PM -0500, Andrey Grodzovsky wrote:
> Implement dual-path optimization in attach_kprobe_session():
> - Fast path: Use syms[] array for exact function names
>   (no kallsyms parsing)
> - Slow path: Use pattern matching with kallsyms only for
>   wildcards
> 
> This avoids expensive kallsyms file parsing (~150ms) when function names
> are specified exactly, improving attachment time 50x (~3-5ms).
> 
> Error code normalization: The fast path returns ESRCH from kernel's
> ftrace_lookup_symbols(), while slow path returns ENOENT from userspace
> kallsyms parsing. Convert ESRCH to ENOENT in fast path to maintain API
> consistency - both paths now return identical error codes for "symbol
> not found".
> 
> Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
> ---
>  tools/lib/bpf/libbpf.c | 34 ++++++++++++++++++++++++++++------
>  1 file changed, 28 insertions(+), 6 deletions(-)
> 
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index 0be7017800fe..0ba8aa2c5fd2 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -12042,6 +12042,20 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
>  		return libbpf_err_ptr(-EINVAL);
>  
>  	if (pattern) {
> +		/*
> +		 * Exact function name (no wildcards): bypass kallsyms parsing
> +		 * and pass the symbol directly to the kernel via syms[] array.
> +		 * The kernel's ftrace_lookup_symbols() resolves it efficiently.
> +		 */
> +		if (!strpbrk(pattern, "*?")) {
> +			const char *sym = pattern;
> +
> +			syms = &sym;

why not use pattern ndirectly?

> +			cnt = 1;
> +			pattern = NULL;

not sure why we need this

> +			goto attach;
> +		}

I wonder we could just another if path and avoid the goto, like:


-	if (pattern) {
+	/*
+	 * Exact function name (no wildcards): bypass kallsyms parsing
+	 * and pass the symbol directly to the kernel via syms[] array.
+	 * The kernel's ftrace_lookup_symbols() resolves it efficiently.
+	 */
+	if (pattern && !strpbrk(pattern, "*?")) {
+		syms = &pattern;
+		cnt = 1;
+	} else if (pattern) {
 		if (has_available_filter_functions_addrs())
 			err = libbpf_available_kprobes_parse(&res);


wdyt?

> +
>  		if (has_available_filter_functions_addrs())
>  			err = libbpf_available_kprobes_parse(&res);
>  		else
> @@ -12060,6 +12074,7 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
>  		cnt = res.cnt;
>  	}
>  
> +attach:
>  	retprobe = OPTS_GET(opts, retprobe, false);
>  	session  = OPTS_GET(opts, session, false);
>  
> @@ -12067,7 +12082,6 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
>  		return libbpf_err_ptr(-EINVAL);
>  
>  	attach_type = session ? BPF_TRACE_KPROBE_SESSION : BPF_TRACE_KPROBE_MULTI;
> -

not needed

>  	lopts.kprobe_multi.syms = syms;
>  	lopts.kprobe_multi.addrs = addrs;
>  	lopts.kprobe_multi.cookies = cookies;
> @@ -12084,6 +12098,14 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
>  	link_fd = bpf_link_create(prog_fd, 0, attach_type, &lopts);
>  	if (link_fd < 0) {
>  		err = -errno;
> +		/*
> +		 * Normalize error code: when exact name bypasses kallsyms
> +		 * parsing, kernel returns ESRCH from ftrace_lookup_symbols().
> +		 * Convert to ENOENT for API consistency with the pattern
> +		 * matching path which returns ENOENT from userspace.
> +		 */
> +		if (err == -ESRCH)
> +			err = -ENOENT;
>  		pr_warn("prog '%s': failed to attach: %s\n",
>  			prog->name, errstr(err));
>  		goto error;
> @@ -12192,7 +12214,7 @@ static int attach_kprobe_session(const struct bpf_program *prog, long cookie,
>  {
>  	LIBBPF_OPTS(bpf_kprobe_multi_opts, opts, .session = true);
>  	const char *spec;
> -	char *pattern;
> +	char *func_name;

I don't think we need the change, it's jus for the different pr_warn
below right? let's keep pattern

thanks,
jirka

>  	int n;
>  
>  	*link = NULL;
> @@ -12202,14 +12224,14 @@ static int attach_kprobe_session(const struct bpf_program *prog, long cookie,
>  		return 0;
>  
>  	spec = prog->sec_name + sizeof("kprobe.session/") - 1;
> -	n = sscanf(spec, "%m[a-zA-Z0-9_.*?]", &pattern);
> +	n = sscanf(spec, "%m[a-zA-Z0-9_.*?]", &func_name);
>  	if (n < 1) {
> -		pr_warn("kprobe session pattern is invalid: %s\n", spec);
> +		pr_warn("kprobe session function name is invalid: %s\n", spec);
>  		return -EINVAL;
>  	}
>  
> -	*link = bpf_program__attach_kprobe_multi_opts(prog, pattern, &opts);
> -	free(pattern);
> +	*link = bpf_program__attach_kprobe_multi_opts(prog, func_name, &opts);
> +	free(func_name);
>  	return *link ? 0 : -errno;
>  }
>  
> -- 
> 2.34.1
> 

^ permalink raw reply

* Re: [PATCH] blktrace: fix __this_cpu_read/write in preemptible context
From: Jens Axboe @ 2026-02-27 16:48 UTC (permalink / raw)
  To: Chaitanya Kulkarni, rostedt, mhiramat, mathieu.desnoyers
  Cc: shinichiro.kawasaki, linux-block, linux-trace-kernel
In-Reply-To: <20260227050303.10945-1-kch@nvidia.com>

On 2/26/26 10:03 PM, Chaitanya Kulkarni wrote:
> tracing_record_cmdline() internally uses __this_cpu_read() and
> __this_cpu_write() on the per-CPU variable trace_taskinfo_save, and
> trace_save_cmdline() explicitly asserts preemption is disabled via
> lockdep_assert_preemption_disabled().  These operations are safe only
> when preemption is off, as they were designed to be called from the
> scheduler's context probe_wakeup_sched_switch() / probe_wakeup().
> 
> __blk_add_trace() calls tracing_record_cmdline(current) from process
> context where preemption is fully enabled, triggering the following
> splat on using blktests/blktrace/002:
> 
> blktrace/002 (blktrace ftrace corruption with sysfs trace)   [failed]
>     runtime  0.367s  ...  0.437s
>     something found in dmesg:
>     [   81.211018] run blktests blktrace/002 at 2026-02-25 22:24:33
>     [   81.239580] null_blk: disk nullb1 created
>     [   81.357294] BUG: using __this_cpu_read() in preemptible [00000000] code: dd/2516
>     [   81.362842] caller is tracing_record_cmdline+0x10/0x40
>     [   81.362872] CPU: 16 UID: 0 PID: 2516 Comm: dd Tainted: G                 N  7.0.0-rc1lblk+ #84 PREEMPT(full)
>     [   81.362877] Tainted: [N]=TEST
>     [   81.362878] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
>     [   81.362881] Call Trace:
>     [   81.362884]  <TASK>
>     [   81.362886]  dump_stack_lvl+0x8d/0xb0
>     ...
>     (See '/mnt/sda/blktests/results/nodev/blktrace/002.dmesg' for the entire message)
> 
> [   81.211018] run blktests blktrace/002 at 2026-02-25 22:24:33
> [   81.239580] null_blk: disk nullb1 created
> [   81.357294] BUG: using __this_cpu_read() in preemptible [00000000] code: dd/2516
> [   81.362842] caller is tracing_record_cmdline+0x10/0x40
> [   81.362872] CPU: 16 UID: 0 PID: 2516 Comm: dd Tainted: G                 N  7.0.0-rc1lblk+ #84 PREEMPT(full)
> [   81.362877] Tainted: [N]=TEST
> [   81.362878] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
> [   81.362881] Call Trace:
> [   81.362884]  <TASK>
> [   81.362886]  dump_stack_lvl+0x8d/0xb0
> [   81.362895]  check_preemption_disabled+0xce/0xe0
> [   81.362902]  tracing_record_cmdline+0x10/0x40
> [   81.362923]  __blk_add_trace+0x307/0x5d0
> [   81.362934]  ? lock_acquire+0xe0/0x300
> [   81.362940]  ? iov_iter_extract_pages+0x101/0xa30
> [   81.362959]  blk_add_trace_bio+0x106/0x1e0
> [   81.362968]  submit_bio_noacct_nocheck+0x24b/0x3a0
> [   81.362979]  ? lockdep_init_map_type+0x58/0x260
> [   81.362988]  submit_bio_wait+0x56/0x90
> [   81.363009]  __blkdev_direct_IO_simple+0x16c/0x250
> [   81.363026]  ? __pfx_submit_bio_wait_endio+0x10/0x10
> [   81.363038]  ? rcu_read_lock_any_held+0x73/0xa0
> [   81.363051]  blkdev_read_iter+0xc1/0x140
> [   81.363059]  vfs_read+0x20b/0x330
> [   81.363083]  ksys_read+0x67/0xe0
> [   81.363090]  do_syscall_64+0xbf/0xf00
> [   81.363102]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [   81.363106] RIP: 0033:0x7f281906029d
> [   81.363111] Code: 31 c0 e9 c6 fe ff ff 50 48 8d 3d 66 63 0a 00 e8 59 ff 01 00 66 0f 1f 84 00 00 00 00 00 80 3d 41 33 0e 00 00 74 17 31 c0 0f 05 <48> 3d 00 f0 ff ff 77 5b c3 66 2e 0f 1f 84 00 00 00 00 00 48 83 ec
> [   81.363113] RSP: 002b:00007ffca127dd48 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
> [   81.363120] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f281906029d
> [   81.363122] RDX: 0000000000001000 RSI: 0000559f8bfae000 RDI: 0000000000000000
> [   81.363123] RBP: 0000000000001000 R08: 0000002863a10a81 R09: 00007f281915f000
> [   81.363124] R10: 00007f2818f77b60 R11: 0000000000000246 R12: 0000559f8bfae000
> [   81.363126] R13: 0000000000000000 R14: 0000000000000000 R15: 000000000000000a
> [   81.363142]  </TASK>

Is this a new issue? Needs a Fixes tag.

-- 
Jens Axboe


^ permalink raw reply

* Re: [PATCH 51/61] security: update audit format strings for u64 i_ino
From: Ryan Lee @ 2026-02-27 16:46 UTC (permalink / raw)
  To: Jeff Layton
  Cc: Alexander Viro, Christian Brauner, Jan Kara, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, Dan Williams, Matthew Wilcox,
	Eric Biggers, Theodore Y. Ts'o, Muchun Song, Oscar Salvador,
	David Hildenbrand, David Howells, Paulo Alcantara, Andreas Dilger,
	Jan Kara, Jaegeuk Kim, Chao Yu, Trond Myklebust, Anna Schumaker,
	Chuck Lever, NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey,
	Steve French, Ronnie Sahlberg, Shyam Prasad N, Bharath SM,
	Alexander Aring, Ryusuke Konishi, Viacheslav Dubeyko,
	Eric Van Hensbergen, Latchesar Ionkov, Dominique Martinet,
	Christian Schoenebeck, David Sterba, Marc Dionne, Ian Kent,
	Luis de Bethencourt, Salah Triki, Tigran A. Aivazian,
	Ilya Dryomov, Alex Markuze, Jan Harkes, coda, Nicolas Pitre,
	Tyler Hicks, Amir Goldstein, Christoph Hellwig,
	John Paul Adrian Glaubitz, Yangtao Li, Mikulas Patocka,
	David Woodhouse, Richard Weinberger, Dave Kleikamp,
	Konstantin Komarov, Mark Fasheh, Joel Becker, Joseph Qi,
	Mike Marshall, Martin Brandenburg, Miklos Szeredi, Anders Larsen,
	Zhihao Cheng, Damien Le Moal, Naohiro Aota, Johannes Thumshirn,
	John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
	Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg, Fan Wu,
	Stephen Smalley, Ondrej Mosnacek, Casey Schaufler, Alex Deucher,
	Christian König, David Airlie, Simona Vetter, Sumit Semwal,
	Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
	David S. Miller, Jakub Kicinski, Simon Horman, Oleg Nesterov,
	Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Ian Rogers, Adrian Hunter, James Clark, Darrick J. Wong,
	Martin Schiller, linux-fsdevel, linux-kernel, linux-trace-kernel,
	nvdimm, fsverity, linux-mm, netfs, linux-ext4, linux-f2fs-devel,
	linux-nfs, linux-cifs, samba-technical, linux-nilfs, v9fs,
	linux-afs, autofs, ceph-devel, codalist, ecryptfs, linux-mtd,
	jfs-discussion, ntfs3, ocfs2-devel, devel, linux-unionfs,
	apparmor, linux-security-module, linux-integrity, selinux,
	amd-gfx, dri-devel, linux-media, linaro-mm-sig, netdev,
	linux-perf-users, linux-fscrypt, linux-xfs, linux-hams, linux-x25
In-Reply-To: <20260226-iino-u64-v1-51-ccceff366db9@kernel.org>

On Thu, Feb 26, 2026 at 9:13 AM Jeff Layton <jlayton@kernel.org> wrote:
>
> Update %lu/%ld to %llu/%lld in security audit logging functions that
> print inode->i_ino, since i_ino is now u64.
>
> Files updated: apparmor/apparmorfs.c, integrity/integrity_audit.c,
> ipe/audit.c, lsm_audit.c.
>
> Signed-off-by: Jeff Layton <jlayton@kernel.org>
> ---
>  security/apparmor/apparmorfs.c       |  4 ++--
>  security/integrity/integrity_audit.c |  2 +-
>  security/ipe/audit.c                 |  2 +-
>  security/lsm_audit.c                 | 10 +++++-----
>  security/selinux/hooks.c             |  4 ++--
>  security/smack/smack_lsm.c           | 12 ++++++------
>  6 files changed, 17 insertions(+), 17 deletions(-)
>
> diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
> index 2f84bd23edb69e7e69cb097e554091df0132816d..7b645f40e71c956f216fa6a7d69c3ecd4e2a5ff4 100644
> --- a/security/apparmor/apparmorfs.c
> +++ b/security/apparmor/apparmorfs.c
> @@ -149,7 +149,7 @@ static int aafs_count;
>
>  static int aafs_show_path(struct seq_file *seq, struct dentry *dentry)
>  {
> -       seq_printf(seq, "%s:[%lu]", AAFS_NAME, d_inode(dentry)->i_ino);
> +       seq_printf(seq, "%s:[%llu]", AAFS_NAME, d_inode(dentry)->i_ino);
>         return 0;
>  }
>
> @@ -2644,7 +2644,7 @@ static int policy_readlink(struct dentry *dentry, char __user *buffer,
>         char name[32];

I have confirmed that the buffer is still big enough for a 64-bit inode number.

>         int res;
>
> -       res = snprintf(name, sizeof(name), "%s:[%lu]", AAFS_NAME,
> +       res = snprintf(name, sizeof(name), "%s:[%llu]", AAFS_NAME,
>                        d_inode(dentry)->i_ino);
>         if (res > 0 && res < sizeof(name))
>                 res = readlink_copy(buffer, buflen, name, strlen(name));

For the AppArmor portion:

Reviewed-By: Ryan Lee <ryan.lee@canonical.com>

> diff --git a/security/integrity/integrity_audit.c b/security/integrity/integrity_audit.c
> index 0ec5e4c22cb2a1066c2b897776ead6d3db72635c..d8d9e5ff1cd22b091f462d1e83d28d2d6bd983e9 100644
> --- a/security/integrity/integrity_audit.c
> +++ b/security/integrity/integrity_audit.c
> @@ -62,7 +62,7 @@ void integrity_audit_message(int audit_msgno, struct inode *inode,
>         if (inode) {
>                 audit_log_format(ab, " dev=");
>                 audit_log_untrustedstring(ab, inode->i_sb->s_id);
> -               audit_log_format(ab, " ino=%lu", inode->i_ino);
> +               audit_log_format(ab, " ino=%llu", inode->i_ino);
>         }
>         audit_log_format(ab, " res=%d errno=%d", !result, errno);
>         audit_log_end(ab);
> diff --git a/security/ipe/audit.c b/security/ipe/audit.c
> index 3f0deeb54912730d9acf5e021a4a0cb29a34e982..93fb59fbddd60b56c0b22be2a38b809ef9e18b76 100644
> --- a/security/ipe/audit.c
> +++ b/security/ipe/audit.c
> @@ -153,7 +153,7 @@ void ipe_audit_match(const struct ipe_eval_ctx *const ctx,
>                 if (inode) {
>                         audit_log_format(ab, " dev=");
>                         audit_log_untrustedstring(ab, inode->i_sb->s_id);
> -                       audit_log_format(ab, " ino=%lu", inode->i_ino);
> +                       audit_log_format(ab, " ino=%llu", inode->i_ino);
>                 } else {
>                         audit_log_format(ab, " dev=? ino=?");
>                 }
> diff --git a/security/lsm_audit.c b/security/lsm_audit.c
> index 7d623b00495c14b079e10e963c21a9f949c11f07..737f5a263a8f79416133315edf363ece3d79c722 100644
> --- a/security/lsm_audit.c
> +++ b/security/lsm_audit.c
> @@ -202,7 +202,7 @@ void audit_log_lsm_data(struct audit_buffer *ab,
>                 if (inode) {
>                         audit_log_format(ab, " dev=");
>                         audit_log_untrustedstring(ab, inode->i_sb->s_id);
> -                       audit_log_format(ab, " ino=%lu", inode->i_ino);
> +                       audit_log_format(ab, " ino=%llu", inode->i_ino);
>                 }
>                 break;
>         }
> @@ -215,7 +215,7 @@ void audit_log_lsm_data(struct audit_buffer *ab,
>                 if (inode) {
>                         audit_log_format(ab, " dev=");
>                         audit_log_untrustedstring(ab, inode->i_sb->s_id);
> -                       audit_log_format(ab, " ino=%lu", inode->i_ino);
> +                       audit_log_format(ab, " ino=%llu", inode->i_ino);
>                 }
>                 break;
>         }
> @@ -228,7 +228,7 @@ void audit_log_lsm_data(struct audit_buffer *ab,
>                 if (inode) {
>                         audit_log_format(ab, " dev=");
>                         audit_log_untrustedstring(ab, inode->i_sb->s_id);
> -                       audit_log_format(ab, " ino=%lu", inode->i_ino);
> +                       audit_log_format(ab, " ino=%llu", inode->i_ino);
>                 }
>
>                 audit_log_format(ab, " ioctlcmd=0x%hx", a->u.op->cmd);
> @@ -246,7 +246,7 @@ void audit_log_lsm_data(struct audit_buffer *ab,
>                 if (inode) {
>                         audit_log_format(ab, " dev=");
>                         audit_log_untrustedstring(ab, inode->i_sb->s_id);
> -                       audit_log_format(ab, " ino=%lu", inode->i_ino);
> +                       audit_log_format(ab, " ino=%llu", inode->i_ino);
>                 }
>                 break;
>         }
> @@ -265,7 +265,7 @@ void audit_log_lsm_data(struct audit_buffer *ab,
>                 }
>                 audit_log_format(ab, " dev=");
>                 audit_log_untrustedstring(ab, inode->i_sb->s_id);
> -               audit_log_format(ab, " ino=%lu", inode->i_ino);
> +               audit_log_format(ab, " ino=%llu", inode->i_ino);
>                 rcu_read_unlock();
>                 break;
>         }
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index d8224ea113d1ac273aac1fb52324f00b3301ae75..150ea86ebc1f7c7f8391af4109a3da82b12d00d2 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -1400,7 +1400,7 @@ static int inode_doinit_use_xattr(struct inode *inode, struct dentry *dentry,
>         if (rc < 0) {
>                 kfree(context);
>                 if (rc != -ENODATA) {
> -                       pr_warn("SELinux: %s:  getxattr returned %d for dev=%s ino=%ld\n",
> +                       pr_warn("SELinux: %s:  getxattr returned %d for dev=%s ino=%lld\n",
>                                 __func__, -rc, inode->i_sb->s_id, inode->i_ino);
>                         return rc;
>                 }
> @@ -3477,7 +3477,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
>                                            &newsid);
>         if (rc) {
>                 pr_err("SELinux:  unable to map context to SID"
> -                      "for (%s, %lu), rc=%d\n",
> +                      "for (%s, %llu), rc=%d\n",
>                        inode->i_sb->s_id, inode->i_ino, -rc);
>                 return;
>         }
> diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
> index 98af9d7b943469d0ddd344fc78c0b87ca40c16c4..7e2f54c17a5d5c70740bbfa92ba4d4f1aca2cf22 100644
> --- a/security/smack/smack_lsm.c
> +++ b/security/smack/smack_lsm.c
> @@ -182,7 +182,7 @@ static int smk_bu_inode(struct inode *inode, int mode, int rc)
>         char acc[SMK_NUM_ACCESS_TYPE + 1];
>
>         if (isp->smk_flags & SMK_INODE_IMPURE)
> -               pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s\n",
> +               pr_info("Smack Unconfined Corruption: inode=(%s %lld) %s\n",
>                         inode->i_sb->s_id, inode->i_ino, current->comm);
>
>         if (rc <= 0)
> @@ -195,7 +195,7 @@ static int smk_bu_inode(struct inode *inode, int mode, int rc)
>
>         smk_bu_mode(mode, acc);
>
> -       pr_info("Smack %s: (%s %s %s) inode=(%s %ld) %s\n", smk_bu_mess[rc],
> +       pr_info("Smack %s: (%s %s %s) inode=(%s %lld) %s\n", smk_bu_mess[rc],
>                 tsp->smk_task->smk_known, isp->smk_inode->smk_known, acc,
>                 inode->i_sb->s_id, inode->i_ino, current->comm);
>         return 0;
> @@ -214,7 +214,7 @@ static int smk_bu_file(struct file *file, int mode, int rc)
>         char acc[SMK_NUM_ACCESS_TYPE + 1];
>
>         if (isp->smk_flags & SMK_INODE_IMPURE)
> -               pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s\n",
> +               pr_info("Smack Unconfined Corruption: inode=(%s %lld) %s\n",
>                         inode->i_sb->s_id, inode->i_ino, current->comm);
>
>         if (rc <= 0)
> @@ -223,7 +223,7 @@ static int smk_bu_file(struct file *file, int mode, int rc)
>                 rc = 0;
>
>         smk_bu_mode(mode, acc);
> -       pr_info("Smack %s: (%s %s %s) file=(%s %ld %pD) %s\n", smk_bu_mess[rc],
> +       pr_info("Smack %s: (%s %s %s) file=(%s %lld %pD) %s\n", smk_bu_mess[rc],
>                 sskp->smk_known, smk_of_inode(inode)->smk_known, acc,
>                 inode->i_sb->s_id, inode->i_ino, file,
>                 current->comm);
> @@ -244,7 +244,7 @@ static int smk_bu_credfile(const struct cred *cred, struct file *file,
>         char acc[SMK_NUM_ACCESS_TYPE + 1];
>
>         if (isp->smk_flags & SMK_INODE_IMPURE)
> -               pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s\n",
> +               pr_info("Smack Unconfined Corruption: inode=(%s %lld) %s\n",
>                         inode->i_sb->s_id, inode->i_ino, current->comm);
>
>         if (rc <= 0)
> @@ -253,7 +253,7 @@ static int smk_bu_credfile(const struct cred *cred, struct file *file,
>                 rc = 0;
>
>         smk_bu_mode(mode, acc);
> -       pr_info("Smack %s: (%s %s %s) file=(%s %ld %pD) %s\n", smk_bu_mess[rc],
> +       pr_info("Smack %s: (%s %s %s) file=(%s %lld %pD) %s\n", smk_bu_mess[rc],
>                 sskp->smk_known, smk_of_inode(inode)->smk_known, acc,
>                 inode->i_sb->s_id, inode->i_ino, file,
>                 current->comm);
>
> --
> 2.53.0
>
>

^ permalink raw reply

* [PATCH v4 5/5] mm: add tracepoints for zone lock
From: Dmitry Ilvokhin @ 2026-02-27 16:00 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Axel Rasmussen, Yuanchu Xie,
	Wei Xu, Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
	Rafael J. Wysocki, Pavel Machek, Len Brown, Brendan Jackman,
	Johannes Weiner, Zi Yan, Oscar Salvador, Qi Zheng, Shakeel Butt
  Cc: linux-kernel, linux-mm, linux-trace-kernel, linux-pm,
	"linux-cxl, Dmitry Ilvokhin
In-Reply-To: <cover.1772206930.git.d@ilvokhin.com>

Add tracepoint instrumentation to zone lock acquire/release operations
via the previously introduced wrappers.

The implementation follows the mmap_lock tracepoint pattern: a
lightweight inline helper checks whether the tracepoint is enabled and
calls into an out-of-line helper when tracing is active. When
CONFIG_TRACING is disabled, helpers compile to empty inline stubs.

The fast path is unaffected when tracing is disabled.

Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
---
 MAINTAINERS                      |  1 +
 include/linux/mmzone_lock.h      | 64 +++++++++++++++++++++++++++++++-
 include/trace/events/zone_lock.h | 64 ++++++++++++++++++++++++++++++++
 mm/Makefile                      |  2 +-
 mm/zone_lock.c                   | 28 ++++++++++++++
 5 files changed, 157 insertions(+), 2 deletions(-)
 create mode 100644 include/trace/events/zone_lock.h
 create mode 100644 mm/zone_lock.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 947298ecb111..de39e87a4c46 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16681,6 +16681,7 @@ F:	include/linux/pgtable.h
 F:	include/linux/ptdump.h
 F:	include/linux/vmpressure.h
 F:	include/linux/vmstat.h
+F:	include/trace/events/zone_lock.h
 F:	kernel/fork.c
 F:	mm/Kconfig
 F:	mm/debug.c
diff --git a/include/linux/mmzone_lock.h b/include/linux/mmzone_lock.h
index 62e34d500078..6bd8b026029f 100644
--- a/include/linux/mmzone_lock.h
+++ b/include/linux/mmzone_lock.h
@@ -4,6 +4,53 @@
 
 #include <linux/mmzone.h>
 #include <linux/spinlock.h>
+#include <linux/tracepoint-defs.h>
+
+DECLARE_TRACEPOINT(zone_lock_start_locking);
+DECLARE_TRACEPOINT(zone_lock_acquire_returned);
+DECLARE_TRACEPOINT(zone_lock_released);
+
+#ifdef CONFIG_TRACING
+
+void __zone_lock_do_trace_start_locking(struct zone *zone);
+void __zone_lock_do_trace_acquire_returned(struct zone *zone, bool success);
+void __zone_lock_do_trace_released(struct zone *zone);
+
+static inline void __zone_lock_trace_start_locking(struct zone *zone)
+{
+	if (tracepoint_enabled(zone_lock_start_locking))
+		__zone_lock_do_trace_start_locking(zone);
+}
+
+static inline void __zone_lock_trace_acquire_returned(struct zone *zone,
+						      bool success)
+{
+	if (tracepoint_enabled(zone_lock_acquire_returned))
+		__zone_lock_do_trace_acquire_returned(zone, success);
+}
+
+static inline void __zone_lock_trace_released(struct zone *zone)
+{
+	if (tracepoint_enabled(zone_lock_released))
+		__zone_lock_do_trace_released(zone);
+}
+
+#else /* !CONFIG_TRACING */
+
+static inline void __zone_lock_trace_start_locking(struct zone *zone)
+{
+}
+
+static inline void __zone_lock_trace_acquire_returned(struct zone *zone,
+						      bool success)
+{
+}
+
+static inline void __zone_lock_trace_released(struct zone *zone)
+{
+}
+
+#endif /* CONFIG_TRACING */
 
 static inline void zone_lock_init(struct zone *zone)
 {
@@ -12,26 +59,41 @@ static inline void zone_lock_init(struct zone *zone)
 
 #define zone_lock_irqsave(zone, flags)				\
 do {								\
+	bool success = true;					\
+								\
+	__zone_lock_trace_start_locking(zone);			\
 	spin_lock_irqsave(&(zone)->_lock, flags);		\
+	__zone_lock_trace_acquire_returned(zone, success);	\
 } while (0)
 
 #define zone_trylock_irqsave(zone, flags)			\
 ({								\
-	spin_trylock_irqsave(&(zone)->_lock, flags);		\
+	bool success;						\
+								\
+	__zone_lock_trace_start_locking(zone);			\
+	success = spin_trylock_irqsave(&(zone)->_lock, flags);	\
+	__zone_lock_trace_acquire_returned(zone, success);	\
+	success;						\
 })
 
 static inline void zone_unlock_irqrestore(struct zone *zone, unsigned long flags)
 {
+	__zone_lock_trace_released(zone);
 	spin_unlock_irqrestore(&zone->_lock, flags);
 }
 
 static inline void zone_lock_irq(struct zone *zone)
 {
+	bool success = true;
+
+	__zone_lock_trace_start_locking(zone);
 	spin_lock_irq(&zone->_lock);
+	__zone_lock_trace_acquire_returned(zone, success);
 }
 
 static inline void zone_unlock_irq(struct zone *zone)
 {
+	__zone_lock_trace_released(zone);
 	spin_unlock_irq(&zone->_lock);
 }
 
diff --git a/include/trace/events/zone_lock.h b/include/trace/events/zone_lock.h
new file mode 100644
index 000000000000..3df82a8c0160
--- /dev/null
+++ b/include/trace/events/zone_lock.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM zone_lock
+
+#if !defined(_TRACE_ZONE_LOCK_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_ZONE_LOCK_H
+
+#include <linux/tracepoint.h>
+#include <linux/types.h>
+
+struct zone;
+
+DECLARE_EVENT_CLASS(zone_lock,
+
+	TP_PROTO(struct zone *zone),
+
+	TP_ARGS(zone),
+
+	TP_STRUCT__entry(
+		__field(struct zone *, zone)
+	),
+
+	TP_fast_assign(
+		__entry->zone = zone;
+	),
+
+	TP_printk("zone=%p", __entry->zone)
+);
+
+#define DEFINE_ZONE_LOCK_EVENT(name)			\
+	DEFINE_EVENT(zone_lock, name,			\
+		TP_PROTO(struct zone *zone),		\
+		TP_ARGS(zone))
+
+DEFINE_ZONE_LOCK_EVENT(zone_lock_start_locking);
+DEFINE_ZONE_LOCK_EVENT(zone_lock_released);
+
+TRACE_EVENT(zone_lock_acquire_returned,
+
+	TP_PROTO(struct zone *zone, bool success),
+
+	TP_ARGS(zone, success),
+
+	TP_STRUCT__entry(
+		__field(struct zone *, zone)
+		__field(bool, success)
+	),
+
+	TP_fast_assign(
+		__entry->zone = zone;
+		__entry->success = success;
+	),
+
+	TP_printk(
+		"zone=%p success=%s",
+		__entry->zone,
+		__entry->success ? "true" : "false"
+	)
+);
+
+#endif /* _TRACE_ZONE_LOCK_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/mm/Makefile b/mm/Makefile
index 8ad2ab08244e..ffd06cf7a04e 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -55,7 +55,7 @@ obj-y			:= filemap.o mempool.o oom_kill.o fadvise.o \
 			   mm_init.o percpu.o slab_common.o \
 			   compaction.o show_mem.o \
 			   interval_tree.o list_lru.o workingset.o \
-			   debug.o gup.o mmap_lock.o vma_init.o $(mmu-y)
+			   debug.o gup.o mmap_lock.o zone_lock.o vma_init.o $(mmu-y)
 
 # Give 'page_alloc' its own module-parameter namespace
 page-alloc-y := page_alloc.o
diff --git a/mm/zone_lock.c b/mm/zone_lock.c
new file mode 100644
index 000000000000..f4e32220af9a
--- /dev/null
+++ b/mm/zone_lock.c
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0
+#define CREATE_TRACE_POINTS
+#include <trace/events/zone_lock.h>
+
+#include <linux/mmzone_lock.h>
+
+EXPORT_TRACEPOINT_SYMBOL(zone_lock_start_locking);
+EXPORT_TRACEPOINT_SYMBOL(zone_lock_acquire_returned);
+EXPORT_TRACEPOINT_SYMBOL(zone_lock_released);
+
+#ifdef CONFIG_TRACING
+
+void __zone_lock_do_trace_start_locking(struct zone *zone)
+{
+	trace_zone_lock_start_locking(zone);
+}
+
+void __zone_lock_do_trace_acquire_returned(struct zone *zone, bool success)
+{
+	trace_zone_lock_acquire_returned(zone, success);
+}
+
+void __zone_lock_do_trace_released(struct zone *zone)
+{
+	trace_zone_lock_released(zone);
+}
+
+#endif /* CONFIG_TRACING */
-- 
2.47.3


^ permalink raw reply related

* [PATCH v4 2/5] mm: convert zone lock users to wrappers
From: Dmitry Ilvokhin @ 2026-02-27 16:00 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Axel Rasmussen, Yuanchu Xie,
	Wei Xu, Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
	Rafael J. Wysocki, Pavel Machek, Len Brown, Brendan Jackman,
	Johannes Weiner, Zi Yan, Oscar Salvador, Qi Zheng, Shakeel Butt
  Cc: linux-kernel, linux-mm, linux-trace-kernel, linux-pm,
	"linux-cxl, Dmitry Ilvokhin, SeongJae Park
In-Reply-To: <cover.1772206930.git.d@ilvokhin.com>

Replace direct zone lock acquire/release operations with the
newly introduced wrappers.

The changes are purely mechanical substitutions. No functional change
intended. Locking semantics and ordering remain unchanged.

The compaction path is left unchanged for now and will be
handled separately in the following patch due to additional
non-trivial modifications.

Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
Reviewed-by: SeongJae Park <sj@kernel.org>
---
 kernel/power/snapshot.c |  5 +--
 mm/compaction.c         | 25 +++++++-------
 mm/memory_hotplug.c     |  9 ++---
 mm/mm_init.c            |  3 +-
 mm/page_alloc.c         | 73 +++++++++++++++++++++--------------------
 mm/page_isolation.c     | 19 ++++++-----
 mm/page_reporting.c     | 13 ++++----
 mm/show_mem.c           |  5 +--
 mm/shuffle.c            |  9 ++---
 mm/vmscan.c             |  5 +--
 mm/vmstat.c             |  9 ++---
 11 files changed, 94 insertions(+), 81 deletions(-)

diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 6e1321837c66..7dcccf378cc2 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -13,6 +13,7 @@
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/mm.h>
+#include <linux/mmzone_lock.h>
 #include <linux/suspend.h>
 #include <linux/delay.h>
 #include <linux/bitops.h>
@@ -1251,7 +1252,7 @@ static void mark_free_pages(struct zone *zone)
 	if (zone_is_empty(zone))
 		return;
 
-	spin_lock_irqsave(&zone->lock, flags);
+	zone_lock_irqsave(zone, flags);
 
 	max_zone_pfn = zone_end_pfn(zone);
 	for_each_valid_pfn(pfn, zone->zone_start_pfn, max_zone_pfn) {
@@ -1284,7 +1285,7 @@ static void mark_free_pages(struct zone *zone)
 			}
 		}
 	}
-	spin_unlock_irqrestore(&zone->lock, flags);
+	zone_unlock_irqrestore(zone, flags);
 }
 
 #ifdef CONFIG_HIGHMEM
diff --git a/mm/compaction.c b/mm/compaction.c
index 1e8f8eca318c..fa0e332a8a92 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -24,6 +24,7 @@
 #include <linux/page_owner.h>
 #include <linux/psi.h>
 #include <linux/cpuset.h>
+#include <linux/mmzone_lock.h>
 #include "internal.h"
 
 #ifdef CONFIG_COMPACTION
@@ -530,11 +531,14 @@ static bool compact_lock_irqsave(spinlock_t *lock, unsigned long *flags,
  * Returns true if compaction should abort due to fatal signal pending.
  * Returns false when compaction can continue.
  */
-static bool compact_unlock_should_abort(spinlock_t *lock,
-		unsigned long flags, bool *locked, struct compact_control *cc)
+
+static bool compact_unlock_should_abort(struct zone *zone,
+					unsigned long flags,
+					bool *locked,
+					struct compact_control *cc)
 {
 	if (*locked) {
-		spin_unlock_irqrestore(lock, flags);
+		zone_unlock_irqrestore(zone, flags);
 		*locked = false;
 	}
 
@@ -582,9 +586,8 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
 		 * contention, to give chance to IRQs. Abort if fatal signal
 		 * pending.
 		 */
-		if (!(blockpfn % COMPACT_CLUSTER_MAX)
-		    && compact_unlock_should_abort(&cc->zone->lock, flags,
-								&locked, cc))
+		if (!(blockpfn % COMPACT_CLUSTER_MAX) &&
+		    compact_unlock_should_abort(cc->zone, flags, &locked, cc))
 			break;
 
 		nr_scanned++;
@@ -649,7 +652,7 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
 	}
 
 	if (locked)
-		spin_unlock_irqrestore(&cc->zone->lock, flags);
+		zone_unlock_irqrestore(cc->zone, flags);
 
 	/*
 	 * Be careful to not go outside of the pageblock.
@@ -1555,7 +1558,7 @@ static void fast_isolate_freepages(struct compact_control *cc)
 		if (!area->nr_free)
 			continue;
 
-		spin_lock_irqsave(&cc->zone->lock, flags);
+		zone_lock_irqsave(cc->zone, flags);
 		freelist = &area->free_list[MIGRATE_MOVABLE];
 		list_for_each_entry_reverse(freepage, freelist, buddy_list) {
 			unsigned long pfn;
@@ -1614,7 +1617,7 @@ static void fast_isolate_freepages(struct compact_control *cc)
 			}
 		}
 
-		spin_unlock_irqrestore(&cc->zone->lock, flags);
+		zone_unlock_irqrestore(cc->zone, flags);
 
 		/* Skip fast search if enough freepages isolated */
 		if (cc->nr_freepages >= cc->nr_migratepages)
@@ -1988,7 +1991,7 @@ static unsigned long fast_find_migrateblock(struct compact_control *cc)
 		if (!area->nr_free)
 			continue;
 
-		spin_lock_irqsave(&cc->zone->lock, flags);
+		zone_lock_irqsave(cc->zone, flags);
 		freelist = &area->free_list[MIGRATE_MOVABLE];
 		list_for_each_entry(freepage, freelist, buddy_list) {
 			unsigned long free_pfn;
@@ -2021,7 +2024,7 @@ static unsigned long fast_find_migrateblock(struct compact_control *cc)
 				break;
 			}
 		}
-		spin_unlock_irqrestore(&cc->zone->lock, flags);
+		zone_unlock_irqrestore(cc->zone, flags);
 	}
 
 	cc->total_migrate_scanned += nr_scanned;
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index bc805029da51..36564e2fcef8 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -36,6 +36,7 @@
 #include <linux/rmap.h>
 #include <linux/module.h>
 #include <linux/node.h>
+#include <linux/mmzone_lock.h>
 
 #include <asm/tlbflush.h>
 
@@ -1190,9 +1191,9 @@ int online_pages(unsigned long pfn, unsigned long nr_pages,
 	 * Fixup the number of isolated pageblocks before marking the sections
 	 * onlining, such that undo_isolate_page_range() works correctly.
 	 */
-	spin_lock_irqsave(&zone->lock, flags);
+	zone_lock_irqsave(zone, flags);
 	zone->nr_isolate_pageblock += nr_pages / pageblock_nr_pages;
-	spin_unlock_irqrestore(&zone->lock, flags);
+	zone_unlock_irqrestore(zone, flags);
 
 	/*
 	 * If this zone is not populated, then it is not in zonelist.
@@ -2041,9 +2042,9 @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages,
 	 * effectively stale; nobody should be touching them. Fixup the number
 	 * of isolated pageblocks, memory onlining will properly revert this.
 	 */
-	spin_lock_irqsave(&zone->lock, flags);
+	zone_lock_irqsave(zone, flags);
 	zone->nr_isolate_pageblock -= nr_pages / pageblock_nr_pages;
-	spin_unlock_irqrestore(&zone->lock, flags);
+	zone_unlock_irqrestore(zone, flags);
 
 	lru_cache_enable();
 	zone_pcp_enable(zone);
diff --git a/mm/mm_init.c b/mm/mm_init.c
index 61d983d23f55..fe494514ce03 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -32,6 +32,7 @@
 #include <linux/vmstat.h>
 #include <linux/kexec_handover.h>
 #include <linux/hugetlb.h>
+#include <linux/mmzone_lock.h>
 #include "internal.h"
 #include "slab.h"
 #include "shuffle.h"
@@ -1425,7 +1426,7 @@ static void __meminit zone_init_internals(struct zone *zone, enum zone_type idx,
 	zone_set_nid(zone, nid);
 	zone->name = zone_names[idx];
 	zone->zone_pgdat = NODE_DATA(nid);
-	spin_lock_init(&zone->lock);
+	zone_lock_init(zone);
 	zone_seqlock_init(zone);
 	zone_pcp_init(zone);
 }
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index fcc32737f451..bcc3fe0368fc 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -54,6 +54,7 @@
 #include <linux/delayacct.h>
 #include <linux/cacheinfo.h>
 #include <linux/pgalloc_tag.h>
+#include <linux/mmzone_lock.h>
 #include <asm/div64.h>
 #include "internal.h"
 #include "shuffle.h"
@@ -1500,7 +1501,7 @@ static void free_pcppages_bulk(struct zone *zone, int count,
 	/* Ensure requested pindex is drained first. */
 	pindex = pindex - 1;
 
-	spin_lock_irqsave(&zone->lock, flags);
+	zone_lock_irqsave(zone, flags);
 
 	while (count > 0) {
 		struct list_head *list;
@@ -1533,7 +1534,7 @@ static void free_pcppages_bulk(struct zone *zone, int count,
 		} while (count > 0 && !list_empty(list));
 	}
 
-	spin_unlock_irqrestore(&zone->lock, flags);
+	zone_unlock_irqrestore(zone, flags);
 }
 
 /* Split a multi-block free page into its individual pageblocks. */
@@ -1577,12 +1578,12 @@ static void free_one_page(struct zone *zone, struct page *page,
 	unsigned long flags;
 
 	if (unlikely(fpi_flags & FPI_TRYLOCK)) {
-		if (!spin_trylock_irqsave(&zone->lock, flags)) {
+		if (!zone_trylock_irqsave(zone, flags)) {
 			add_page_to_zone_llist(zone, page, order);
 			return;
 		}
 	} else {
-		spin_lock_irqsave(&zone->lock, flags);
+		zone_lock_irqsave(zone, flags);
 	}
 
 	/* The lock succeeded. Process deferred pages. */
@@ -1600,7 +1601,7 @@ static void free_one_page(struct zone *zone, struct page *page,
 		}
 	}
 	split_large_buddy(zone, page, pfn, order, fpi_flags);
-	spin_unlock_irqrestore(&zone->lock, flags);
+	zone_unlock_irqrestore(zone, flags);
 
 	__count_vm_events(PGFREE, 1 << order);
 }
@@ -2553,10 +2554,10 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
 	int i;
 
 	if (unlikely(alloc_flags & ALLOC_TRYLOCK)) {
-		if (!spin_trylock_irqsave(&zone->lock, flags))
+		if (!zone_trylock_irqsave(zone, flags))
 			return 0;
 	} else {
-		spin_lock_irqsave(&zone->lock, flags);
+		zone_lock_irqsave(zone, flags);
 	}
 	for (i = 0; i < count; ++i) {
 		struct page *page = __rmqueue(zone, order, migratetype,
@@ -2576,7 +2577,7 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
 		 */
 		list_add_tail(&page->pcp_list, list);
 	}
-	spin_unlock_irqrestore(&zone->lock, flags);
+	zone_unlock_irqrestore(zone, flags);
 
 	return i;
 }
@@ -3246,10 +3247,10 @@ struct page *rmqueue_buddy(struct zone *preferred_zone, struct zone *zone,
 	do {
 		page = NULL;
 		if (unlikely(alloc_flags & ALLOC_TRYLOCK)) {
-			if (!spin_trylock_irqsave(&zone->lock, flags))
+			if (!zone_trylock_irqsave(zone, flags))
 				return NULL;
 		} else {
-			spin_lock_irqsave(&zone->lock, flags);
+			zone_lock_irqsave(zone, flags);
 		}
 		if (alloc_flags & ALLOC_HIGHATOMIC)
 			page = __rmqueue_smallest(zone, order, MIGRATE_HIGHATOMIC);
@@ -3268,11 +3269,11 @@ struct page *rmqueue_buddy(struct zone *preferred_zone, struct zone *zone,
 				page = __rmqueue_smallest(zone, order, MIGRATE_HIGHATOMIC);
 
 			if (!page) {
-				spin_unlock_irqrestore(&zone->lock, flags);
+				zone_unlock_irqrestore(zone, flags);
 				return NULL;
 			}
 		}
-		spin_unlock_irqrestore(&zone->lock, flags);
+		zone_unlock_irqrestore(zone, flags);
 	} while (check_new_pages(page, order));
 
 	__count_zid_vm_events(PGALLOC, page_zonenum(page), 1 << order);
@@ -3459,7 +3460,7 @@ static void reserve_highatomic_pageblock(struct page *page, int order,
 	if (zone->nr_reserved_highatomic >= max_managed)
 		return;
 
-	spin_lock_irqsave(&zone->lock, flags);
+	zone_lock_irqsave(zone, flags);
 
 	/* Recheck the nr_reserved_highatomic limit under the lock */
 	if (zone->nr_reserved_highatomic >= max_managed)
@@ -3481,7 +3482,7 @@ static void reserve_highatomic_pageblock(struct page *page, int order,
 	}
 
 out_unlock:
-	spin_unlock_irqrestore(&zone->lock, flags);
+	zone_unlock_irqrestore(zone, flags);
 }
 
 /*
@@ -3514,7 +3515,7 @@ static bool unreserve_highatomic_pageblock(const struct alloc_context *ac,
 					pageblock_nr_pages)
 			continue;
 
-		spin_lock_irqsave(&zone->lock, flags);
+		zone_lock_irqsave(zone, flags);
 		for (order = 0; order < NR_PAGE_ORDERS; order++) {
 			struct free_area *area = &(zone->free_area[order]);
 			unsigned long size;
@@ -3562,11 +3563,11 @@ static bool unreserve_highatomic_pageblock(const struct alloc_context *ac,
 			 */
 			WARN_ON_ONCE(ret == -1);
 			if (ret > 0) {
-				spin_unlock_irqrestore(&zone->lock, flags);
+				zone_unlock_irqrestore(zone, flags);
 				return ret;
 			}
 		}
-		spin_unlock_irqrestore(&zone->lock, flags);
+		zone_unlock_irqrestore(zone, flags);
 	}
 
 	return false;
@@ -6446,7 +6447,7 @@ static void __setup_per_zone_wmarks(void)
 	for_each_zone(zone) {
 		u64 tmp;
 
-		spin_lock_irqsave(&zone->lock, flags);
+		zone_lock_irqsave(zone, flags);
 		tmp = (u64)pages_min * zone_managed_pages(zone);
 		tmp = div64_ul(tmp, lowmem_pages);
 		if (is_highmem(zone) || zone_idx(zone) == ZONE_MOVABLE) {
@@ -6487,7 +6488,7 @@ static void __setup_per_zone_wmarks(void)
 		zone->_watermark[WMARK_PROMO] = high_wmark_pages(zone) + tmp;
 		trace_mm_setup_per_zone_wmarks(zone);
 
-		spin_unlock_irqrestore(&zone->lock, flags);
+		zone_unlock_irqrestore(zone, flags);
 	}
 
 	/* update totalreserve_pages */
@@ -7257,7 +7258,7 @@ struct page *alloc_contig_frozen_pages_noprof(unsigned long nr_pages,
 	zonelist = node_zonelist(nid, gfp_mask);
 	for_each_zone_zonelist_nodemask(zone, z, zonelist,
 					gfp_zone(gfp_mask), nodemask) {
-		spin_lock_irqsave(&zone->lock, flags);
+		zone_lock_irqsave(zone, flags);
 
 		pfn = ALIGN(zone->zone_start_pfn, nr_pages);
 		while (zone_spans_last_pfn(zone, pfn, nr_pages)) {
@@ -7271,18 +7272,18 @@ struct page *alloc_contig_frozen_pages_noprof(unsigned long nr_pages,
 				 * allocation spinning on this lock, it may
 				 * win the race and cause allocation to fail.
 				 */
-				spin_unlock_irqrestore(&zone->lock, flags);
+				zone_unlock_irqrestore(zone, flags);
 				ret = alloc_contig_frozen_range_noprof(pfn,
 							pfn + nr_pages,
 							ACR_FLAGS_NONE,
 							gfp_mask);
 				if (!ret)
 					return pfn_to_page(pfn);
-				spin_lock_irqsave(&zone->lock, flags);
+				zone_lock_irqsave(zone, flags);
 			}
 			pfn += nr_pages;
 		}
-		spin_unlock_irqrestore(&zone->lock, flags);
+		zone_unlock_irqrestore(zone, flags);
 	}
 	/*
 	 * If we failed, retry the search, but treat regions with HugeTLB pages
@@ -7436,7 +7437,7 @@ unsigned long __offline_isolated_pages(unsigned long start_pfn,
 
 	offline_mem_sections(pfn, end_pfn);
 	zone = page_zone(pfn_to_page(pfn));
-	spin_lock_irqsave(&zone->lock, flags);
+	zone_lock_irqsave(zone, flags);
 	while (pfn < end_pfn) {
 		page = pfn_to_page(pfn);
 		/*
@@ -7466,7 +7467,7 @@ unsigned long __offline_isolated_pages(unsigned long start_pfn,
 		del_page_from_free_list(page, zone, order, MIGRATE_ISOLATE);
 		pfn += (1 << order);
 	}
-	spin_unlock_irqrestore(&zone->lock, flags);
+	zone_unlock_irqrestore(zone, flags);
 
 	return end_pfn - start_pfn - already_offline;
 }
@@ -7542,7 +7543,7 @@ bool take_page_off_buddy(struct page *page)
 	unsigned int order;
 	bool ret = false;
 
-	spin_lock_irqsave(&zone->lock, flags);
+	zone_lock_irqsave(zone, flags);
 	for (order = 0; order < NR_PAGE_ORDERS; order++) {
 		struct page *page_head = page - (pfn & ((1 << order) - 1));
 		int page_order = buddy_order(page_head);
@@ -7563,7 +7564,7 @@ bool take_page_off_buddy(struct page *page)
 		if (page_count(page_head) > 0)
 			break;
 	}
-	spin_unlock_irqrestore(&zone->lock, flags);
+	zone_unlock_irqrestore(zone, flags);
 	return ret;
 }
 
@@ -7576,7 +7577,7 @@ bool put_page_back_buddy(struct page *page)
 	unsigned long flags;
 	bool ret = false;
 
-	spin_lock_irqsave(&zone->lock, flags);
+	zone_lock_irqsave(zone, flags);
 	if (put_page_testzero(page)) {
 		unsigned long pfn = page_to_pfn(page);
 		int migratetype = get_pfnblock_migratetype(page, pfn);
@@ -7587,7 +7588,7 @@ bool put_page_back_buddy(struct page *page)
 			ret = true;
 		}
 	}
-	spin_unlock_irqrestore(&zone->lock, flags);
+	zone_unlock_irqrestore(zone, flags);
 
 	return ret;
 }
@@ -7636,7 +7637,7 @@ static void __accept_page(struct zone *zone, unsigned long *flags,
 	account_freepages(zone, -MAX_ORDER_NR_PAGES, MIGRATE_MOVABLE);
 	__mod_zone_page_state(zone, NR_UNACCEPTED, -MAX_ORDER_NR_PAGES);
 	__ClearPageUnaccepted(page);
-	spin_unlock_irqrestore(&zone->lock, *flags);
+	zone_unlock_irqrestore(zone, *flags);
 
 	accept_memory(page_to_phys(page), PAGE_SIZE << MAX_PAGE_ORDER);
 
@@ -7648,9 +7649,9 @@ void accept_page(struct page *page)
 	struct zone *zone = page_zone(page);
 	unsigned long flags;
 
-	spin_lock_irqsave(&zone->lock, flags);
+	zone_lock_irqsave(zone, flags);
 	if (!PageUnaccepted(page)) {
-		spin_unlock_irqrestore(&zone->lock, flags);
+		zone_unlock_irqrestore(zone, flags);
 		return;
 	}
 
@@ -7663,11 +7664,11 @@ static bool try_to_accept_memory_one(struct zone *zone)
 	unsigned long flags;
 	struct page *page;
 
-	spin_lock_irqsave(&zone->lock, flags);
+	zone_lock_irqsave(zone, flags);
 	page = list_first_entry_or_null(&zone->unaccepted_pages,
 					struct page, lru);
 	if (!page) {
-		spin_unlock_irqrestore(&zone->lock, flags);
+		zone_unlock_irqrestore(zone, flags);
 		return false;
 	}
 
@@ -7724,12 +7725,12 @@ static bool __free_unaccepted(struct page *page)
 	if (!lazy_accept)
 		return false;
 
-	spin_lock_irqsave(&zone->lock, flags);
+	zone_lock_irqsave(zone, flags);
 	list_add_tail(&page->lru, &zone->unaccepted_pages);
 	account_freepages(zone, MAX_ORDER_NR_PAGES, MIGRATE_MOVABLE);
 	__mod_zone_page_state(zone, NR_UNACCEPTED, MAX_ORDER_NR_PAGES);
 	__SetPageUnaccepted(page);
-	spin_unlock_irqrestore(&zone->lock, flags);
+	zone_unlock_irqrestore(zone, flags);
 
 	return true;
 }
diff --git a/mm/page_isolation.c b/mm/page_isolation.c
index c48ff5c00244..91a0836bf1b7 100644
--- a/mm/page_isolation.c
+++ b/mm/page_isolation.c
@@ -10,6 +10,7 @@
 #include <linux/hugetlb.h>
 #include <linux/page_owner.h>
 #include <linux/migrate.h>
+#include <linux/mmzone_lock.h>
 #include "internal.h"
 
 #define CREATE_TRACE_POINTS
@@ -173,7 +174,7 @@ static int set_migratetype_isolate(struct page *page, enum pb_isolate_mode mode,
 	if (PageUnaccepted(page))
 		accept_page(page);
 
-	spin_lock_irqsave(&zone->lock, flags);
+	zone_lock_irqsave(zone, flags);
 
 	/*
 	 * We assume the caller intended to SET migrate type to isolate.
@@ -181,7 +182,7 @@ static int set_migratetype_isolate(struct page *page, enum pb_isolate_mode mode,
 	 * set it before us.
 	 */
 	if (is_migrate_isolate_page(page)) {
-		spin_unlock_irqrestore(&zone->lock, flags);
+		zone_unlock_irqrestore(zone, flags);
 		return -EBUSY;
 	}
 
@@ -200,15 +201,15 @@ static int set_migratetype_isolate(struct page *page, enum pb_isolate_mode mode,
 			mode);
 	if (!unmovable) {
 		if (!pageblock_isolate_and_move_free_pages(zone, page)) {
-			spin_unlock_irqrestore(&zone->lock, flags);
+			zone_unlock_irqrestore(zone, flags);
 			return -EBUSY;
 		}
 		zone->nr_isolate_pageblock++;
-		spin_unlock_irqrestore(&zone->lock, flags);
+		zone_unlock_irqrestore(zone, flags);
 		return 0;
 	}
 
-	spin_unlock_irqrestore(&zone->lock, flags);
+	zone_unlock_irqrestore(zone, flags);
 	if (mode == PB_ISOLATE_MODE_MEM_OFFLINE) {
 		/*
 		 * printk() with zone->lock held will likely trigger a
@@ -229,7 +230,7 @@ static void unset_migratetype_isolate(struct page *page)
 	struct page *buddy;
 
 	zone = page_zone(page);
-	spin_lock_irqsave(&zone->lock, flags);
+	zone_lock_irqsave(zone, flags);
 	if (!is_migrate_isolate_page(page))
 		goto out;
 
@@ -280,7 +281,7 @@ static void unset_migratetype_isolate(struct page *page)
 	}
 	zone->nr_isolate_pageblock--;
 out:
-	spin_unlock_irqrestore(&zone->lock, flags);
+	zone_unlock_irqrestore(zone, flags);
 }
 
 static inline struct page *
@@ -641,9 +642,9 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn,
 
 	/* Check all pages are free or marked as ISOLATED */
 	zone = page_zone(page);
-	spin_lock_irqsave(&zone->lock, flags);
+	zone_lock_irqsave(zone, flags);
 	pfn = __test_page_isolated_in_pageblock(start_pfn, end_pfn, mode);
-	spin_unlock_irqrestore(&zone->lock, flags);
+	zone_unlock_irqrestore(zone, flags);
 
 	ret = pfn < end_pfn ? -EBUSY : 0;
 
diff --git a/mm/page_reporting.c b/mm/page_reporting.c
index f0042d5743af..43976a9dce3f 100644
--- a/mm/page_reporting.c
+++ b/mm/page_reporting.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/mm.h>
 #include <linux/mmzone.h>
+#include <linux/mmzone_lock.h>
 #include <linux/page_reporting.h>
 #include <linux/gfp.h>
 #include <linux/export.h>
@@ -161,7 +162,7 @@ page_reporting_cycle(struct page_reporting_dev_info *prdev, struct zone *zone,
 	if (list_empty(list))
 		return err;
 
-	spin_lock_irq(&zone->lock);
+	zone_lock_irq(zone);
 
 	/*
 	 * Limit how many calls we will be making to the page reporting
@@ -219,7 +220,7 @@ page_reporting_cycle(struct page_reporting_dev_info *prdev, struct zone *zone,
 			list_rotate_to_front(&page->lru, list);
 
 		/* release lock before waiting on report processing */
-		spin_unlock_irq(&zone->lock);
+		zone_unlock_irq(zone);
 
 		/* begin processing pages in local list */
 		err = prdev->report(prdev, sgl, PAGE_REPORTING_CAPACITY);
@@ -231,7 +232,7 @@ page_reporting_cycle(struct page_reporting_dev_info *prdev, struct zone *zone,
 		budget--;
 
 		/* reacquire zone lock and resume processing */
-		spin_lock_irq(&zone->lock);
+		zone_lock_irq(zone);
 
 		/* flush reported pages from the sg list */
 		page_reporting_drain(prdev, sgl, PAGE_REPORTING_CAPACITY, !err);
@@ -251,7 +252,7 @@ page_reporting_cycle(struct page_reporting_dev_info *prdev, struct zone *zone,
 	if (!list_entry_is_head(next, list, lru) && !list_is_first(&next->lru, list))
 		list_rotate_to_front(&next->lru, list);
 
-	spin_unlock_irq(&zone->lock);
+	zone_unlock_irq(zone);
 
 	return err;
 }
@@ -296,9 +297,9 @@ page_reporting_process_zone(struct page_reporting_dev_info *prdev,
 		err = prdev->report(prdev, sgl, leftover);
 
 		/* flush any remaining pages out from the last report */
-		spin_lock_irq(&zone->lock);
+		zone_lock_irq(zone);
 		page_reporting_drain(prdev, sgl, leftover, !err);
-		spin_unlock_irq(&zone->lock);
+		zone_unlock_irq(zone);
 	}
 
 	return err;
diff --git a/mm/show_mem.c b/mm/show_mem.c
index 24078ac3e6bc..d7d1b6cd6442 100644
--- a/mm/show_mem.c
+++ b/mm/show_mem.c
@@ -12,6 +12,7 @@
 #include <linux/hugetlb.h>
 #include <linux/mm.h>
 #include <linux/mmzone.h>
+#include <linux/mmzone_lock.h>
 #include <linux/swap.h>
 #include <linux/vmstat.h>
 
@@ -363,7 +364,7 @@ static void show_free_areas(unsigned int filter, nodemask_t *nodemask, int max_z
 		show_node(zone);
 		printk(KERN_CONT "%s: ", zone->name);
 
-		spin_lock_irqsave(&zone->lock, flags);
+		zone_lock_irqsave(zone, flags);
 		for (order = 0; order < NR_PAGE_ORDERS; order++) {
 			struct free_area *area = &zone->free_area[order];
 			int type;
@@ -377,7 +378,7 @@ static void show_free_areas(unsigned int filter, nodemask_t *nodemask, int max_z
 					types[order] |= 1 << type;
 			}
 		}
-		spin_unlock_irqrestore(&zone->lock, flags);
+		zone_unlock_irqrestore(zone, flags);
 		for (order = 0; order < NR_PAGE_ORDERS; order++) {
 			printk(KERN_CONT "%lu*%lukB ",
 			       nr[order], K(1UL) << order);
diff --git a/mm/shuffle.c b/mm/shuffle.c
index fb1393b8b3a9..5f6ae3c52842 100644
--- a/mm/shuffle.c
+++ b/mm/shuffle.c
@@ -4,6 +4,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/mmzone.h>
+#include <linux/mmzone_lock.h>
 #include <linux/random.h>
 #include <linux/moduleparam.h>
 #include "internal.h"
@@ -85,7 +86,7 @@ void __meminit __shuffle_zone(struct zone *z)
 	const int order = SHUFFLE_ORDER;
 	const int order_pages = 1 << order;
 
-	spin_lock_irqsave(&z->lock, flags);
+	zone_lock_irqsave(z, flags);
 	start_pfn = ALIGN(start_pfn, order_pages);
 	for (i = start_pfn; i < end_pfn; i += order_pages) {
 		unsigned long j;
@@ -138,12 +139,12 @@ void __meminit __shuffle_zone(struct zone *z)
 
 		/* take it easy on the zone lock */
 		if ((i % (100 * order_pages)) == 0) {
-			spin_unlock_irqrestore(&z->lock, flags);
+			zone_unlock_irqrestore(z, flags);
 			cond_resched();
-			spin_lock_irqsave(&z->lock, flags);
+			zone_lock_irqsave(z, flags);
 		}
 	}
-	spin_unlock_irqrestore(&z->lock, flags);
+	zone_unlock_irqrestore(z, flags);
 }
 
 /*
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 0fc9373e8251..44c70e4400e2 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -58,6 +58,7 @@
 #include <linux/random.h>
 #include <linux/mmu_notifier.h>
 #include <linux/parser.h>
+#include <linux/mmzone_lock.h>
 
 #include <asm/tlbflush.h>
 #include <asm/div64.h>
@@ -7139,9 +7140,9 @@ static int balance_pgdat(pg_data_t *pgdat, int order, int highest_zoneidx)
 
 			/* Increments are under the zone lock */
 			zone = pgdat->node_zones + i;
-			spin_lock_irqsave(&zone->lock, flags);
+			zone_lock_irqsave(zone, flags);
 			zone->watermark_boost -= min(zone->watermark_boost, zone_boosts[i]);
-			spin_unlock_irqrestore(&zone->lock, flags);
+			zone_unlock_irqrestore(zone, flags);
 		}
 
 		/*
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 86b14b0f77b5..6608bb489790 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -28,6 +28,7 @@
 #include <linux/mm_inline.h>
 #include <linux/page_owner.h>
 #include <linux/sched/isolation.h>
+#include <linux/mmzone_lock.h>
 
 #include "internal.h"
 
@@ -1535,10 +1536,10 @@ static void walk_zones_in_node(struct seq_file *m, pg_data_t *pgdat,
 			continue;
 
 		if (!nolock)
-			spin_lock_irqsave(&zone->lock, flags);
+			zone_lock_irqsave(zone, flags);
 		print(m, pgdat, zone);
 		if (!nolock)
-			spin_unlock_irqrestore(&zone->lock, flags);
+			zone_unlock_irqrestore(zone, flags);
 	}
 }
 #endif
@@ -1603,9 +1604,9 @@ static void pagetypeinfo_showfree_print(struct seq_file *m,
 				}
 			}
 			seq_printf(m, "%s%6lu ", overflow ? ">" : "", freecount);
-			spin_unlock_irq(&zone->lock);
+			zone_unlock_irq(zone);
 			cond_resched();
-			spin_lock_irq(&zone->lock);
+			zone_lock_irq(zone);
 		}
 		seq_putc(m, '\n');
 	}
-- 
2.47.3


^ permalink raw reply related

* [PATCH v4 4/5] mm: rename zone->lock to zone->_lock
From: Dmitry Ilvokhin @ 2026-02-27 16:00 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Axel Rasmussen, Yuanchu Xie,
	Wei Xu, Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
	Rafael J. Wysocki, Pavel Machek, Len Brown, Brendan Jackman,
	Johannes Weiner, Zi Yan, Oscar Salvador, Qi Zheng, Shakeel Butt
  Cc: linux-kernel, linux-mm, linux-trace-kernel, linux-pm,
	"linux-cxl, Dmitry Ilvokhin, SeongJae Park
In-Reply-To: <cover.1772206930.git.d@ilvokhin.com>

This intentionally breaks direct users of zone->lock at compile time so
all call sites are converted to the zone lock wrappers. Without the
rename, present and future out-of-tree code could continue using
spin_lock(&zone->lock) and bypass the wrappers and tracing
infrastructure.

No functional change intended.

Suggested-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
Acked-by: SeongJae Park <sj@kernel.org>
---
 include/linux/mmzone.h      |  7 +++++--
 include/linux/mmzone_lock.h | 12 ++++++------
 mm/compaction.c             |  4 ++--
 mm/internal.h               |  2 +-
 mm/page_alloc.c             | 16 ++++++++--------
 mm/page_isolation.c         |  4 ++--
 mm/page_owner.c             |  2 +-
 7 files changed, 25 insertions(+), 22 deletions(-)

diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 3e51190a55e4..32bca655fce5 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -1009,8 +1009,11 @@ struct zone {
 	/* zone flags, see below */
 	unsigned long		flags;
 
-	/* Primarily protects free_area */
-	spinlock_t		lock;
+	/*
+	 * Primarily protects free_area. Should be accessed via zone_lock_*
+	 * helpers.
+	 */
+	spinlock_t		_lock;
 
 	/* Pages to be freed when next trylock succeeds */
 	struct llist_head	trylock_free_pages;
diff --git a/include/linux/mmzone_lock.h b/include/linux/mmzone_lock.h
index a1cfba8408d6..62e34d500078 100644
--- a/include/linux/mmzone_lock.h
+++ b/include/linux/mmzone_lock.h
@@ -7,32 +7,32 @@
 
 static inline void zone_lock_init(struct zone *zone)
 {
-	spin_lock_init(&zone->lock);
+	spin_lock_init(&zone->_lock);
 }
 
 #define zone_lock_irqsave(zone, flags)				\
 do {								\
-	spin_lock_irqsave(&(zone)->lock, flags);		\
+	spin_lock_irqsave(&(zone)->_lock, flags);		\
 } while (0)
 
 #define zone_trylock_irqsave(zone, flags)			\
 ({								\
-	spin_trylock_irqsave(&(zone)->lock, flags);		\
+	spin_trylock_irqsave(&(zone)->_lock, flags);		\
 })
 
 static inline void zone_unlock_irqrestore(struct zone *zone, unsigned long flags)
 {
-	spin_unlock_irqrestore(&zone->lock, flags);
+	spin_unlock_irqrestore(&zone->_lock, flags);
 }
 
 static inline void zone_lock_irq(struct zone *zone)
 {
-	spin_lock_irq(&zone->lock);
+	spin_lock_irq(&zone->_lock);
 }
 
 static inline void zone_unlock_irq(struct zone *zone)
 {
-	spin_unlock_irq(&zone->lock);
+	spin_unlock_irq(&zone->_lock);
 }
 
 #endif /* _LINUX_MMZONE_LOCK_H */
diff --git a/mm/compaction.c b/mm/compaction.c
index c68fcc416fc7..ac2a259518b1 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -506,7 +506,7 @@ static bool test_and_set_skip(struct compact_control *cc, struct page *page)
 static bool compact_zone_lock_irqsave(struct zone *zone,
 				      unsigned long *flags,
 				      struct compact_control *cc)
-	__acquires(&zone->lock)
+	__acquires(&zone->_lock)
 {
 	/* Track if the lock is contended in async mode */
 	if (cc->mode == MIGRATE_ASYNC && !cc->contended) {
@@ -1402,7 +1402,7 @@ static bool suitable_migration_target(struct compact_control *cc,
 		int order = cc->order > 0 ? cc->order : pageblock_order;
 
 		/*
-		 * We are checking page_order without zone->lock taken. But
+		 * We are checking page_order without zone->_lock taken. But
 		 * the only small danger is that we skip a potentially suitable
 		 * pageblock, so it's not worth to check order for valid range.
 		 */
diff --git a/mm/internal.h b/mm/internal.h
index cb0af847d7d9..6cb06e21ce15 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -710,7 +710,7 @@ static inline unsigned int buddy_order(struct page *page)
  * (d) a page and its buddy are in the same zone.
  *
  * For recording whether a page is in the buddy system, we set PageBuddy.
- * Setting, clearing, and testing PageBuddy is serialized by zone->lock.
+ * Setting, clearing, and testing PageBuddy is serialized by zone->_lock.
  *
  * For recording page's order, we use page_private(page).
  */
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index bcc3fe0368fc..0d078aef8ed6 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -815,7 +815,7 @@ compaction_capture(struct capture_control *capc, struct page *page,
 static inline void account_freepages(struct zone *zone, int nr_pages,
 				     int migratetype)
 {
-	lockdep_assert_held(&zone->lock);
+	lockdep_assert_held(&zone->_lock);
 
 	if (is_migrate_isolate(migratetype))
 		return;
@@ -2473,7 +2473,7 @@ enum rmqueue_mode {
 
 /*
  * Do the hard work of removing an element from the buddy allocator.
- * Call me with the zone->lock already held.
+ * Call me with the zone->_lock already held.
  */
 static __always_inline struct page *
 __rmqueue(struct zone *zone, unsigned int order, int migratetype,
@@ -2501,7 +2501,7 @@ __rmqueue(struct zone *zone, unsigned int order, int migratetype,
 	 * fallbacks modes with increasing levels of fragmentation risk.
 	 *
 	 * The fallback logic is expensive and rmqueue_bulk() calls in
-	 * a loop with the zone->lock held, meaning the freelists are
+	 * a loop with the zone->_lock held, meaning the freelists are
 	 * not subject to any outside changes. Remember in *mode where
 	 * we found pay dirt, to save us the search on the next call.
 	 */
@@ -3203,7 +3203,7 @@ void __putback_isolated_page(struct page *page, unsigned int order, int mt)
 	struct zone *zone = page_zone(page);
 
 	/* zone lock should be held when this function is called */
-	lockdep_assert_held(&zone->lock);
+	lockdep_assert_held(&zone->_lock);
 
 	/* Return isolated page to tail of freelist. */
 	__free_one_page(page, page_to_pfn(page), zone, order, mt,
@@ -7086,7 +7086,7 @@ int alloc_contig_frozen_range_noprof(unsigned long start, unsigned long end,
 	 * pages.  Because of this, we reserve the bigger range and
 	 * once this is done free the pages we are not interested in.
 	 *
-	 * We don't have to hold zone->lock here because the pages are
+	 * We don't have to hold zone->_lock here because the pages are
 	 * isolated thus they won't get removed from buddy.
 	 */
 	outer_start = find_large_buddy(start);
@@ -7655,7 +7655,7 @@ void accept_page(struct page *page)
 		return;
 	}
 
-	/* Unlocks zone->lock */
+	/* Unlocks zone->_lock */
 	__accept_page(zone, &flags, page);
 }
 
@@ -7672,7 +7672,7 @@ static bool try_to_accept_memory_one(struct zone *zone)
 		return false;
 	}
 
-	/* Unlocks zone->lock */
+	/* Unlocks zone->_lock */
 	__accept_page(zone, &flags, page);
 
 	return true;
@@ -7813,7 +7813,7 @@ struct page *alloc_frozen_pages_nolock_noprof(gfp_t gfp_flags, int nid, unsigned
 
 	/*
 	 * Best effort allocation from percpu free list.
-	 * If it's empty attempt to spin_trylock zone->lock.
+	 * If it's empty attempt to spin_trylock zone->_lock.
 	 */
 	page = get_page_from_freelist(alloc_gfp, order, alloc_flags, &ac);
 
diff --git a/mm/page_isolation.c b/mm/page_isolation.c
index 91a0836bf1b7..cf731370e7a7 100644
--- a/mm/page_isolation.c
+++ b/mm/page_isolation.c
@@ -212,7 +212,7 @@ static int set_migratetype_isolate(struct page *page, enum pb_isolate_mode mode,
 	zone_unlock_irqrestore(zone, flags);
 	if (mode == PB_ISOLATE_MODE_MEM_OFFLINE) {
 		/*
-		 * printk() with zone->lock held will likely trigger a
+		 * printk() with zone->_lock held will likely trigger a
 		 * lockdep splat, so defer it here.
 		 */
 		dump_page(unmovable, "unmovable page");
@@ -553,7 +553,7 @@ void undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn)
 /*
  * Test all pages in the range is free(means isolated) or not.
  * all pages in [start_pfn...end_pfn) must be in the same zone.
- * zone->lock must be held before call this.
+ * zone->_lock must be held before call this.
  *
  * Returns the last tested pfn.
  */
diff --git a/mm/page_owner.c b/mm/page_owner.c
index 8178e0be557f..54a4ba63b14f 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -799,7 +799,7 @@ static void init_pages_in_zone(struct zone *zone)
 				continue;
 
 			/*
-			 * To avoid having to grab zone->lock, be a little
+			 * To avoid having to grab zone->_lock, be a little
 			 * careful when reading buddy page order. The only
 			 * danger is that we skip too much and potentially miss
 			 * some early allocated pages, which is better than
-- 
2.47.3


^ permalink raw reply related

* [PATCH v4 3/5] mm: convert compaction to zone lock wrappers
From: Dmitry Ilvokhin @ 2026-02-27 16:00 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Axel Rasmussen, Yuanchu Xie,
	Wei Xu, Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
	Rafael J. Wysocki, Pavel Machek, Len Brown, Brendan Jackman,
	Johannes Weiner, Zi Yan, Oscar Salvador, Qi Zheng, Shakeel Butt
  Cc: linux-kernel, linux-mm, linux-trace-kernel, linux-pm,
	"linux-cxl, Dmitry Ilvokhin
In-Reply-To: <cover.1772206930.git.d@ilvokhin.com>

Compaction uses compact_lock_irqsave(), which currently operates
on a raw spinlock_t pointer so it can be used for both zone->lock
and lruvec->lru_lock. Since zone lock operations are now wrapped,
compact_lock_irqsave() can no longer directly operate on a
spinlock_t when the lock belongs to a zone.

Split the helper into compact_zone_lock_irqsave() and
compact_lruvec_lock_irqsave(), duplicating the small amount of
shared logic. As there are only two call sites and both statically
know the lock type, this avoids introducing additional abstraction
or runtime dispatch in the compaction path.

No functional change intended.

Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
---
 mm/compaction.c | 33 ++++++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/mm/compaction.c b/mm/compaction.c
index fa0e332a8a92..c68fcc416fc7 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -503,19 +503,36 @@ static bool test_and_set_skip(struct compact_control *cc, struct page *page)
  *
  * Always returns true which makes it easier to track lock state in callers.
  */
-static bool compact_lock_irqsave(spinlock_t *lock, unsigned long *flags,
-						struct compact_control *cc)
-	__acquires(lock)
+static bool compact_zone_lock_irqsave(struct zone *zone,
+				      unsigned long *flags,
+				      struct compact_control *cc)
+	__acquires(&zone->lock)
 {
 	/* Track if the lock is contended in async mode */
 	if (cc->mode == MIGRATE_ASYNC && !cc->contended) {
-		if (spin_trylock_irqsave(lock, *flags))
+		if (zone_trylock_irqsave(zone, *flags))
 			return true;
 
 		cc->contended = true;
 	}
 
-	spin_lock_irqsave(lock, *flags);
+	zone_lock_irqsave(zone, *flags);
+	return true;
+}
+
+static bool compact_lruvec_lock_irqsave(struct lruvec *lruvec,
+					unsigned long *flags,
+					struct compact_control *cc)
+	__acquires(&lruvec->lru_lock)
+{
+	if (cc->mode == MIGRATE_ASYNC && !cc->contended) {
+		if (spin_trylock_irqsave(&lruvec->lru_lock, *flags))
+			return true;
+
+		cc->contended = true;
+	}
+
+	spin_lock_irqsave(&lruvec->lru_lock, *flags);
 	return true;
 }
 
@@ -531,7 +548,6 @@ static bool compact_lock_irqsave(spinlock_t *lock, unsigned long *flags,
  * Returns true if compaction should abort due to fatal signal pending.
  * Returns false when compaction can continue.
  */
-
 static bool compact_unlock_should_abort(struct zone *zone,
 					unsigned long flags,
 					bool *locked,
@@ -616,8 +632,7 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
 
 		/* If we already hold the lock, we can skip some rechecking. */
 		if (!locked) {
-			locked = compact_lock_irqsave(&cc->zone->lock,
-								&flags, cc);
+			locked = compact_zone_lock_irqsave(cc->zone, &flags, cc);
 
 			/* Recheck this is a buddy page under lock */
 			if (!PageBuddy(page))
@@ -1163,7 +1178,7 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
 			if (locked)
 				unlock_page_lruvec_irqrestore(locked, flags);
 
-			compact_lock_irqsave(&lruvec->lru_lock, &flags, cc);
+			compact_lruvec_lock_irqsave(lruvec, &flags, cc);
 			locked = lruvec;
 
 			lruvec_memcg_debug(lruvec, folio);
-- 
2.47.3


^ permalink raw reply related

* [PATCH v4 1/5] mm: introduce zone lock wrappers
From: Dmitry Ilvokhin @ 2026-02-27 16:00 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Axel Rasmussen, Yuanchu Xie,
	Wei Xu, Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
	Rafael J. Wysocki, Pavel Machek, Len Brown, Brendan Jackman,
	Johannes Weiner, Zi Yan, Oscar Salvador, Qi Zheng, Shakeel Butt
  Cc: linux-kernel, linux-mm, linux-trace-kernel, linux-pm,
	"linux-cxl, Dmitry Ilvokhin
In-Reply-To: <cover.1772206930.git.d@ilvokhin.com>

Add thin wrappers around zone lock acquire/release operations. This
prepares the code for future tracepoint instrumentation without
modifying individual call sites.

Centralizing zone lock operations behind wrappers allows future
instrumentation or debugging hooks to be added without touching
all users.

No functional change intended. The wrappers are introduced in
preparation for subsequent patches and are not yet used.

Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
---
 MAINTAINERS                 |  1 +
 include/linux/mmzone_lock.h | 38 +++++++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+)
 create mode 100644 include/linux/mmzone_lock.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 55af015174a5..947298ecb111 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16672,6 +16672,7 @@ F:	include/linux/memory.h
 F:	include/linux/mm.h
 F:	include/linux/mm_*.h
 F:	include/linux/mmzone.h
+F:	include/linux/mmzone_lock.h
 F:	include/linux/mmdebug.h
 F:	include/linux/mmu_notifier.h
 F:	include/linux/pagewalk.h
diff --git a/include/linux/mmzone_lock.h b/include/linux/mmzone_lock.h
new file mode 100644
index 000000000000..a1cfba8408d6
--- /dev/null
+++ b/include/linux/mmzone_lock.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_MMZONE_LOCK_H
+#define _LINUX_MMZONE_LOCK_H
+
+#include <linux/mmzone.h>
+#include <linux/spinlock.h>
+
+static inline void zone_lock_init(struct zone *zone)
+{
+	spin_lock_init(&zone->lock);
+}
+
+#define zone_lock_irqsave(zone, flags)				\
+do {								\
+	spin_lock_irqsave(&(zone)->lock, flags);		\
+} while (0)
+
+#define zone_trylock_irqsave(zone, flags)			\
+({								\
+	spin_trylock_irqsave(&(zone)->lock, flags);		\
+})
+
+static inline void zone_unlock_irqrestore(struct zone *zone, unsigned long flags)
+{
+	spin_unlock_irqrestore(&zone->lock, flags);
+}
+
+static inline void zone_lock_irq(struct zone *zone)
+{
+	spin_lock_irq(&zone->lock);
+}
+
+static inline void zone_unlock_irq(struct zone *zone)
+{
+	spin_unlock_irq(&zone->lock);
+}
+
+#endif /* _LINUX_MMZONE_LOCK_H */
-- 
2.47.3


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox