linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Menglong Dong <menglong8.dong@gmail.com>
To: alexei.starovoitov@gmail.com, rostedt@goodmis.org, jolsa@kernel.org
Cc: bpf@vger.kernel.org, Menglong Dong <dongml2@chinatelecom.cn>,
	linux-kernel@vger.kernel.org
Subject: [PATCH bpf-next 04/25] bpf: make kfunc_md support global trampoline link
Date: Wed, 28 May 2025 11:46:51 +0800	[thread overview]
Message-ID: <20250528034712.138701-5-dongml2@chinatelecom.cn> (raw)
In-Reply-To: <20250528034712.138701-1-dongml2@chinatelecom.cn>

Introduce the struct kfunc_md_tramp_prog for BPF_PROG_TYPE_TRACING, and
add the field "bpf_progs" to struct kfunc_md. These filed will be used
in the next patch of bpf global trampoline.

And the KFUNC_MD_FL_TRACING_ORIGIN is introduced to indicate that origin
call is needed on this function.

Add the function kfunc_md_bpf_link and kfunc_md_bpf_unlink to add or
remove bpf prog to kfunc_md. Meanwhile, introduce kunfc_md_bpf_ips() to
get all the kernel functions in kfunc_mds that contains bpf progs.

The KFUNC_MD_FL_BPF_REMOVING indicate that a removing operation is in
progress, and we shouldn't return it if "bpf_prog_cnt<=1" in
kunfc_md_bpf_ips().

Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
 include/linux/kfunc_md.h |  17 ++++++
 kernel/trace/kfunc_md.c  | 118 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 135 insertions(+)

diff --git a/include/linux/kfunc_md.h b/include/linux/kfunc_md.h
index 21c0b879cc03..f1b1012eeab2 100644
--- a/include/linux/kfunc_md.h
+++ b/include/linux/kfunc_md.h
@@ -3,12 +3,21 @@
 #define _LINUX_KFUNC_MD_H
 
 #define KFUNC_MD_FL_DEAD		(1 << 0) /* the md shouldn't be reused */
+#define KFUNC_MD_FL_TRACING_ORIGIN	(1 << 1)
+#define KFUNC_MD_FL_BPF_REMOVING	(1 << 2)
 
 #ifndef __ASSEMBLER__
 
 #include <linux/kernel.h>
 #include <linux/bpf.h>
 
+struct kfunc_md_tramp_prog {
+	struct kfunc_md_tramp_prog *next;
+	struct bpf_prog *prog;
+	u64 cookie;
+	struct rcu_head rcu;
+};
+
 struct kfunc_md_array;
 
 struct kfunc_md {
@@ -19,6 +28,7 @@ struct kfunc_md {
 	struct rcu_head rcu;
 #endif
 	unsigned long func;
+	struct kfunc_md_tramp_prog *bpf_progs[BPF_TRAMP_MAX];
 #ifdef CONFIG_FUNCTION_METADATA
 	/* the array is used for the fast mode */
 	struct kfunc_md_array *array;
@@ -26,6 +36,7 @@ struct kfunc_md {
 	struct percpu_ref pcref;
 	u32 flags;
 	u16 users;
+	u8 bpf_prog_cnt;
 	u8 nr_args;
 };
 
@@ -40,5 +51,11 @@ void kfunc_md_exit(struct kfunc_md *md);
 void kfunc_md_enter(struct kfunc_md *md);
 bool kfunc_md_arch_support(int *insn, int *data);
 
+int kfunc_md_bpf_ips(void ***ips);
+
+int kfunc_md_bpf_unlink(struct kfunc_md *md, struct bpf_prog *prog, int type);
+int kfunc_md_bpf_link(struct kfunc_md *md, struct bpf_prog *prog, int type,
+		      u64 cookie);
+
 #endif
 #endif
diff --git a/kernel/trace/kfunc_md.c b/kernel/trace/kfunc_md.c
index 9571081f6560..ebb4e46d482d 100644
--- a/kernel/trace/kfunc_md.c
+++ b/kernel/trace/kfunc_md.c
@@ -131,6 +131,23 @@ static bool kfunc_md_fast(void)
 {
 	return static_branch_likely(&kfunc_md_use_padding);
 }
+
+static int kfunc_md_hash_bpf_ips(void **ips)
+{
+	struct hlist_head *head;
+	struct kfunc_md *md;
+	int c = 0, i;
+
+	for (i = 0; i < (1 << KFUNC_MD_HASH_BITS); i++) {
+		head = &kfunc_md_table[i];
+		hlist_for_each_entry(md, head, hash) {
+			if (md->bpf_prog_cnt > !!(md->flags & KFUNC_MD_FL_BPF_REMOVING))
+				ips[c++] = (void *)md->func;
+		}
+	}
+
+	return c;
+}
 #else
 
 static void kfunc_md_hash_put(struct kfunc_md *md)
@@ -148,6 +165,11 @@ static struct kfunc_md *kfunc_md_hash_create(unsigned long ip, int nr_args)
 }
 
 #define kfunc_md_fast() 1
+
+static int kfunc_md_hash_bpf_ips(void **ips)
+{
+	return 0;
+}
 #endif /* CONFIG_FUNCTION_METADATA_PADDING */
 
 #ifdef CONFIG_FUNCTION_METADATA
@@ -442,6 +464,19 @@ static struct kfunc_md *kfunc_md_fast_create(unsigned long ip, int nr_args)
 
 	return md;
 }
