public inbox for bpf@vger.kernel.org
 help / color / mirror / Atom feed
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
To: bpf@vger.kernel.org
Cc: Alexei Starovoitov <ast@kernel.org>,
	Andrii Nakryiko <andrii@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Martin KaFai Lau <martin.lau@kernel.org>,
	Eduard Zingerman <eddyz87@gmail.com>,
	Ihor Solodrai <ihor.solodrai@linux.dev>,
	kkd@meta.com, kernel-team@meta.com
Subject: [PATCH bpf-next v2 5/6] bpf: Add __bpf_kfunc_replacement() annotation
Date: Wed,  8 Apr 2026 04:13:56 +0200	[thread overview]
Message-ID: <20260408021359.3786905-6-memxor@gmail.com> (raw)
In-Reply-To: <20260408021359.3786905-1-memxor@gmail.com>

Add an annotation to emit more contextual messages per deprecated kfunc
about which replacement kfunc can be used in its place.  The macro
itself takes the replacement kfunc as the argument.

This uses BTF declaration tags, and is only supplied as a warning to the
user when the kernel is compiled using LLVM, as GCC lacks equivalent
support. That said, in all cases KF_DEPRECATED does produce a warning,
so this strictly leads to an improved message where possible.

Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
---
 include/linux/btf.h                                |  5 +++++
 include/linux/compiler_types.h                     | 14 ++++++++++++--
 kernel/bpf/helpers.c                               |  8 ++++++++
 kernel/bpf/verifier.c                              |  9 +++++++++
 .../testing/selftests/bpf/test_kmods/bpf_testmod.c |  1 +
 5 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/include/linux/btf.h b/include/linux/btf.h
index 86006a2d8b2a..50cc8aa50e7a 100644
--- a/include/linux/btf.h
+++ b/include/linux/btf.h
@@ -89,6 +89,11 @@
  */
 #define __bpf_kfunc __used __retain __noclone noinline
 
