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
next prev 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).