+
+static int kfunc_md_fast_bpf_ips(void **ips)
+{
+	struct kfunc_md *md;
+	int i, c = 0;
+
+	for (i = 0; i < kfunc_mds->kfunc_md_count; i++) {
+		md = &kfunc_mds->mds[i];
+		if (md->users && md->bpf_prog_cnt > !!(md->flags & KFUNC_MD_FL_BPF_REMOVING))
+			ips[c++] = (void *)md->func;
+	}
+	return c;
+}
 #else
 
 static void kfunc_md_fast_put(struct kfunc_md *md)
@@ -458,6 +493,10 @@ static struct kfunc_md *kfunc_md_fast_create(unsigned long ip, int nr_args)
 	return NULL;
 }
 
+static int kfunc_md_fast_bpf_ips(void **ips)
+{
+	return 0;
+}
 #endif /* !CONFIG_FUNCTION_METADATA */
 
 void kfunc_md_enter(struct kfunc_md *md)
@@ -547,6 +586,85 @@ struct kfunc_md *kfunc_md_create(unsigned long ip, int nr_args)
 }
 EXPORT_SYMBOL_GPL(kfunc_md_create);
 
+int kfunc_md_bpf_ips(void ***ips)
+{
+	void **tmp;
+	int c;
+
+	c = atomic_read(&kfunc_mds->kfunc_md_used);
+	if (!c)
+		return 0;
+
+	tmp = kmalloc_array(c, sizeof(*tmp), GFP_KERNEL);
+	if (!tmp)
+		return -ENOMEM;
+
+	rcu_read_lock();
+	c = CALL(kfunc_md_fast_bpf_ips, kfunc_md_hash_bpf_ips, int, tmp);
+	rcu_read_unlock();
+
+	*ips = tmp;
+
+	return c;
+}
+
+int kfunc_md_bpf_link(struct kfunc_md *md, struct bpf_prog *prog, int type,
+		      u64 cookie)
+{
+	struct kfunc_md_tramp_prog *tramp_prog, **last;
+
+	tramp_prog = md->bpf_progs[type];
+	/* check if the prog is already linked */
+	while (tramp_prog) {
+		if (tramp_prog->prog == prog)
+			return -EEXIST;
+		tramp_prog = tramp_prog->next;
+	}
+
+	tramp_prog = kmalloc(sizeof(*tramp_prog), GFP_KERNEL);
+	if (!tramp_prog)
+		return -ENOMEM;
+
+	tramp_prog->prog = prog;
+	tramp_prog->cookie = cookie;
+	tramp_prog->next = NULL;
+
+	/* add the new prog to the list tail */
+	last = &md->bpf_progs[type];
+	while (*last)
+		last = &(*last)->next;
+	*last = tramp_prog;
+
+	md->bpf_prog_cnt++;
+	if (type == BPF_TRAMP_FEXIT || type == BPF_TRAMP_MODIFY_RETURN)
+		md->flags |= KFUNC_MD_FL_TRACING_ORIGIN;
+
+	return 0;
+}
+
+int kfunc_md_bpf_unlink(struct kfunc_md *md, struct bpf_prog *prog, int type)
+{
+	struct kfunc_md_tramp_prog *cur, **prev;
+
+	prev = &md->bpf_progs[type];
+	while (*prev && (*prev)->prog != prog)
+		prev = &(*prev)->next;
+
+	cur = *prev;
+	if (!cur)
+		return -EINVAL;
+
+	*prev = cur->next;
+	kfree_rcu(cur, rcu);
+	md->bpf_prog_cnt--;
+
+	if (!md->bpf_progs[BPF_TRAMP_FEXIT] &&
+	    !md->bpf_progs[BPF_TRAMP_MODIFY_RETURN])
+		md->flags &= ~KFUNC_MD_FL_TRACING_ORIGIN;
+
+	return 0;
+}
+
 bool __weak kfunc_md_arch_support(int *insn, int *data)
 {
 	return false;
-- 
2.39.5


  parent reply	other threads:[~2025-05-28  3:49 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-28  3:46 [PATCH bpf-next 00/25] bpf: tracing multi-link support Menglong Dong
2025-05-28  3:46 ` [PATCH bpf-next 01/25] add per-function metadata storage support Menglong Dong
2025-05-28  3:46 ` [PATCH bpf-next 02/25] x86: implement per-function metadata storage for x86 Menglong Dong
2025-05-28  3:46 ` [PATCH bpf-next 03/25] arm64: implement per-function metadata storage for arm64 Menglong Dong
2025-05-28 12:16   ` kernel test robot
2025-05-28  3:46 ` Menglong Dong [this message]
2025-05-28  3:46 ` [PATCH bpf-next 05/25] x86,bpf: add bpf_global_caller for global trampoline Menglong Dong
2025-05-28  3:46 ` [PATCH bpf-next 06/25] ftrace: factor out ftrace_direct_update from register_ftrace_direct Menglong Dong
2025-05-28  3:46 ` [PATCH bpf-next 07/25] ftrace: add reset_ftrace_direct_ips Menglong Dong
2025-05-28  3:46 ` [PATCH bpf-next 08/25] bpf: introduce bpf_gtramp_link Menglong Dong
2025-05-28  3:46 ` [PATCH bpf-next 09/25] bpf: tracing: add support to record and check the accessed args Menglong Dong
2025-05-28  3:46 ` [PATCH bpf-next 10/25] bpf: refactor the modules_array to ptr_array Menglong Dong
2025-05-28  3:46 ` [PATCH bpf-next 11/25] bpf: verifier: add btf to the function args of bpf_check_attach_target Menglong Dong
2025-05-28  3:46 ` [PATCH bpf-next 12/25] bpf: verifier: move btf_id_deny to bpf_check_attach_target Menglong Dong
2025-05-28  3:47 ` [PATCH bpf-next 13/25] x86,bpf: factor out __arch_get_bpf_regs_nr Menglong Dong
2025-05-28  3:47 ` [PATCH bpf-next 14/25] bpf: tracing: add multi-link support Menglong Dong
2025-05-28 11:34   ` kernel test robot
2025-05-28  3:47 ` [PATCH bpf-next 15/25] ftrace: factor out __unregister_ftrace_direct Menglong Dong
2025-05-28 12:37   ` kernel test robot
2025-05-28  3:47 ` [PATCH bpf-next 16/25] ftrace: supporting replace direct ftrace_ops Menglong Dong
2025-05-28  3:47 ` [PATCH bpf-next 17/25] bpf: make trampoline compatible with global trampoline Menglong Dong
2025-05-28  3:47 ` [PATCH bpf-next 18/25] libbpf: don't free btf if tracing_multi progs existing Menglong Dong
2025-05-28  3:47 ` [PATCH bpf-next 19/25] libbpf: support tracing_multi Menglong Dong
2025-05-28  3:47 ` [PATCH bpf-next 20/25] libbpf: add btf type hash lookup support Menglong Dong
2025-05-28  3:47 ` [PATCH bpf-next 21/25] libbpf: add skip_invalid and attach_tracing for tracing_multi Menglong Dong
2025-05-28  3:47 ` [PATCH bpf-next 22/25] selftests/bpf: use the glob_match() from libbpf in test_progs.c Menglong Dong
2025-05-28  3:47 ` [PATCH bpf-next 23/25] selftests/bpf: add get_ksyms and get_addrs to test_progs.c Menglong Dong
2025-05-28  3:47 ` [PATCH bpf-next 24/25] selftests/bpf: add testcases for multi-link of tracing Menglong Dong
2025-05-28  3:47 ` [PATCH bpf-next 25/25] selftests/bpf: add performance bench test for trace prog Menglong Dong
2025-05-28 13:51 ` [PATCH bpf-next 00/25] bpf: tracing multi-link support Steven Rostedt
2025-05-29  1:44   ` Menglong Dong
2025-06-11  3:32 ` Alexei Starovoitov
2025-06-11 12:58   ` Menglong Dong
2025-06-11 16:11     ` Alexei Starovoitov
2025-06-12  0:07       ` Menglong Dong
2025-06-12  0:58         ` Alexei Starovoitov
2025-06-12  3:18           ` Menglong Dong
2025-06-15  8:35           ` Menglong Dong

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=20250528034712.138701-5-dongml2@chinatelecom.cn \
    --to=menglong8.dong@gmail.com \
    --cc=alexei.starovoitov@gmail.com \
    --cc=bpf@vger.kernel.org \
    --cc=dongml2@chinatelecom.cn \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rostedt@goodmis.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;
as well as URLs for NNTP newsgroup(s).