Re: [PATCH 1/3] kprobes: Disarm disabled optprobe on forced unoptimization

From: Masami Hiramatsu (Google)

Date: Wed Nov 04 2026 - 01:49:45 EST


Hi Mani,

On Tue, 03 Nov 2026 13:45:59 -0500, Mani Tofigh <mt4022@xxxxxxxxxxxx> wrote:

> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> --- a/kernel/kprobes.c
> +++ b/kernel/kprobes.c
> @@ -1006,6 +1006,9 @@ static void unoptimize_kprobe(struct kprobe *p, bool force)
> list_move(&op->list, &cur->freeing_list);
> } else {
> + /* Disarm probes if marked disabled and not gone */
> + if (kprobe_disabled(&op->kp) && !kprobe_gone(&op->kp))

Nice catch!

BTW, since `kprobe_unused(&op->kp)` checks `kprobe_disabled(&op->kp)`
(see definition in `kprobe_unused()`), both the `kprobe_unused()` block
and this `else` block execute the same `arch_disarm_kprobe(&op->kp)`
under `kprobe_disabled(&op->kp) && !kprobe_gone(&op->kp)`.

So we can factor this disarm check out above the
`if (kprobe_unused(&op->kp))` block as below:

force_unoptimize_kprobe(op);
/* Disarm probes if marked disabled and not gone */
if (kprobe_disabled(&op->kp) && !kprobe_gone(&op->kp))
arch_disarm_kprobe(&op->kp);

if (kprobe_unused(&op->kp)) {
hlist_del_init_rcu(&op->kp.hlist);
list_move(&op->list, &cur->freeing_list);
} else {
list_move(&op->list, &cur->cooling_list);
}

This makes the invariant clearer: once an optprobe is forcibly unoptimized,
if it is disabled it is immediately disarmed, regardless of whether it is
queued for freeing or cooling.

Thanks!

> + arch_disarm_kprobe(&op->kp);
> list_move(&op->list, &cur->cooling_list);
> }

--
Masami Hiramatsu (Google) <mhiramat@xxxxxxxxxx>