summaryrefslogtreecommitdiff
path: root/scripts/basic/split-include.c
diff options
context:
space:
mode:
authorMasami Hiramatsu (Google) <mhiramat@kernel.org>2026-10-02 13:48:49 +0900
committerMasami Hiramatsu (Google) <mhiramat@kernel.org>2026-10-03 09:27:54 +0900
commit06e0d3b89da12f24ed5ed434acc8e2cb504f5e4f (patch)
treeb798836221573b9611bf3953196fc8dc2bc700fe /scripts/basic/split-include.c
parentf3c6c0549e87b92d309700cf2c0ebe94056428e0 (diff)
downloadlinux-06e0d3b89da12f24ed5ed434acc8e2cb504f5e4f.tar.gz
linux-06e0d3b89da12f24ed5ed434acc8e2cb504f5e4f.zip
kprobes: Make optprobe optimizer multi-generational and asynchronous
Currently, kprobe_optimizer() holds kprobe_mutex, text_mutex, and cpus_read_lock() simultaneously while executing synchronize_rcu_tasks(). Under PREEMPT_LAZY and server workloads with long-running CPU-bound kernel tasks or heavy cgroup writeback loops, synchronize_rcu_tasks() can block for seconds to minutes. Because text_mutex and cpus_read_lock() are held during this entire wait, any concurrent static key updates, module loading/unloading, CPU hotplug, or tracing updates stall, frequently triggering hung-task detector panics. Instead of penalizing the kernel preemption path with invasive hooks and global hash lookups, decouple kprobe jump optimization from synchronous waiting entirely: 1. Replace synchronize_rcu_tasks() with call_rcu_tasks(). Locks (text_mutex and cpus_read_lock()) are held only for the brief moment needed to patch instructions via arch_unoptimize_kprobes() and arch_optimize_kprobes() (microseconds), and are completely released while waiting for the Tasks RCU grace period. 2. Introduce a fixed ring of generations (optprobe_gens[OPTPROBE_GEN_MAX]) to avoid any dynamic memory allocation (kmalloc) or -ENOMEM failure modes. 3. The last generation slot in the array is reserved as a "waiting room" and is not dispatched to RCU until another in-flight generation has finished. While a generation is waiting for its Tasks RCU grace period, any newly registered or unregistered probes accumulate in the waiting room generation without blocking or requiring additional slots. 4. When the Tasks RCU callback fires, it marks the generation as ready and wakes up the optimizer thread to finalize optimization (poking the jump instructions) and free cleaned probe slots. Once finalized, the generation is marked idle, allowing the waiting room generation to be dispatched next. 5. Flushing via wait_for_kprobe_optimizer() waits asynchronously for all in-flight and queued generations to drain without stalling other kernel subsystems. On non-preemptive kernels or configs where CONFIG_TASKS_RCU=n, call_rcu_tasks() transparently aliases to call_rcu(), preserving full portability. Link: https://lore.kernel.org/all/179091652953.526694.3402334249215311330.stgit@devnote2/ Assisted-by: LLM Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Diffstat (limited to 'scripts/basic/split-include.c')
0 files changed, 0 insertions, 0 deletions