[RFC PATCH bpf-next 1/7] bpf: Set up update_prog scaffolding for bpf_tracing_link_lops

bot+bpf-ci at kernel.org bot+bpf-ci at kernel.org
Mon Nov 17 17:27:45 PST 2025


> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 09d5dc541..23fcbcd26 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h

[ ... ]

> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
> index a2a441185..14dd8be7b 100644
> --- a/kernel/bpf/syscall.c
> +++ b/kernel/bpf/syscall.c

[ ... ]

> diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
> index 04104397c..d2fd02e10 100644
> --- a/kernel/bpf/trampoline.c
> +++ b/kernel/bpf/trampoline.c
> @@ -607,6 +607,35 @@ int bpf_trampoline_link_prog(struct bpf_tramp_link *link,
>  	return err;
>  }
>
> +static int __bpf_trampoline_update_prog(struct bpf_tramp_link *link,
> +					struct bpf_prog *new_prog,
> +					struct bpf_trampoline *tr)
> +{
> +	return -ENOTSUPP;
> +}
> +
> +int bpf_trampoline_update_prog(struct bpf_tramp_link *link,
> +			       struct bpf_prog *new_prog,
> +			       struct bpf_trampoline *tr)
> +{
> +	struct bpf_prog *old_prog;
> +	int err;
> +
> +	mutex_lock(&tr->mutex);
> +	err = __bpf_trampoline_update_prog(link, new_prog, tr);
> +	if (!err) {
> +		/* If a program update was successful, switch the program
> +		 * in the link before releasing tr->mutex; otherwise, another
> +		 * operation could come along and update the trampoline with
> +		 * the link still pointing at the old program.
> +		 */
> +		old_prog = xchg(&link->link.prog, new_prog);
> +		bpf_prog_put(old_prog);
> +	}
> +	mutex_unlock(&tr->mutex);
> +	return err;
> +}
> +

Can bpf_prog_put() be called while holding tr->mutex?

When bpf_prog_put()->__bpf_prog_put() drops the program's refcount to
zero and we're not in IRQ context (which we aren't when holding a regular
mutex), it directly calls bpf_prog_put_deferred(). This eventually calls
bpf_trampoline_put(), which takes trampoline_mutex.

The existing code in bpf_trampoline_link_cgroup_shim() carefully unlocks
tr->mutex before calling bpf_trampoline_put() (see the comment "have to
release tr while _not_ holding its mutex"). Additionally,
bpf_trampoline_put() has WARN_ON_ONCE(mutex_is_locked(&tr->mutex)) to
catch this pattern.

Should bpf_prog_put() be moved after mutex_unlock(&tr->mutex)?

>  static int __bpf_trampoline_unlink_prog(struct bpf_tramp_link *link,
>  					struct bpf_trampoline *tr,
>  					struct bpf_prog *tgt_prog)

[ ... ]


---
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/19450205468


More information about the linux-arm-kernel mailing list