+#define BPF_KFUNC_DECL_TAG_REPLACEMENT "bpf:kfunc:replacement:"
+
+#define __bpf_kfunc_replacement(replacement) \
+	BTF_DECL_TAG(BPF_KFUNC_DECL_TAG_REPLACEMENT __stringify(replacement))
+
 #define __bpf_kfunc_start_defs()					       \
 	__diag_push();							       \
 	__diag_ignore_all("-Wmissing-declarations",			       \
diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
index 890076d0974b..ef840212dc56 100644
--- a/include/linux/compiler_types.h
+++ b/include/linux/compiler_types.h
@@ -35,10 +35,20 @@
  * see https://github.com/rust-lang/rust-bindgen/issues/2244.
  */
 #if defined(CONFIG_DEBUG_INFO_BTF) && defined(CONFIG_PAHOLE_HAS_BTF_TAG) && \
-	__has_attribute(btf_type_tag) && !defined(__BINDGEN__)
-# define BTF_TYPE_TAG(value) __attribute__((btf_type_tag(#value)))
+	!defined(__BINDGEN__)
+# if __has_attribute(btf_type_tag)
+#  define BTF_TYPE_TAG(value) __attribute__((btf_type_tag(#value)))
+# else
+#  define BTF_TYPE_TAG(value) /* nothing */
+# endif
+# if __has_attribute(btf_decl_tag)
+#  define BTF_DECL_TAG(value) __attribute__((btf_decl_tag(value)))
+# else
+#  define BTF_DECL_TAG(value) /* nothing */
+# endif
 #else
 # define BTF_TYPE_TAG(value) /* nothing */
+# define BTF_DECL_TAG(value) /* nothing */
 #endif
 
 #include <linux/compiler-context-analysis.h>
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index 190c0b382f11..a07ebc0597a3 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -2328,6 +2328,7 @@ __bpf_kfunc void *bpf_obj_new(u64 local_type_id__k, struct btf_struct_meta *meta
 	return p;
 }
 
+__bpf_kfunc_replacement(bpf_obj_new)
 __bpf_kfunc void *bpf_obj_new_impl(u64 local_type_id__k, void *meta__ign)
 {
 	return bpf_obj_new(local_type_id__k, meta__ign);
@@ -2352,6 +2353,7 @@ __bpf_kfunc void *bpf_percpu_obj_new(u64 local_type_id__k, struct btf_struct_met
 	return bpf_mem_alloc(&bpf_global_percpu_ma, size);
 }
 
+__bpf_kfunc_replacement(bpf_percpu_obj_new)
 __bpf_kfunc void *bpf_percpu_obj_new_impl(u64 local_type_id__k, void *meta__ign)
 {
 	return bpf_percpu_obj_new(local_type_id__k, meta__ign);
@@ -2395,6 +2397,7 @@ __bpf_kfunc void bpf_obj_drop(void *p__alloc, struct btf_struct_meta *meta)
 	__bpf_obj_drop_impl(p, meta ? meta->record : NULL, false);
 }
 
+__bpf_kfunc_replacement(bpf_obj_drop)
 __bpf_kfunc void bpf_obj_drop_impl(void *p__alloc, void *meta__ign)
 {
 	return bpf_obj_drop(p__alloc, meta__ign);
@@ -2413,6 +2416,7 @@ __bpf_kfunc void bpf_percpu_obj_drop(void *p__alloc, struct btf_struct_meta *met
 	bpf_mem_free_rcu(&bpf_global_percpu_ma, p__alloc);
 }
 
+__bpf_kfunc_replacement(bpf_percpu_obj_drop)
 __bpf_kfunc void bpf_percpu_obj_drop_impl(void *p__alloc, void *meta__ign)
 {
 	bpf_percpu_obj_drop(p__alloc, meta__ign);
@@ -2445,6 +2449,7 @@ __bpf_kfunc void *bpf_refcount_acquire(void *p__refcounted_kptr, struct btf_stru
 	return (void *)p__refcounted_kptr;
 }
 
+__bpf_kfunc_replacement(bpf_refcount_acquire)
 __bpf_kfunc void *bpf_refcount_acquire_impl(void *p__refcounted_kptr, void *meta__ign)
 {
 	return bpf_refcount_acquire(p__refcounted_kptr, meta__ign);
@@ -2499,6 +2504,7 @@ __bpf_kfunc int bpf_list_push_front(struct bpf_list_head *head,
 	return __bpf_list_add(n, head, false, meta ? meta->record : NULL, off);
 }
 
+__bpf_kfunc_replacement(bpf_list_push_front)
 __bpf_kfunc int bpf_list_push_front_impl(struct bpf_list_head *head,
 					 struct bpf_list_node *node,
 					 void *meta__ign, u64 off)
@@ -2528,6 +2534,7 @@ __bpf_kfunc int bpf_list_push_back(struct bpf_list_head *head,
 	return __bpf_list_add(n, head, true, meta ? meta->record : NULL, off);
 }
 
+__bpf_kfunc_replacement(bpf_list_push_back)
 __bpf_kfunc int bpf_list_push_back_impl(struct bpf_list_head *head,
 					struct bpf_list_node *node,
 					void *meta__ign, u64 off)
@@ -2668,6 +2675,7 @@ __bpf_kfunc int bpf_rbtree_add(struct bpf_rb_root *root,
 	return __bpf_rbtree_add(root, n, (void *)less, meta ? meta->record : NULL, off);
 }
 
+__bpf_kfunc_replacement(bpf_rbtree_add)
 __bpf_kfunc int bpf_rbtree_add_impl(struct bpf_rb_root *root, struct bpf_rb_node *node,
 				    bool (less)(struct bpf_rb_node *a, const struct bpf_rb_node *b),
 				    void *meta__ign, u64 off)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 267ab3c36f6f..535b4af710a8 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -14594,6 +14594,8 @@ static void warn_for_deprecated_kfuncs(struct bpf_verifier_env *env,
 				       int insn_idx, s16 offset)
 {
 	const struct bpf_line_info *linfo;
+	const char *replacement;
+	const struct btf_type *t;
 	struct bpf_kfunc_desc *desc;
 	const char *file;
 	int line_num;
@@ -14612,6 +14614,13 @@ static void warn_for_deprecated_kfuncs(struct bpf_verifier_env *env,
 		     insn_idx, meta->func_name);
 	}
 
+	t = btf_type_by_id(meta->btf, meta->func_id);
+	replacement = btf_find_decl_tag_value(meta->btf, t, -1, BPF_KFUNC_DECL_TAG_REPLACEMENT);
+	if (!IS_ERR(replacement) && !str_is_empty(replacement)) {
+		warn(env, "Switch to kfunc %s() instead.\n", replacement);
+		warn(env, "For older kernels, choose the correct kfunc using bpf_ksym_exists().\n");
+	}
+
 	desc->warned_deprecated = true;
 }
 
diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
index 6ad7b2cdfd05..7391247e3d18 100644
--- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
+++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
@@ -1252,6 +1252,7 @@ __bpf_kfunc int bpf_kfunc_multi_st_ops_test_1_assoc(struct st_ops_args *args, st
 
 __bpf_kfunc int bpf_kfunc_implicit_arg(int a, struct bpf_prog_aux *aux);
 __bpf_kfunc int bpf_kfunc_implicit_arg_legacy(int a, int b, struct bpf_prog_aux *aux);
+__bpf_kfunc_replacement(bpf_kfunc_implicit_arg_legacy)
 __bpf_kfunc int bpf_kfunc_implicit_arg_legacy_impl(int a, int b, struct bpf_prog_aux *aux);
 
 /* hook targets */
-- 
2.52.0


  parent reply	other threads:[~2026-04-08  2:14 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-08  2:13 [PATCH bpf-next v2 0/6] Add support to emit verifier warnings Kumar Kartikeya Dwivedi
2026-04-08  2:13 ` [PATCH bpf-next v2 1/6] bpf: Add support for verifier warning messages Kumar Kartikeya Dwivedi
2026-04-08  8:46   ` sun jian
2026-04-08  2:13 ` [PATCH bpf-next v2 2/6] bpf: Extract bpf_get_linfo_file_line Kumar Kartikeya Dwivedi
2026-04-08  2:13 ` [PATCH bpf-next v2 3/6] bpf: Make find_linfo widely available Kumar Kartikeya Dwivedi
2026-04-08 15:46   ` Mykyta Yatsenko
2026-04-08  2:13 ` [PATCH bpf-next v2 4/6] bpf: Use KF_DEPRECATED to emit verifier warnings Kumar Kartikeya Dwivedi
2026-04-08  2:13 ` Kumar Kartikeya Dwivedi [this message]
2026-04-08  2:13 ` [PATCH bpf-next v2 6/6] libbpf: Flush verifier warning messages by default Kumar Kartikeya Dwivedi
2026-04-08  2:21   ` Kumar Kartikeya Dwivedi
2026-04-08 14:55 ` [PATCH bpf-next v2 0/6] Add support to emit verifier warnings Leon Hwang
2026-04-08 15:30   ` Leon Hwang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260408021359.3786905-6-memxor@gmail.com \
    --to=memxor@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=ihor.solodrai@linux.dev \
    --cc=kernel-team@meta.com \
    --cc=kkd@meta.com \
    --cc=martin.lau@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox