* Re: [PATCHv4 06/13] libbpf: Change has_nop_combo to work on top of nop10
From: bot+bpf-ci @ 2026-05-26 21:46 UTC (permalink / raw)
To: jolsa, oleg, peterz, mingo, mhiramat, andrii
Cc: jakub, bpf, linux-trace-kernel, ast, andrii, daniel, martin.lau,
eddyz87, yonghong.song, clm, ihor.solodrai
In-Reply-To: <20260526205840.173790-7-jolsa@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 2986 bytes --]
> commit 5ad96df841a0877eeca7d2cbe4b3f726b7fd0b72
> Author: Jiri Olsa <jolsa@kernel.org>
> Date: Tue May 26 22:58:33 2026 +0200
>
> libbpf: Change has_nop_combo to work on top of nop10
>
> We now expect nop combo with 10 bytes nop instead of 5 bytes nop,
> fixing has_nop_combo to reflect that.
>
> Fixes: 41a5c7df4466 ("libbpf: Add support to detect nop,nop5 instructions combo for usdt probe")
> Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com>
> Acked-by: Andrii Nakryiko <andrii@kernel.org>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
The Fixes: tag references commit 41a5c7df4466 which originally added
has_nop_combo() with correct nop5 support. However, the actual bug was
introduced by commit af734a7ddb4e which changed the kernel's uprobe
implementation from nop5 to nop10. Should the tag be:
Fixes: af734a7ddb4e ("uprobes/x86: Move optimized uprobe from nop5 to nop10")
> diff --git a/tools/lib/bpf/usdt.c b/tools/lib/bpf/usdt.c
> index e3710933fd52..484a4354e82b 100644
> --- a/tools/lib/bpf/usdt.c
> +++ b/tools/lib/bpf/usdt.c
> @@ -305,7 +305,7 @@ struct usdt_manager *usdt_manager_new(struct bpf_object *obj)
>
> /*
> * Detect kernel support for uprobe() syscall, it's presence means we can
> - * take advantage of faster nop5 uprobe handling.
> + * take advantage of faster nop10 uprobe handling.
> * Added in: 56101b69c919 ("uprobes/x86: Add uprobe syscall to speed up uprobe")
> */
The comment at the end of this block references commit 56101b69c919 which
added the uprobe syscall. Andrii Nakryiko noted in v3 review that it would
be good to also reference the commit that switches nop5 to nop10, though he
acknowledged the hash isn't stable until it lands. Now that af734a7ddb4e is
available, could this be updated to reference both commits?
> @@ -596,14 +596,14 @@ static int parse_usdt_spec(struct usdt_spec *spec, const struct usdt_note *note,
> #if defined(__x86_64__)
> static bool has_nop_combo(int fd, long off)
> {
> - unsigned char nop_combo[6] = {
> - 0x90, 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nop,nop5 */
> + unsigned char nop_combo[11] = {
> + 0x90, 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
> };
> - unsigned char buf[6];
> + unsigned char buf[11];
>
> - if (pread(fd, buf, 6, off) != 6)
> + if (pread(fd, buf, 11, off) != 11)
> return false;
> - return memcmp(buf, nop_combo, 6) == 0;
> + return memcmp(buf, nop_combo, 11) == 0;
> }
This isn't a bug, but Jakub Sitnicki suggested in v1 review using
ARRAY_SIZE(buf) instead of repeating the scalar value 11. The author
preferred keeping the literal number for simplicity, though the value
now appears in 5 locations (array declarations, pread size, pread check,
memcmp size).
[ ... ]
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/26475828601
^ permalink raw reply
* Re: [PATCHv4 09/13] selftests/bpf: Change uprobe syscall tests to use nop10
From: bot+bpf-ci @ 2026-05-26 21:46 UTC (permalink / raw)
To: jolsa, oleg, peterz, mingo, mhiramat, andrii
Cc: bpf, linux-trace-kernel, ast, andrii, daniel, martin.lau, eddyz87,
yonghong.song, clm, ihor.solodrai
In-Reply-To: <20260526205840.173790-10-jolsa@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 3728 bytes --]
> diff --git a/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c b/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c
> index c944136252c6..0868fb9793e0 100644
> --- a/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c
> +++ b/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c
[ ... ]
> @@ -388,14 +388,15 @@ static int find_uprobes_trampoline(void *tramp_addr)
> return ret;
> }
>
> -static unsigned char nop5[5] = { 0x0f, 0x1f, 0x44, 0x00, 0x00 };
> +static unsigned char nop10[10] = { 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
> +static unsigned char lea_rsp[5] = { 0x48, 0x8d, 0x64, 0x24, 0x80 };
>
> -static void *find_nop5(void *fn)
> +static void *find_nop10(void *fn)
> {
> int i;
>
> - for (i = 0; i < 10; i++) {
> - if (!memcmp(nop5, fn + i, 5))
> + for (i = 0; i < 128; i++) {
> + if (!memcmp(nop10, fn + i, 10))
> return fn + i;
> }
> return NULL;
[ ... ]
> diff --git a/tools/testing/selftests/bpf/prog_tests/usdt.c b/tools/testing/selftests/bpf/prog_tests/usdt.c
> index 69759b27794d..fda3a298ccfc 100644
> --- a/tools/testing/selftests/bpf/prog_tests/usdt.c
> +++ b/tools/testing/selftests/bpf/prog_tests/usdt.c
> @@ -252,7 +252,7 @@ extern void usdt_1(void);
> extern void usdt_2(void);
>
> static unsigned char nop1[1] = { 0x90 };
> -static unsigned char nop1_nop5_combo[6] = { 0x90, 0x0f, 0x1f, 0x44, 0x00, 0x00 };
> +static unsigned char nop1_nop10_combo[11] = { 0x90, 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
>
> static void *find_instr(void *fn, unsigned char *instr, size_t cnt)
> {
Is the loop in find_instr() adequate to find the updated instruction
sequence? In uprobe_syscall.c, find_nop10() was updated to search up
to 128 bytes to account for compiler-generated prologues:
tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c:find_nop10() {
for (i = 0; i < 128; i++) {
if (!memcmp(nop10, fn + i, 10))
return fn + i;
}
}
But find_instr() in usdt.c only searches the first 10 bytes:
tools/testing/selftests/bpf/prog_tests/usdt.c:find_instr() {
for (i = 0; i < 10; i++) {
if (!memcmp(instr, fn + i, cnt))
return fn + i;
}
}
If a modern compiler generates a prologue longer than 9 bytes for
usdt_2(), find_instr() will prematurely terminate and cause
subtest_optimized_attach() to fail. This concern was raised by
reviewers in v2 and v3 of the patch series:
https://lore.kernel.org/bpf/20260518111604.CC731C2BCB7@smtp.kernel.org/
The author acknowledged this with "yea find_instr needs same update,
will fix" but the loop bound remains 10 in the current v4 patch.
> @@ -271,17 +271,17 @@ static void subtest_optimized_attach(void)
> __u8 *addr_1, *addr_2;
>
> /* usdt_1 USDT probe has single nop instruction */
> - addr_1 = find_instr(usdt_1, nop1_nop5_combo, 6);
> - if (!ASSERT_NULL(addr_1, "usdt_1_find_nop1_nop5_combo"))
> + addr_1 = find_instr(usdt_1, nop1_nop10_combo, 11);
> + if (!ASSERT_NULL(addr_1, "usdt_1_find_nop1_nop10_combo"))
> return;
>
> addr_1 = find_instr(usdt_1, nop1, 1);
> if (!ASSERT_OK_PTR(addr_1, "usdt_1_find_nop1"))
> return;
>
> - /* usdt_2 USDT probe has nop,nop5 instructions combo */
> - addr_2 = find_instr(usdt_2, nop1_nop5_combo, 6);
> - if (!ASSERT_OK_PTR(addr_2, "usdt_2_find_nop1_nop5_combo"))
> + /* usdt_2 USDT probe has nop,nop10 instructions combo */
> + addr_2 = find_instr(usdt_2, nop1_nop10_combo, 11);
> + if (!ASSERT_OK_PTR(addr_2, "usdt_2_find_nop1_nop10_combo"))
> return;
[ ... ]
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/26475828601
^ permalink raw reply
* Re: [PATCHv4 03/13] uprobes/x86: Allow to copy uprobe trampolines on fork
From: bot+bpf-ci @ 2026-05-26 21:46 UTC (permalink / raw)
To: jolsa, oleg, peterz, mingo, mhiramat, andrii
Cc: bpf, linux-trace-kernel, ast, andrii, daniel, martin.lau, eddyz87,
yonghong.song, clm, ihor.solodrai
In-Reply-To: <20260526205840.173790-4-jolsa@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 1449 bytes --]
> diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
> index 733655bc610e..c8af41ed681a 100644
> --- a/arch/x86/kernel/uprobes.c
> +++ b/arch/x86/kernel/uprobes.c
> @@ -697,7 +697,7 @@ static struct vm_area_struct *get_uprobe_trampoline(struct mm_struct *mm, unsign
> return ERR_PTR(vaddr);
>
> return _install_special_mapping(mm, vaddr, PAGE_SIZE,
> - VM_READ|VM_EXEC|VM_MAYEXEC|VM_MAYREAD|VM_DONTCOPY|VM_IO,
> + VM_READ|VM_EXEC|VM_MAYEXEC|VM_MAYREAD|VM_IO,
> &tramp_mapping);
> }
When a process with optimized uprobes is forked, the child inherits the
optimized code and trampoline. This means sys_uprobe invocations in the
child will go into the uprobe trampoline, and the syscall will keep
returning -EPROTO since no handler is registered.
Is there a way to restore the original memory pages for clones?
This behavior seems suboptimal from a performance perspective. For
standard int3-based uprobes, breakpoints are removed via
UPROBE_HANDLER_REMOVE. Could something similar be implemented for
optimized uprobes, perhaps with proper filtering in uprobe_multi?
Reference: https://lore.kernel.org/bpf/CAEf4BzYo-8PAXFJt9MHoUn9ux1O2YVxJADC0tGSsacVu_R8Stw@mail.gmail.com/
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/26475828601
^ permalink raw reply
* Re: [PATCHv4 12/13] selftests/bpf: Add tests for uprobe nop10 red zone clobbering
From: bot+bpf-ci @ 2026-05-26 21:46 UTC (permalink / raw)
To: jolsa, oleg, peterz, mingo, mhiramat, andrii
Cc: bpf, linux-trace-kernel, ast, andrii, daniel, martin.lau, eddyz87,
yonghong.song, clm, ihor.solodrai
In-Reply-To: <20260526205840.173790-13-jolsa@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 3775 bytes --]
> diff --git a/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c b/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c
> index 969f4deba9fd..efff0c515184 100644
> --- a/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c
> +++ b/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c
[ ... ]
> @@ -855,6 +897,37 @@ static void test_uprobe_race(void)
> #define __NR_uprobe 336
> #endif
>
> +static void test_uprobe_red_zone(void)
> +{
> + struct uprobe_syscall_executed *skel;
> + struct bpf_link *link;
> + void *nop10_addr;
> + size_t offset;
> + int i;
> +
> + nop10_addr = find_nop10(uprobe_red_zone_test);
> + if (!ASSERT_NEQ(nop10_addr, NULL, "find_nop10"))
> + return;
> +
> + skel = uprobe_syscall_executed__open_and_load();
> + if (!ASSERT_OK_PTR(skel, "open_and_load"))
> + return;
> +
> + offset = get_uprobe_offset(nop10_addr);
> + link = bpf_program__attach_uprobe_opts(skel->progs.test_uprobe,
> + 0, "/proc/self/exe", offset, NULL);
> + if (!ASSERT_OK_PTR(link, "attach_uprobe"))
> + goto cleanup;
> +
> + for (i = 0; i < 10; i++)
> + ASSERT_EQ(uprobe_red_zone_test(), 0, "red_zone_intact");
Does this loop execute too quickly to guarantee the uprobe optimization has
completed?
Uprobe optimization is performed asynchronously by a worker thread. Since this
is a tight loop with no delays or blocking, the 10 iterations might finish
before the background worker patches the code.
If all hits execute on the unoptimized INT3 path, the test could falsely pass
on kernels where the CALL-based optimization bug is present.
(This concern was raised by sashiko-bot@kernel.org in v1 and remains
unaddressed:
https://lore.kernel.org/bpf/20260514212219.BF1F3C2BCB3@smtp.kernel.org/)
> +
> + bpf_link__destroy(link);
> +
> +cleanup:
> + uprobe_syscall_executed__destroy(skel);
> +}
[ ... ]
> diff --git a/tools/testing/selftests/bpf/usdt_2.c b/tools/testing/selftests/bpf/usdt_2.c
> index b359b389f6c0..5e38f8605b02 100644
> --- a/tools/testing/selftests/bpf/usdt_2.c
> +++ b/tools/testing/selftests/bpf/usdt_2.c
> @@ -13,4 +13,17 @@ void usdt_2(void)
> USDT(optimized_attach, usdt_2);
> }
>
> +static volatile unsigned long usdt_red_zone_arg1 = 0xDEADBEEF;
> +static volatile unsigned long usdt_red_zone_arg2 = 0xCAFEBABE;
> +static volatile unsigned long usdt_red_zone_arg3 = 0xFEEDFACE;
> +
> +void __attribute__((noinline)) usdt_red_zone_trigger(void)
> +{
> + unsigned long a1 = usdt_red_zone_arg1;
> + unsigned long a2 = usdt_red_zone_arg2;
> + unsigned long a3 = usdt_red_zone_arg3;
> +
> + USDT(optimized_attach, usdt_red_zone, a1, a2, a3);
> +}
Is this test reliable across different compiler versions and optimizations?
The USDT macro uses the "nor" inline assembly constraint, which allows the
compiler to allocate these operands to CPU registers.
Because there is no register pressure in usdt_red_zone_trigger(), modern
compilers might allocate a1, a2, and a3 directly to registers rather than the
stack's red zone.
If the operands are placed in registers, the uprobe CALL optimization
clobbering [rsp-8] will not corrupt them. This could cause the test to pass
even on buggy kernels, creating a false positive.
Would it be safer to explicitly force these operands into the red zone using
inline assembly constraints, rather than depending on the compiler's register
allocator?
(This concern was raised by bot+bpf-ci@kernel.org in v1 and v3 and remains
unaddressed:
https://lore.kernel.org/bpf/e91d31e0c1378fe970db6385c7af419e97af0c2acd37b3b8775a2fac02ea2361@mail.kernel.org/)
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/26475828601
^ permalink raw reply
* Re: [PATCHv4 02/13] uprobes/x86: Remove struct uprobe_trampoline object
From: bot+bpf-ci @ 2026-05-26 21:46 UTC (permalink / raw)
To: jolsa, oleg, peterz, mingo, mhiramat, andrii
Cc: bpf, linux-trace-kernel, ast, andrii, daniel, martin.lau, eddyz87,
yonghong.song, clm, ihor.solodrai
In-Reply-To: <20260526205840.173790-3-jolsa@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 4383 bytes --]
> diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
> index 2be6707e3320..733655bc610e 100644
> --- a/arch/x86/kernel/uprobes.c
> +++ b/arch/x86/kernel/uprobes.c
[ ... ]
> @@ -1111,21 +1051,18 @@ int set_orig_insn(struct arch_uprobe *auprobe, struct vm_area_struct *vma,
> static int __arch_uprobe_optimize(struct arch_uprobe *auprobe, struct mm_struct *mm,
> unsigned long vaddr)
> {
> - struct uprobe_trampoline *tramp;
> - struct vm_area_struct *vma;
> - bool new = false;
> - int err = 0;
> + struct pt_regs *regs = task_pt_regs(current);
> + struct vm_area_struct *vma, *tramp;
>
> + if (!user_64bit_mode(regs))
> + return -EINVAL;
> vma = find_vma(mm, vaddr);
> if (!vma)
> return -EINVAL;
> - tramp = get_uprobe_trampoline(vaddr, &new);
> - if (!tramp)
> - return -EINVAL;
> - err = swbp_optimize(auprobe, vma, vaddr, tramp->vaddr);
> - if (WARN_ON_ONCE(err) && new)
> - destroy_uprobe_trampoline(tramp);
> - return err;
> + tramp = get_uprobe_trampoline(mm, vaddr);
> + if (IS_ERR(tramp))
> + return PTR_ERR(tramp);
> + return WARN_ON_ONCE(swbp_optimize(auprobe, vma, vaddr, tramp->vm_start));
> }
When swbp_optimize() fails in __arch_uprobe_optimize() and the preceding
get_uprobe_trampoline() call created a new trampoline VMA via
_install_special_mapping(), does the new VMA leak in the process address
space?
The pre-patch code tracked whether the trampoline was newly created and
called destroy_uprobe_trampoline() on the failure path:
err = swbp_optimize(auprobe, vma, vaddr, tramp->vaddr);
if (WARN_ON_ONCE(err) && new)
destroy_uprobe_trampoline(tramp);
return err;
The new code drops that cleanup entirely:
return WARN_ON_ONCE(swbp_optimize(auprobe, vma, vaddr, tramp->vm_start));
Although the old destroy_uprobe_trampoline only freed the struct (not the
underlying VMA), the new code appears to introduce a VMA leak: the freshly
mapped PAGE_SIZE special mapping in the user's address space stays mapped
even though optimization failed. arch_uprobe_optimize() then sets
ARCH_UPROBE_FLAG_OPTIMIZE_FAIL so subsequent calls won't retry, leaving the
orphan trampoline mapping in the address space until exit_mmap() reaps it at
process teardown.
The commit message mentions: "Note the original code called
destroy_uprobe_trampoline if the optimiation failed, but it only freed the
struct uprobe_trampoline object, not the vma. The new vma leak is fixed in
following change."
Is the VMA leak addressed in the subsequent commit in this series?
A secondary behaviour change is that 'return WARN_ON_ONCE(swbp_optimize(...))'
now returns the boolean truth value of the error (0 or 1) instead of the
original errno. While the current caller (arch_uprobe_optimize) only treats
the value as boolean, could this surprise a future caller that propagates the
return code?
Commit message:
> uprobes/x86: Remove struct uprobe_trampoline object
>
> Removing struct uprobe_trampoline object and it's tracking code,
> because it's not needed. We can do same thing directly on top of
> struct vm_area_struct objects.
>
> This makes the code simpler and allows easy propagation of the
> trampoline vma object into child process in following change.
>
> Note the original code called destroy_uprobe_trampoline if the
> optimiation failed, but it only freed the struct uprobe_trampoline
> object, not the vma. The new vma leak is fixed in following change.
>
> Acked-by: Andrii Nakryiko <andrii@kernel.org>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
CI bot suggested adding a Fixes tag in v3: 'Fixes: ba2bfc97b462
("uprobes/x86: Add support to optimize uprobes")' because the commit message
notes a VMA resource leak in the original code.
Reference: https://lore.kernel.org/bpf/8861cc7af8e0dfff2674ca4ae6381ea2d82c242dec115774e8e11048bde358c4@mail.kernel.org/
The author responded that 'the logic stays' and a separate fix is needed, but
did not explain why the Fixes tag should not be included. If this patch is
documenting a pre-existing bug (even if the full fix comes later), should it
include a Fixes tag for backporting purposes?
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/26475828601
^ permalink raw reply
* Re: [PATCHv4 07/13] libbpf: Detect uprobe syscall with new error
From: bot+bpf-ci @ 2026-05-26 21:46 UTC (permalink / raw)
To: jolsa, oleg, peterz, mingo, mhiramat, andrii
Cc: bpf, linux-trace-kernel, ast, andrii, daniel, martin.lau, eddyz87,
yonghong.song, clm, ihor.solodrai
In-Reply-To: <20260526205840.173790-8-jolsa@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 1261 bytes --]
> libbpf: Detect uprobe syscall with new error
>
> In the previous optimized uprobe fix we changed the syscall
> error used for its detection from ENXIO to EPROTO.
>
> Changing related probe_uprobe_syscall detection check.
>
> Acked-by: Andrii Nakryiko <andrii@kernel.org>
> Fixes: 05738da0efa1 ("libbpf: Add uprobe syscall feature detection")
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
The commit message states "In the previous optimized uprobe fix we
changed the syscall error used for its detection from ENXIO to EPROTO."
The Fixes tag points to commit 05738da0efa1 ("libbpf: Add uprobe syscall
feature detection"), but that commit originally added the ENXIO check
correctly. The bug was actually introduced by commit af734a7ddb4e
("uprobes/x86: Move optimized uprobe from nop5 to nop10"), which changed
the kernel to return EPROTO instead of ENXIO but did not update the
libbpf detection code to match.
Should the Fixes tag be:
Fixes: af734a7ddb4e ("uprobes/x86: Move optimized uprobe from nop5 to nop10")
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/26475828601
^ permalink raw reply
* Re: [PATCHv4 08/13] selftests/bpf: Emit nop,nop10 instructions combo for x86_64 arch
From: bot+bpf-ci @ 2026-05-26 21:46 UTC (permalink / raw)
To: jolsa, oleg, peterz, mingo, mhiramat, andrii
Cc: jakub, bpf, linux-trace-kernel, ast, andrii, daniel, martin.lau,
eddyz87, yonghong.song, clm, ihor.solodrai
In-Reply-To: <20260526205840.173790-9-jolsa@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 1909 bytes --]
> diff --git a/tools/testing/selftests/bpf/usdt.h b/tools/testing/selftests/bpf/usdt.h
> index c71e21df38b3..75687f50f4e2 100644
> --- a/tools/testing/selftests/bpf/usdt.h
> +++ b/tools/testing/selftests/bpf/usdt.h
> @@ -313,7 +313,7 @@ struct usdt_sema { volatile unsigned short active; };
> #if defined(__ia64__) || defined(__s390__) || defined(__s390x__)
> #define USDT_NOP nop 0
> #elif defined(__x86_64__)
> -#define USDT_NOP .byte 0x90, 0x0f, 0x1f, 0x44, 0x00, 0x0 /* nop, nop5 */
> +#define USDT_NOP .byte 0x90, 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 /* nop, nop10 */
> #else
> #define USDT_NOP nop
> #endif
Does this change break the USDT selftest? Multiple reviewers raised
concerns across v1 through v4 that subtest_optimized_attach() in
prog_tests/usdt.c searches for the old 6-byte nop1_nop5_combo sequence.
When usdt_2.c emits the new 11-byte nop,nop10 instead, find_instr() will
return NULL and fail the ASSERT_OK_PTR check.
You mentioned in v1/v2 that the test would be updated in a following commit,
preferring to keep changes separated for easier review. However, this creates
a git bisect regression where the test breaks at this commit. Should the test
update be squashed in to avoid breaking bisectability?
The commit message contains a placeholder reference:
> Syncing latest usdt.h change [1].
>
> Now that we have nop10 optimization support in kernel, let's emit
> nop,nop10 for usdt probe. We leave it up to the library to use
> desirable nop instruction.
>
> [1] TBD
This isn't a bug, but the "[1] TBD" should either be filled in or removed.
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/26475828601
^ permalink raw reply
* Re: [PATCHv4 04/13] uprobes/x86: Unmap trampoline vma object in case it's unused
From: bot+bpf-ci @ 2026-05-26 21:46 UTC (permalink / raw)
To: jolsa, oleg, peterz, mingo, mhiramat, andrii
Cc: bpf, linux-trace-kernel, ast, andrii, daniel, martin.lau, eddyz87,
yonghong.song, clm, ihor.solodrai
In-Reply-To: <20260526205840.173790-5-jolsa@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 3456 bytes --]
> commit 68883203f0583fb1a8d79536f5c8945542974abd
> Author: Jiri Olsa <jolsa@kernel.org>
> Date: Tue May 26 22:58:31 2026 +0200
>
> uprobes/x86: Unmap trampoline vma object in case it's unused
>
> In case the optimization fails, we leak new-ly created trampoline
> vma mapping (in case we just created it), let's unmap it.
>
> Fixes: ba2bfc97b462 ("uprobes/x86: Add support to optimize uprobes")
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Should this Fixes: tag point to a9fe6f54968c instead? The vma leak bug
was actually introduced by commit a9fe6f54968c ("uprobes/x86: Remove
struct uprobe_trampoline object"), not ba2bfc97b462. Commit a9fe6f54968c
removed the destroy_uprobe_trampoline() cleanup call, and its commit
message explicitly states: "The new vma leak is fixed in following
change."
Suggested: Fixes: a9fe6f54968c ("uprobes/x86: Remove struct
uprobe_trampoline object")
> diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
> index c8af41ed681a..af5af7d67999 100644
> --- a/arch/x86/kernel/uprobes.c
> +++ b/arch/x86/kernel/uprobes.c
> @@ -677,11 +677,14 @@ static unsigned long find_nearest_trampoline(unsigned long vaddr)
> return high_tramp;
> }
>
> -static struct vm_area_struct *get_uprobe_trampoline(struct mm_struct *mm, unsigned long vaddr)
> +static struct vm_area_struct *get_uprobe_trampoline(struct mm_struct *mm, unsigned long vaddr,
> + bool *new_mapping)
> {
> VMA_ITERATOR(vmi, mm, 0);
> struct vm_area_struct *vma;
>
> + *new_mapping = false;
> +
> if (vaddr > TASK_SIZE || vaddr < PAGE_SIZE)
> return ERR_PTR(-EINVAL);
>
Does this fix address the VMA leak scenario across fork chains? In v2,
sashiko-bot raised a concern about inherited-but-not-tracked VMAs:
https://lore.kernel.org/bpf/20260518114208.CE128C2BCF6@smtp.kernel.org/
When VM_DONTCOPY is removed, child processes inherit trampoline VMAs
but their tracking list (mm->uprobes_state.head_tramps) is empty. When
the child executes a uprobe, get_uprobe_trampoline() fails to find the
inherited VMA and creates a duplicate trampoline.
Child fork:
dup_mmap()
copies trampoline VMA to child
mm_init_uprobes_state()
initializes head_tramps as empty (parent's state not copied)
Child executes uprobe:
arch_uprobe_optimize()
get_uprobe_trampoline()
head_tramps is empty, fails to find inherited VMA
create_uprobe_trampoline()
find_nearest_trampoline() finds new unmapped area
installs second duplicate trampoline VMA
In a deep fork chain, each generation inherits all previous VMAs, has an
empty head_tramps list, and creates a new VMA. Can this cause linear
accumulation of redundant VMAs, eventually exhausting vm.max_map_count?
While this patch addresses unmapping failed optimization attempts, it
does not prevent the inherited-but-not-tracked VMA leak scenario in fork
chains.
> @@ -696,6 +699,7 @@ static struct vm_area_struct *get_uprobe_trampoline(struct mm_struct *mm, unsign
> if (IS_ERR_VALUE(vaddr))
> return ERR_PTR(vaddr);
>
> + *new_mapping = true;
> return _install_special_mapping(mm, vaddr, PAGE_SIZE,
> VM_READ|VM_EXEC|VM_MAYEXEC|VM_MAYREAD|VM_IO,
> &tramp_mapping);
[ ... ]
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/26475828601
^ permalink raw reply
* Re: [PATCH] tracing: Fix field_var_str allocation errno
From: Masami Hiramatsu @ 2026-05-27 1:04 UTC (permalink / raw)
To: Yu Peng
Cc: Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers, Tom Zanussi,
linux-trace-kernel, linux-kernel
In-Reply-To: <20260526095022.1330107-1-pengyu@kylinos.cn>
On Tue, 26 May 2026 17:50:22 +0800
Yu Peng <pengyu@kylinos.cn> wrote:
> hist_trigger_elt_data_alloc() returns -EINVAL when the field_var_str
> kcalloc() fails. Return -ENOMEM instead, matching the other allocation
> failures in the function.
>
Looks good to me.
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Thanks,
> Fixes: c910db943d35 ("tracing: Dynamically allocate the per-elt hist_elt_data array")
> Signed-off-by: Yu Peng <pengyu@kylinos.cn>
> ---
> kernel/trace/trace_events_hist.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
> index eb2c2bc8bc3d..17fe13e12a4f 100644
> --- a/kernel/trace/trace_events_hist.c
> +++ b/kernel/trace/trace_events_hist.c
> @@ -1680,7 +1680,7 @@ static int hist_trigger_elt_data_alloc(struct tracing_map_elt *elt)
> elt_data->field_var_str = kcalloc(n_str, sizeof(char *), GFP_KERNEL);
> if (!elt_data->field_var_str) {
> hist_elt_data_free(elt_data);
> - return -EINVAL;
> + return -ENOMEM;
> }
> elt_data->n_field_var_str = n_str;
>
> --
> 2.43.0
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply
* Re: [PATCH] tracing: Use kstrdup_const() for constant hist field type
From: Masami Hiramatsu @ 2026-05-27 1:10 UTC (permalink / raw)
To: Yu Peng
Cc: Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
linux-trace-kernel, linux-kernel
In-Reply-To: <20260526095105.1330810-1-pengyu@kylinos.cn>
On Tue, 26 May 2026 17:51:05 +0800
Yu Peng <pengyu@kylinos.cn> wrote:
> The HIST_FIELD_FL_CONST path duplicates the literal "u64" type with
> kstrdup(), then releases it through kfree_const().
>
> Use kstrdup_const() instead, avoiding the allocation for a .rodata string
> while keeping the matching free helper.
>
Since we are using kfree_const() to free hist_field->type,
we can just point it as same as HIST_FIELD_FL_HITCOUNT case.
Thanks,
> Signed-off-by: Yu Peng <pengyu@kylinos.cn>
> ---
> kernel/trace/trace_events_hist.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
> index eb2c2bc8bc3d..6ffe9f4720a0 100644
> --- a/kernel/trace/trace_events_hist.c
> +++ b/kernel/trace/trace_events_hist.c
> @@ -1992,7 +1992,7 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data,
> if (flags & HIST_FIELD_FL_CONST) {
> hist_field->fn_num = HIST_FIELD_FN_CONST;
> hist_field->size = sizeof(u64);
> - hist_field->type = kstrdup("u64", GFP_KERNEL);
> + hist_field->type = kstrdup_const("u64", GFP_KERNEL);
> if (!hist_field->type)
> goto free;
> goto out;
> --
> 2.43.0
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply
* Re: [PATCH] tracing: Use kstrdup_const() for constant hist field type
From: Steven Rostedt @ 2026-05-27 1:50 UTC (permalink / raw)
To: Masami Hiramatsu (Google)
Cc: Yu Peng, Mathieu Desnoyers, linux-trace-kernel, linux-kernel
In-Reply-To: <20260527101015.74fc2d54860f16e4aba83cd7@kernel.org>
On Wed, 27 May 2026 10:10:15 +0900
Masami Hiramatsu (Google) <mhiramat@kernel.org> wrote:
> On Tue, 26 May 2026 17:51:05 +0800
> Yu Peng <pengyu@kylinos.cn> wrote:
>
> > The HIST_FIELD_FL_CONST path duplicates the literal "u64" type with
> > kstrdup(), then releases it through kfree_const().
> >
> > Use kstrdup_const() instead, avoiding the allocation for a .rodata string
> > while keeping the matching free helper.
> >
>
> Since we are using kfree_const() to free hist_field->type,
> we can just point it as same as HIST_FIELD_FL_HITCOUNT case.
>
Agreed.
> Thanks,
>
> > Signed-off-by: Yu Peng <pengyu@kylinos.cn>
> > ---
> > kernel/trace/trace_events_hist.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
> > index eb2c2bc8bc3d..6ffe9f4720a0 100644
> > --- a/kernel/trace/trace_events_hist.c
> > +++ b/kernel/trace/trace_events_hist.c
> > @@ -1992,7 +1992,7 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data,
> > if (flags & HIST_FIELD_FL_CONST) {
> > hist_field->fn_num = HIST_FIELD_FN_CONST;
> > hist_field->size = sizeof(u64);
> > - hist_field->type = kstrdup("u64", GFP_KERNEL);
> > + hist_field->type = kstrdup_const("u64", GFP_KERNEL);
This can simply be made to point to "u64".
Thanks,
-- Steve
> > if (!hist_field->type)
> > goto free;
> > goto out;
> > --
> > 2.43.0
>
>
^ permalink raw reply
* Re: [PATCH bpf-next v2 2/3] tracing: Expose tracepoint BTF ids via tracefs
From: Steven Rostedt @ 2026-05-27 1:57 UTC (permalink / raw)
To: Mykyta Yatsenko
Cc: bpf, Mykyta Yatsenko, linux-trace-kernel, Andrii Nakryiko,
Alexei Starovoitov
In-Reply-To: <eed59d12-969f-4135-a84b-4965743692cd@gmail.com>
On Tue, 26 May 2026 11:07:56 +0100
Mykyta Yatsenko <mykyta.yatsenko5@gmail.com> wrote:
> Hi Steven,
>
> Gentle ping on this patch from the series.
>
> Since this part touches tracing, I’d appreciate your thoughts on the
> tracing changes whenever you have a chance.
>
Hi,
I've been looking at this and was wondering if there are ways to not
extend the trace_event_class structure. It's added for most trace
events (actually each DECLARE_EVENT_CLASS). Although when things like
BTF is enabled, this is a very small amount of extra memory.
I haven't been ignoring this. I've just been thinking about other
approaches, but haven't come up with anything. Of course, I haven't
been spending that much time on it, as I've been focused on other
things.
-- Steve
^ permalink raw reply
* [PATCH v2] tracing: Point constant hist field type to string literal
From: Yu Peng @ 2026-05-27 2:18 UTC (permalink / raw)
To: rostedt
Cc: linux-kernel, linux-trace-kernel, mathieu.desnoyers, mhiramat,
pengyu
In-Reply-To: <20260526215033.78fdac7f@fedora>
The HIST_FIELD_FL_CONST path uses the fixed "u64" type string.
Point hist_field->type directly to the string literal, matching the
HIST_FIELD_FL_HITCOUNT path. The release path already uses kfree_const(),
so no duplication is needed.
Signed-off-by: Yu Peng <pengyu@kylinos.cn>
---
Changes in v2:
- Point hist_field->type directly to "u64" as suggested.
kernel/trace/trace_events_hist.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index eb2c2bc8bc3d5..b50f2bd5ff771 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -1992,9 +1992,7 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data,
if (flags & HIST_FIELD_FL_CONST) {
hist_field->fn_num = HIST_FIELD_FN_CONST;
hist_field->size = sizeof(u64);
- hist_field->type = kstrdup("u64", GFP_KERNEL);
- if (!hist_field->type)
- goto free;
+ hist_field->type = "u64";
goto out;
}
--
2.43.0
^ permalink raw reply related
* Re: [RFC PATCH v3 0/3] trace: stack trace deduplication for ftrace ring buffer
From: Li Pengfei @ 2026-05-27 2:23 UTC (permalink / raw)
To: rostedt
Cc: mhiramat, linux-trace-kernel, linux-kernel, cmllamas, zhangbo56,
Pengfei Li
In-Reply-To: <20260526153905.093aff7c@gandalf.local.home>
From: Pengfei Li <lipengfei28@xiaomi.com>
On Mon, 26 May 2026 15:39:05 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:
> Please DO NOT SEND new versions of a patch or patch series as a reply to
> the old one. It makes it extremely difficult for maintainers to manage the
> replies and patches.
>
> A new version should ALWAYS start a new email thread!
Understood. Will start a fresh thread from v4 onwards and use a
lore link to reference the previous version in the cover letter.
Sorry for the noise.
Pengfei
^ permalink raw reply
* Re: [PATCH v2] tracing: Point constant hist field type to string literal
From: Steven Rostedt @ 2026-05-27 2:26 UTC (permalink / raw)
To: Yu Peng; +Cc: linux-kernel, linux-trace-kernel, mathieu.desnoyers, mhiramat
In-Reply-To: <20260527021827.2123529-1-pengyu@kylinos.cn>
On Wed, 27 May 2026 10:18:27 +0800
Yu Peng <pengyu@kylinos.cn> wrote:
> The HIST_FIELD_FL_CONST path uses the fixed "u64" type string.
>
> Point hist_field->type directly to the string literal, matching the
> HIST_FIELD_FL_HITCOUNT path. The release path already uses kfree_const(),
> so no duplication is needed.
>
> Signed-off-by: Yu Peng <pengyu@kylinos.cn>
> ---
> Changes in v2:
> - Point hist_field->type directly to "u64" as suggested
All new versions of a patch need to start a new thread. Please resend
this as a new thread and not a reply.
-- Steve
>
> kernel/trace/trace_events_hist.c | 4 +---
> 1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
> index eb2c2bc8bc3d5..b50f2bd5ff771 100644
> --- a/kernel/trace/trace_events_hist.c
> +++ b/kernel/trace/trace_events_hist.c
> @@ -1992,9 +1992,7 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data,
> if (flags & HIST_FIELD_FL_CONST) {
> hist_field->fn_num = HIST_FIELD_FN_CONST;
> hist_field->size = sizeof(u64);
> - hist_field->type = kstrdup("u64", GFP_KERNEL);
> - if (!hist_field->type)
> - goto free;
> + hist_field->type = "u64";
> goto out;
> }
>
^ permalink raw reply
* [PATCH v2] tracing: Point constant hist field type to string literal
From: Yu Peng @ 2026-05-27 2:34 UTC (permalink / raw)
To: rostedt
Cc: linux-kernel, linux-trace-kernel, mathieu.desnoyers, mhiramat,
pengyu
The HIST_FIELD_FL_CONST path uses the fixed "u64" type string.
Point hist_field->type directly to the string literal, matching the
HIST_FIELD_FL_HITCOUNT path. The release path already uses kfree_const(),
so no duplication is needed.
Signed-off-by: Yu Peng <pengyu@kylinos.cn>
---
Changes in v2:
- Point hist_field->type directly to "u64" as suggested.
kernel/trace/trace_events_hist.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index eb2c2bc8bc3d5..b50f2bd5ff771 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -1992,9 +1992,7 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data,
if (flags & HIST_FIELD_FL_CONST) {
hist_field->fn_num = HIST_FIELD_FN_CONST;
hist_field->size = sizeof(u64);
- hist_field->type = kstrdup("u64", GFP_KERNEL);
- if (!hist_field->type)
- goto free;
+ hist_field->type = "u64";
goto out;
}
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v2] tracing: Point constant hist field type to string literal
From: Masami Hiramatsu @ 2026-05-27 2:41 UTC (permalink / raw)
To: Yu Peng
Cc: rostedt, linux-kernel, linux-trace-kernel, mathieu.desnoyers,
mhiramat
In-Reply-To: <20260527023450.2137639-1-pengyu@kylinos.cn>
On Wed, 27 May 2026 10:34:50 +0800
Yu Peng <pengyu@kylinos.cn> wrote:
> The HIST_FIELD_FL_CONST path uses the fixed "u64" type string.
>
> Point hist_field->type directly to the string literal, matching the
> HIST_FIELD_FL_HITCOUNT path. The release path already uses kfree_const(),
> so no duplication is needed.
>
> Signed-off-by: Yu Peng <pengyu@kylinos.cn>
This looks good to me.
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Thanks,
> ---
> Changes in v2:
> - Point hist_field->type directly to "u64" as suggested.
>
> kernel/trace/trace_events_hist.c | 4 +---
> 1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
> index eb2c2bc8bc3d5..b50f2bd5ff771 100644
> --- a/kernel/trace/trace_events_hist.c
> +++ b/kernel/trace/trace_events_hist.c
> @@ -1992,9 +1992,7 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data,
> if (flags & HIST_FIELD_FL_CONST) {
> hist_field->fn_num = HIST_FIELD_FN_CONST;
> hist_field->size = sizeof(u64);
> - hist_field->type = kstrdup("u64", GFP_KERNEL);
> - if (!hist_field->type)
> - goto free;
> + hist_field->type = "u64";
> goto out;
> }
>
> --
> 2.43.0
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply
* Re: [PATCH v21 8/9] ring-buffer: Show persistent buffer dropped events in trace file
From: Masami Hiramatsu @ 2026-05-27 3:47 UTC (permalink / raw)
To: Steven Rostedt
Cc: linux-kernel, linux-trace-kernel, Mark Rutland, Mathieu Desnoyers,
Andrew Morton, Ian Rogers
In-Reply-To: <20260526134116.11e1db99@gandalf.local.home>
On Tue, 26 May 2026 13:41:16 -0400
Steven Rostedt <rostedt@kernel.org> wrote:
> On Tue, 26 May 2026 14:06:09 +0900
> Masami Hiramatsu (Google) <mhiramat@kernel.org> wrote:
>
> > > @@ -7204,10 +7209,12 @@ int ring_buffer_read_page(struct trace_buffer *buffer,
> > > * Set a flag in the commit field if we lost events
> > > */
> > > if (missed_events) {
> > > - /* If there is room at the end of the page to save the
> > > + /*
> > > + * If there is room at the end of the page to save the
> > > * missed events, then record it there.
> > > */
> > > - if (buffer->subbuf_size - commit >= sizeof(missed_events)) {
> > > + if (missed_events > 0 &&
> > > + buffer->subbuf_size - commit >= sizeof(missed_events)) {
> > > memcpy(&dpage->data[commit], &missed_events,
> > > sizeof(missed_events));
> > > local_add(RB_MISSED_STORED, &dpage->commit);
> >
> > After this line, we "add" RB_MISSED_EVENTS instead of set.
> > In this case, does it clear the RB_MISSED_EVENTS bit because
> > it already sets RB_MISSED_EVENTS.
> >
> > commit += sizeof(missed_events);
> > }
> > local_add(RB_MISSED_EVENTS, &bpage->commit);
> > ^^^ here.
>
> Perhaps this needs to be commented better.
>
> The answer to your question is "No". The reason is that this is a *copy* of
> the page we are reading. As persistent pages are always assigned to
> specific memory, it can never leave the buffer even for the splice system
> call. It is always copied to a new page.
>
> The new page doesn't have these bits set and needs to set them depending on
> what was found when reading the page from the buffer.
>
> Now if this was a normal ring buffer where it did a zero copy from the
> buffer itself by swapping pages with the passed in page, if the bit was set
> before, then adding would cause a problem. But normal ring buffer pages
> never set these bits while in the buffer. They are only set by this function.
Yeah, for the persistent ring buffer, it does not happen.
But there seems RB_MISSED_EVENTS bit can be cleared in
"else" path (after applying 1-8 patches)?
----------
if (read || (len < (commit - read)) ||
cpu_buffer->reader_page == cpu_buffer->commit_page ||
force_memcpy) { // <-- persistent ring buffer sets force_memcpy = true.
[...]
} else {
/* update the entry counter */
[...]
if (!missed_events && rb_data_page_commit(dpage) & RB_MISSED_EVENTS)
missed_events = -1;
//^-- we check RB_MISSED_EVENTS bit on @dpage->commit and set missed_events = -1.
/*
* Use the real_end for the data size,
* This gives us a chance to store the lost events
* on the page.
*/
if (reader->real_end)
local_set(&dpage->commit, reader->real_end);
// ^- only if @reader->real_end, RB_MISSED_EVENTS bit is dropped.
}
cpu_buffer->lost_events = 0;
commit = rb_data_page_commit(dpage);
/*
* Set a flag in the commit field if we lost events
*/
if (missed_events) {
/*
* If there is room at the end of the page to save the
* missed events, then record it there.
*/
if (missed_events > 0 &&
buffer->subbuf_size - commit >= sizeof(missed_events)) {
memcpy(&dpage->data[commit], &missed_events,
sizeof(missed_events));
local_add(RB_MISSED_STORED, &dpage->commit);
commit += sizeof(missed_events);
}
local_add(RB_MISSED_EVENTS, &dpage->commit); // <-- @dpage->commit is updated.
}
----------
Thanks,
>
> -- Steve
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply
* Re: [PATCH v21 0/9] ring-buffer: Making persistent ring buffers robust
From: Masami Hiramatsu @ 2026-05-27 3:57 UTC (permalink / raw)
To: Steven Rostedt
Cc: linux-kernel, linux-trace-kernel, Mark Rutland, Mathieu Desnoyers,
Andrew Morton, Ian Rogers
In-Reply-To: <20260526134231.1a65aef5@gandalf.local.home>
On Tue, 26 May 2026 13:42:31 -0400
Steven Rostedt <rostedt@kernel.org> wrote:
> On Tue, 26 May 2026 14:17:46 +0900
> Masami Hiramatsu (Google) <mhiramat@kernel.org> wrote:
>
> > On Fri, 22 May 2026 13:08:57 -0400
> > Steven Rostedt <rostedt@kernel.org> wrote:
> >
> > > This is to make the persistent ring buffer more robust when sub-buffers
> > > are detected to be corrupted. Instead of invalidating the entire buffer,
> > > just invalidate the individual sub-buffers.
> > >
> > > I started with Masami's patches and modified some from Sashiko reviews.
> > > I added a few patches to display the dropped events when the persistent
> > > ring buffers validation checks found sub-buffers were dropped due to being
> > > corrupted data.
> >
> > It seems that Sashiko still marks it "Incompleted".
> > Maybe we need base-commit: tag in this cover mail?
> > I also guess that this series does not use "In-Reply-To:" but
> > only uses "References:" tag in the mail header. I guess
> > Sashiko's mail header parser missed it.
>
> But this applies to mainline. I'm not sure why it's having problems.
Yeah, I confirmed this series can be applied to linus mainline tree.
I meant that the Sashiko's email header parser may failed to parse the
thread correctly.
- The patches in this series are listed separately.
https://sashiko.dev/#/?list=org.kernel.vger.linux-trace-kernel
- The cover mail also listed and the page has "Thread" list
but it only has replies to the cover mail. No other patches.
https://sashiko.dev/#/patchset/20260522170857.263969486%40kernel.org
- v18 seems correctly parsed, which has "In-Reply-To:" tag in the mail header.
https://sashiko.dev/#/patchset/177701351903.2223789.17087009302463188638.stgit%40mhiramat.tok.corp.google.com
So I guess Sashiko's email header parser does not correctly handle
the "References:" tag for recognizing thread.
Thank you,
>
> -- Steve
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply
* [PATCH v2 00/12] rv: Fixes on Deterministic and Hybrid Automata
From: Gabriele Monaco @ 2026-05-27 6:23 UTC (permalink / raw)
To: linux-kernel
Cc: Steven Rostedt, Gabriele Monaco, Nam Cao, Wen Yang,
linux-trace-kernel
Fix issues that were reported by bots or visible only after integration:
* Make sure timers are always terminated and waited for when disabling
the monitor or when the target terminates
* Run per-cpu monitors with migration disabled since preemption is now
enabled from tracepoints
* Fix a wrong __user specifier in a helper function
* Other cleanup and concurrency issues
Differences since V1 [1]:
* Fix memory consistency with timer callbacks racing with resets
* Add per-obj deallocation hook in rvgen generated code
* Do not rely on clean monitor when initialising HA
* Add tracepoint synchronisation before returning per-task slots
* Fix suffix strip in dot2k
* Generate stub deallocation hooks instead of failing build when per-obj
miss those
[1] - https://lore.kernel.org/lkml/20260512140250.262190-1-gmonaco@redhat.com
Cc: Nam Cao <namcao@linutronix.de>
Cc: Wen Yang <wen.yang@linux.dev>
Cc: linux-trace-kernel@vger.kernel.org
Gabriele Monaco (11):
rv: Fix __user specifier usage in extract_params()
rv: Fix read_lock scope in per-task DA cleanup
rv: Reset per-task DA monitors before releasing the slot
rv: Prevent task migration while handling per-CPU events
rv: Prevent in-flight per-task handlers from using invalid slots
rv: Ensure all pending probes terminate on per-obj monitor destroy
rv: Ensure synchronous cleanup for HA monitors
rv: Do not rely on clean monitor when initialising HA
rv: Add automatic cleanup handlers for per-task HA monitors
verification/rvgen: Generate cleanup hook for per-obj monitor
verification/rvgen: Fix suffix strip in dot2k
Wen Yang (1):
rv: Fix monitor start ordering and memory ordering for monitoring flag
include/rv/da_monitor.h | 67 +++++++++----
include/rv/ha_monitor.h | 95 ++++++++++++++++++-
include/rv/ltl_monitor.h | 1 +
kernel/trace/rv/monitors/deadline/deadline.h | 3 +-
kernel/trace/rv/monitors/nomiss/nomiss.c | 4 +-
kernel/trace/rv/monitors/opid/opid.c | 4 +-
kernel/trace/rv/monitors/stall/stall.c | 4 +-
tools/verification/rvgen/rvgen/dot2k.py | 19 +++-
.../rvgen/rvgen/templates/dot2k/main.c | 4 +-
9 files changed, 171 insertions(+), 30 deletions(-)
base-commit: 8bc67e4db64aa72732c474b44ea8622062c903f0
--
2.54.0
^ permalink raw reply
* [PATCH v2 01/12] rv: Fix __user specifier usage in extract_params()
From: Gabriele Monaco @ 2026-05-27 6:23 UTC (permalink / raw)
To: linux-kernel, Steven Rostedt, Gabriele Monaco, Masami Hiramatsu,
Nam Cao, linux-trace-kernel
Cc: kernel test robot, Wen Yang
In-Reply-To: <20260527062313.39908-1-gmonaco@redhat.com>
The attributes variables extracted from syscalls in the helper are both
defined with the __user specifier although only the actual pointer to
user data should be marked.
Remove the __user specifier from attr.
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202604150820.Ny143u6X-lkp@intel.com
Fixes: b133207deb72 ("rv: Add nomiss deadline monitor")
Reviewed-by: Wen Yang <wen.yang@linux.dev>
Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
---
kernel/trace/rv/monitors/deadline/deadline.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/trace/rv/monitors/deadline/deadline.h b/kernel/trace/rv/monitors/deadline/deadline.h
index 0bbfd2543329..78fca873d61e 100644
--- a/kernel/trace/rv/monitors/deadline/deadline.h
+++ b/kernel/trace/rv/monitors/deadline/deadline.h
@@ -95,7 +95,8 @@ static inline u8 get_server_type(struct task_struct *tsk)
static inline int extract_params(struct pt_regs *regs, long id, pid_t *pid_out)
{
size_t size = offsetofend(struct sched_attr, sched_flags);
- struct sched_attr __user *uattr, attr;
+ struct sched_attr __user *uattr;
+ struct sched_attr attr;
int new_policy = -1, ret;
unsigned long args[6];
--
2.54.0
^ permalink raw reply related
* [PATCH v2 02/12] rv: Fix read_lock scope in per-task DA cleanup
From: Gabriele Monaco @ 2026-05-27 6:23 UTC (permalink / raw)
To: linux-kernel, Steven Rostedt, Gabriele Monaco, Nam Cao,
linux-trace-kernel
Cc: Wen Yang
In-Reply-To: <20260527062313.39908-1-gmonaco@redhat.com>
The da_monitor_reset_all() function for per-task monitors takes
tasklist_lock while iterating over tasks, then keeps it also while
iterating over idle tasks (one per CPU). The latter is not necessary
since the lock needs to guard only for_each_process_thread().
Use a scoped_guard for more compact syntax and adjust the scope only
where the lock is necessary.
Fixes: 30984ccf31b7f ("rv: Refactor da_monitor to minimise macros")
Fixes: 8259cb14a7068 ("rv: Reset per-task monitors also for idle tasks")
Reviewed-by: Wen Yang <wen.yang@linux.dev>
Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
---
include/rv/da_monitor.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/include/rv/da_monitor.h b/include/rv/da_monitor.h
index 39765ff6f098..250888812125 100644
--- a/include/rv/da_monitor.h
+++ b/include/rv/da_monitor.h
@@ -272,12 +272,12 @@ static void da_monitor_reset_all(void)
struct task_struct *g, *p;
int cpu;
- read_lock(&tasklist_lock);
- for_each_process_thread(g, p)
- da_monitor_reset(da_get_monitor(p));
+ scoped_guard(read_lock, &tasklist_lock) {
+ for_each_process_thread(g, p)
+ da_monitor_reset(da_get_monitor(p));
+ }
for_each_present_cpu(cpu)
da_monitor_reset(da_get_monitor(idle_task(cpu)));
- read_unlock(&tasklist_lock);
}
/*
--
2.54.0
^ permalink raw reply related
* [PATCH v2 03/12] rv: Reset per-task DA monitors before releasing the slot
From: Gabriele Monaco @ 2026-05-27 6:23 UTC (permalink / raw)
To: linux-kernel, Steven Rostedt, Gabriele Monaco, Nam Cao,
linux-trace-kernel
Cc: Wen Yang
In-Reply-To: <20260527062313.39908-1-gmonaco@redhat.com>
Per-task monitors use task_mon_slot to determine which slot in the array
to use for the monitor. During destruction, this slot is returned but
this is done before resetting the monitor. As a result, the monitor's
reset is in fact resetting a slot that is outside of the array
(RV_PER_TASK_MONITOR_INIT).
Release the slot only after the reset to avoid out-of-bound memory
access.
Fixes: f5587d1b6ec93 ("rv: Add Hybrid Automata monitor type")
Suggested-by: Wen Yang <wen.yang@linux.dev>
Reviewed-by: Wen Yang <wen.yang@linux.dev>
Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
---
include/rv/da_monitor.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/include/rv/da_monitor.h b/include/rv/da_monitor.h
index 250888812125..0b7028df08fb 100644
--- a/include/rv/da_monitor.h
+++ b/include/rv/da_monitor.h
@@ -309,10 +309,11 @@ static inline void da_monitor_destroy(void)
WARN_ONCE(1, "Disabling a disabled monitor: " __stringify(MONITOR_NAME));
return;
}
- rv_put_task_monitor_slot(task_mon_slot);
- task_mon_slot = RV_PER_TASK_MONITOR_INIT;
da_monitor_reset_all();
+
+ rv_put_task_monitor_slot(task_mon_slot);
+ task_mon_slot = RV_PER_TASK_MONITOR_INIT;
}
#elif RV_MON_TYPE == RV_MON_PER_OBJ
--
2.54.0
^ permalink raw reply related
* [PATCH v2 04/12] rv: Prevent task migration while handling per-CPU events
From: Gabriele Monaco @ 2026-05-27 6:23 UTC (permalink / raw)
To: linux-kernel, Steven Rostedt, Gabriele Monaco, linux-trace-kernel
Cc: Wen Yang, Nam Cao
In-Reply-To: <20260527062313.39908-1-gmonaco@redhat.com>
Tracepoint handlers are now fully preemptible. When a per-CPU monitor
handles an event, it retrieves the monitor state using a per-CPU
pointer. If the event itself doesn't disable preemption, the task can
migrate to a different CPU and we risk updating the wrong monitor.
Mitigate this by explicitly disabling task migration before acquiring
the monitor pointer. This cannot guarantee the monitor runs on the
correct CPU but reduces the race condition window and prevents warnings.
Reviewed-by: Wen Yang <wen.yang@linux.dev>
Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
---
include/rv/da_monitor.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/include/rv/da_monitor.h b/include/rv/da_monitor.h
index 0b7028df08fb..a9fd284195ee 100644
--- a/include/rv/da_monitor.h
+++ b/include/rv/da_monitor.h
@@ -181,6 +181,10 @@ static inline void da_monitor_destroy(void)
da_monitor_reset_all();
}
+#ifndef da_implicit_guard
+#define da_implicit_guard()
+#endif
+
#elif RV_MON_TYPE == RV_MON_PER_CPU
/*
* Functions to define, init and get a per-cpu monitor.
@@ -230,6 +234,10 @@ static inline void da_monitor_destroy(void)
da_monitor_reset_all();
}
+#ifndef da_implicit_guard
+#define da_implicit_guard() guard(migrate)()
+#endif
+
#elif RV_MON_TYPE == RV_MON_PER_TASK
/*
* Functions to define, init and get a per-task monitor.
@@ -677,6 +685,7 @@ static inline bool __da_handle_start_run_event(struct da_monitor *da_mon,
*/
static inline void da_handle_event(enum events event)
{
+ da_implicit_guard();
__da_handle_event(da_get_monitor(), event, 0);
}
@@ -692,6 +701,7 @@ static inline void da_handle_event(enum events event)
*/
static inline bool da_handle_start_event(enum events event)
{
+ da_implicit_guard();
return __da_handle_start_event(da_get_monitor(), event, 0);
}
@@ -703,6 +713,7 @@ static inline bool da_handle_start_event(enum events event)
*/
static inline bool da_handle_start_run_event(enum events event)
{
+ da_implicit_guard();
return __da_handle_start_run_event(da_get_monitor(), event, 0);
}
--
2.54.0
^ permalink raw reply related
* [PATCH v2 05/12] rv: Prevent in-flight per-task handlers from using invalid slots
From: Gabriele Monaco @ 2026-05-27 6:23 UTC (permalink / raw)
To: linux-kernel, Steven Rostedt, Gabriele Monaco, Nam Cao,
linux-trace-kernel
Cc: Wen Yang
In-Reply-To: <20260527062313.39908-1-gmonaco@redhat.com>
Per-task monitors use a slot in the task_struct->rv[] array and store
that locally (e.g. task_mon_slot), this slot is returned during the
destruction process but currently hanlers can be running while that slot
is returning and this race may lead to accessing an invalid slot.
Synchronise with all in-flight tracepoint handlers using
tracepoint_synchronize_unregister() before returning the slot.
Fixes: f5587d1b6ec9 ("rv: Add Hybrid Automata monitor type")
Fixes: a9769a5b9878 ("rv: Add support for LTL monitors")
Suggested-by: Wen Yang <wen.yang@linux.dev>
Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
---
include/rv/da_monitor.h | 4 ++++
include/rv/ltl_monitor.h | 1 +
2 files changed, 5 insertions(+)
diff --git a/include/rv/da_monitor.h b/include/rv/da_monitor.h
index a9fd284195ee..446a4d53d99c 100644
--- a/include/rv/da_monitor.h
+++ b/include/rv/da_monitor.h
@@ -310,6 +310,9 @@ static int da_monitor_init(void)
/*
* da_monitor_destroy - return the allocated slot
+ *
+ * Wait for all in-flight handlers before returning the slot to avoid
+ * out-of-bound accesses.
*/
static inline void da_monitor_destroy(void)
{
@@ -320,6 +323,7 @@ static inline void da_monitor_destroy(void)
da_monitor_reset_all();
+ tracepoint_synchronize_unregister();
rv_put_task_monitor_slot(task_mon_slot);
task_mon_slot = RV_PER_TASK_MONITOR_INIT;
}
diff --git a/include/rv/ltl_monitor.h b/include/rv/ltl_monitor.h
index eff60cd61106..38e792401f76 100644
--- a/include/rv/ltl_monitor.h
+++ b/include/rv/ltl_monitor.h
@@ -77,6 +77,7 @@ static void ltl_monitor_destroy(void)
{
rv_detach_trace_probe(name, task_newtask, handle_task_newtask);
+ tracepoint_synchronize_unregister();
rv_put_task_monitor_slot(ltl_monitor_slot);
ltl_monitor_slot = RV_PER_TASK_MONITOR_INIT;
}
--
2.54.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox