hi, this patchset adds support to optimize usdt probes on top of 5-byte nop instruction.
The generic approach (optimize all uprobes) is hard due to emulating possible multiple original instructions and its related issues. The usdt case, which stores 5-byte nop seems much easier, so starting with that. The basic idea is to replace breakpoint exception with syscall which is faster on x86_64. For more details please see changelog of patch 8. The run_bench_uprobes.sh benchmark triggers uprobe (on top of different original instructions) in a loop and counts how many of those happened per second (the unit below is million loops). There's big speed up if you consider current usdt implementation (uprobe-nop) compared to proposed usdt (uprobe-nop5): current: usermode-count : 152.501 ± 0.012M/s syscall-count : 14.463 ± 0.062M/s --> uprobe-nop : 3.160 ± 0.005M/s uprobe-push : 3.003 ± 0.003M/s uprobe-ret : 1.100 ± 0.003M/s uprobe-nop5 : 3.132 ± 0.012M/s uretprobe-nop : 2.103 ± 0.002M/s uretprobe-push : 2.027 ± 0.004M/s uretprobe-ret : 0.914 ± 0.002M/s uretprobe-nop5 : 2.115 ± 0.002M/s after the change: usermode-count : 152.343 ± 0.400M/s syscall-count : 14.851 ± 0.033M/s uprobe-nop : 3.204 ± 0.005M/s uprobe-push : 3.040 ± 0.005M/s uprobe-ret : 1.098 ± 0.003M/s --> uprobe-nop5 : 7.286 ± 0.017M/s uretprobe-nop : 2.144 ± 0.001M/s uretprobe-push : 2.069 ± 0.002M/s uretprobe-ret : 0.922 ± 0.000M/s uretprobe-nop5 : 3.487 ± 0.001M/s I see bit more speed up on Intel (above) compared to AMD. The big nop5 speed up is partly due to emulating nop5 and partly due to optimization. The key speed up we do this for is the USDT switch from nop to nop5: uprobe-nop : 3.160 ± 0.005M/s uprobe-nop5 : 7.286 ± 0.017M/s Changes from v1: - rebased on top of tip/master + mm/mm-stable + 1 extra change [1] - keep the refcrf offset update inside write_insn and enabling it via function argument - fixed locking comment for uprobe_write_opcode, but skiped suggested comment on register_for_each_vma, need more thinking on that [Oleg] - added acks - removed refctr from uprobe_trampoline object [Oleg] - change find_nearest_page to use vm_unmapped_area [Oleg] - re-structured x86 set_swbp [Andrii] - use -EINVAL in __arch_uprobe_optimize [Andrii] - added usdt.h from libbpf/usdt project [Andrii] - several minor test code changes [Andrii] - man page updates [Alejandro] This patchset is adding new syscall, here are notes to check list items in Documentation/process/adding-syscalls.rst: - System Call Alternatives New syscall seems like the best way in here, because we need just to quickly enter kernel with no extra arguments processing, which we'd need to do if we decided to use another syscall. - Designing the API: Planning for Extension The uprobe syscall is very specific and most likely won't be extended in the future. - Designing the API: Other Considerations N/A because uprobe syscall does not return reference to kernel object. - Proposing the API Wiring up of the uprobe system call is in separate change, selftests and man page changes are part of the patchset. - Generic System Call Implementation There's no CONFIG option for the new functionality because it keeps the same behaviour from the user POV. - x86 System Call Implementation It's 64-bit syscall only. - Compatibility System Calls (Generic) N/A uprobe syscall has no arguments and is not supported for compat processes. - Compatibility System Calls (x86) N/A uprobe syscall is not supported for compat processes. - System Calls Returning Elsewhere N/A. - Other Details N/A. - Testing Adding new bpf selftests. - Man Page Attached. - Do not call System Calls in the Kernel N/A pending todo (or follow ups): - use PROCMAP_QUERY in tests - alloc 'struct uprobes_state' for mm_struct only when needed [Andrii] - use mm_cpumask(vma->vm_mm) in text_poke_sync thanks, jirka Cc: Alejandro Colomar <a...@kernel.org> Cc: Eyal Birger <eyal.bir...@gmail.com> Cc: k...@kernel.org [1] https://lore.kernel.org/linux-trace-kernel/20250514101809.2010193-1-jo...@kernel.org/T/#u --- Jiri Olsa (21): uprobes: Remove breakpoint in unapply_uprobe under mmap_write_lock uprobes: Rename arch_uretprobe_trampoline function uprobes: Make copy_from_page global uprobes: Add uprobe_write function uprobes: Add nbytes argument to uprobe_write uprobes: Add is_register argument to uprobe_write and uprobe_write_opcode uprobes: Add do_ref_ctr argument to uprobe_write function uprobes/x86: Add mapping for optimized uprobe trampolines uprobes/x86: Add uprobe syscall to speed up uprobe uprobes/x86: Add support to optimize uprobes selftests/bpf: Import usdt.h from libbpf/usdt project selftests/bpf: Reorg the uprobe_syscall test function selftests/bpf: Rename uprobe_syscall_executed prog to test_uretprobe_multi selftests/bpf: Add uprobe/usdt syscall tests selftests/bpf: Add hit/attach/detach race optimized uprobe test selftests/bpf: Add uprobe syscall sigill signal test selftests/bpf: Add optimized usdt variant for basic usdt test selftests/bpf: Add uprobe_regs_equal test selftests/bpf: Change test_uretprobe_regs_change for uprobe and uretprobe seccomp: passthrough uprobe systemcall without filtering selftests/seccomp: validate uprobe syscall passes through seccomp arch/arm/probes/uprobes/core.c | 2 +- arch/x86/entry/syscalls/syscall_64.tbl | 1 + arch/x86/include/asm/uprobes.h | 7 ++ arch/x86/kernel/uprobes.c | 525 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- include/linux/syscalls.h | 2 + include/linux/uprobes.h | 20 +++- kernel/events/uprobes.c | 100 ++++++++++++----- kernel/fork.c | 1 + kernel/seccomp.c | 32 ++++-- kernel/sys_ni.c | 1 + tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c | 511 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ tools/testing/selftests/bpf/prog_tests/usdt.c | 38 ++++--- tools/testing/selftests/bpf/progs/uprobe_syscall.c | 4 +- tools/testing/selftests/bpf/progs/uprobe_syscall_executed.c | 45 +++++++- tools/testing/selftests/bpf/test_kmods/bpf_testmod.c | 11 +- tools/testing/selftests/bpf/usdt.h | 545 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/testing/selftests/seccomp/seccomp_bpf.c | 107 ++++++++++++++---- 17 files changed, 1838 insertions(+), 114 deletions(-) create mode 100644 tools/testing/selftests/bpf/usdt.h Jiri Olsa (1): man2: Add uprobe syscall page man/man2/uprobe.2 | 1 + man/man2/uretprobe.2 | 36 ++++++++++++++++++++++++------------ 2 files changed, 25 insertions(+), 12 deletions(-) create mode 100644 man/man2/uprobe.2