On Tue, 22 Sep 2026 02:23:22 +0000 Josef Bacik <[email protected]> wrote:
> kprobe_optimizer() is the one synchronize_rcu_tasks() user that is not > about trampoline text: it waits for tasks that were interrupted on an > instruction boundary inside the bytes it is about to overwrite with the > optimized jump, so that none of them resumes into the middle of the new > instruction. Those bytes are ordinary kernel or module text with no > Tasks Trace reader around them, so on CONFIG_TASKS_RCU_TRAMPOLINE_READERS > kernels the irq-exit quiescent-state check has to be told about them. > > Add kprobe_in_optimized_region(), a lockless and conservative form of > get_optimized_kprobe() that reports whether any registered kprobe lies > within MAX_OPTIMIZED_LENGTH before the given address regardless of its > optimization state, and have rcu_tasks_trampoline_text() consult it for > core and module text so that a task interrupted there becomes a holdout > rather than a quiescent event. The hash walk only runs while > kprobe_optimizer() is actually inside its synchronize_rcu_tasks(), > tracked by a flag it sets around the call; otherwise the check is a > single load. That check cannot see a task that was already preempted in > the region before the flag went up (possibly before the kprobe even > existed), and the new grace period does not otherwise wait for a > preempted task to run again, so before synchronize_rcu_tasks() the > optimizer calls rcu_tasks_wait_irq_preempted() to wait until no parked > task's recorded irq-exit preemption IP is inside such a region; its > leading synchronize_rcu() also publishes the flag to every (interrupts- > disabled) check in flight. The kprobe hash is RCU-protected and every > free path waits for a grace period after unhashing, so the lockless walk > from the irq-exit path is safe. > > On other configurations the flag is set and cleared but nothing reads > it and rcu_tasks_wait_irq_preempted() is a stub; the classic > implementation already waits for such tasks. Hmm, this seems a bit awkward. To solve this problem with tasks RCU is not a straight solution. I rather like to suggest fixing kprobe_optimizer. Since the root cause of the mutex related hang_task stall is the kprobe_optimizer() waits RCU under locking mutexes -- text_mutex, cpu_read_lock, and kprobe_mutex. When I introduced this, waiting RCU grace period did not take so long time. But now it can take longer, so it is a good chance to fix it completely. Since the RCU is a kind of the generation control of internal state, we can introduce multi-generation optimizing/freeing list and RCU tasks callback for that. Let me try to make another series to fix optprobe side. Thank you, -- Masami Hiramatsu (Google) <[email protected]>
