Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

link: implement kprobe.multi link #716

Merged
merged 4 commits into from Sep 15, 2022
Merged

link: implement kprobe.multi link #716

merged 4 commits into from Sep 15, 2022

Conversation

mmat11
Copy link
Collaborator

@mmat11 mmat11 commented Jun 16, 2022

Leaving as draft until CI supports 5.18.
Also, support for pattern matching and addresses array (which libbpf already supports) is to be evaluated

Edit: I've added support for addresses array, I left "pattern matching" out for now since it's not part of the link_create API

@lmb
Copy link
Collaborator

lmb commented Jun 24, 2022

Do you have a link to the corresponding upstream patch set?

Should we support transparent multi attach, with a fallback for old kernels instead of a separate multi attach API? How does libbpf expose this?

@mmat11
Copy link
Collaborator Author

mmat11 commented Jun 24, 2022

Do you have a link to the corresponding upstream patch set?

https://patchwork.kernel.org/project/netdevbpf/list/?series=623878&state=*

I think there are also some bugfixes which are not part of that set

Should we support transparent multi attach, with a fallback for old kernels instead of a separate multi attach API? How does libbpf expose this?

From what I can see, libbpf doesn't do fallback; I think it doesn't make much sense as the underlying API is different from the one of classic kprobes

p.s. I think we need to enable CONFIG_FPROBE=y in ci-kernels (libbpf/libbpf@c84815e), I can recompile them once #668 is merged

@ti-mo
Copy link
Collaborator

ti-mo commented Jun 28, 2022

Thanks for picking this up! (cc @olsajiri)

Should we support transparent multi attach, with a fallback for old kernels instead of a separate multi attach API?

I've been mulling this over for a while, was thinking the same. There's no straightforward way to make K(ret)probe() variadic since symbol is the first arg. This kind of addition justifies breaking API in my book. KprobeOptions and KprobeMultiOptions are too similar to be separate IMO.

What about unifying them and something like func Kprobe(prog *ebpf.Program, opts *KprobeOptions, symbols ...string) (Link, error)? Also parsing strings for symbols vs. addresses.

@lmb
Copy link
Collaborator

lmb commented Jul 5, 2022

The following make transparent fallback difficult:

https://patchwork.kernel.org/project/netdevbpf/patch/20220316122419.933957-4-jolsa@kernel.org/

The fprobe API allows to attach probe on multiple functions at once
very fast, because it works on top of ftrace. On the other hand this
limits the probe point to the function entry or return.

This is incompatible with KprobeOptions.Offset. Possible to work around by returning an error I guess.

https://patchwork.kernel.org/project/netdevbpf/patch/20220316122419.933957-10-jolsa@kernel.org/

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 1ca520a29fdb..f3a31478e23b 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c 
@@ -8621,6 +8622,8 @@  static const struct bpf_sec_def section_defs[] = {
 	SEC_DEF("uprobe/",		KPROBE,	0, SEC_NONE),
 	SEC_DEF("kretprobe/",		KPROBE, 0, SEC_NONE, attach_kprobe),
 	SEC_DEF("uretprobe/",		KPROBE, 0, SEC_NONE),
+	SEC_DEF("kprobe.multi/",	KPROBE,	BPF_TRACE_KPROBE_MULTI, SEC_NONE, attach_kprobe_multi),
+	SEC_DEF("kretprobe.multi/",	KPROBE,	BPF_TRACE_KPROBE_MULTI, SEC_NONE, attach_kprobe_multi),
 	SEC_DEF("tc",			SCHED_CLS, 0, SEC_NONE),
 	SEC_DEF("classifier",		SCHED_CLS, 0, SEC_NONE | SEC_SLOPPY_PFX | SEC_DEPRECATED),
 	SEC_DEF("action",		SCHED_ACT, 0, SEC_NONE | SEC_SLOPPY_PFX),

Multi kprobes have a distinct expected_attach_type. This significantly reduces the likelihood / usefulness of a fallback, since you can't just take a regular kprobe and attach it to to multiple functions.

@olsajiri
Copy link
Contributor

olsajiri commented Jul 6, 2022

not sure fallback is possible.. attaching all symbols by separate kprobe, but that would be real slow, I'd just return error

it's looks good, I'm out this week, but next week I'll try to rebase my multi_kprobe tetragon code on top of this and test, thanks

@olsajiri
Copy link
Contributor

I made first draft in here cilium/tetragon@ebccee5 and I'm able to use the interface in tetragon, there are many loose ends I need to take care of, but the interface is fine for tetragon for now ;-) thanks

@mmat11 mmat11 force-pushed the matt/multikp branch 4 times, most recently from 9e00e33 to 2a39fd8 Compare July 20, 2022 15:29
@mmat11 mmat11 marked this pull request as ready for review July 20, 2022 15:32
@olsajiri
Copy link
Contributor

@mmat11 @ti-mo is there easy way to use the multi kprobe detection check from user code?

@mmat11
Copy link
Collaborator Author

mmat11 commented Aug 13, 2022

@mmat11 @ti-mo is there easy way to use the multi kprobe detection check from user code?

I could expose HaveKprobeMultiLink in the features package

@olsajiri
Copy link
Contributor

@mmat11 @ti-mo is there easy way to use the multi kprobe detection check from user code?

I could expose HaveKprobeMultiLink in the features package

that would work for me, thanks

@ti-mo
Copy link
Collaborator

ti-mo commented Aug 14, 2022

@mmat11 @ti-mo is there easy way to use the multi kprobe detection check from user code?

I could expose HaveKprobeMultiLink in the features package

that would work for me, thanks

Before we do that, could you give an example of how that would be used and why? (as opposed to just trying the multi-attach and falling back to perf attach when it fails?)

Probably better to make the multi attach itself return ErrNotSupported instead of adding arbitrary feature probes. Ask for forgiveness, not permission etc.

@olsajiri
Copy link
Contributor

olsajiri commented Aug 14, 2022

we are going to use kprobe_multi link instead of standard kprobe,
when there's support detected, like in cilium/tetragon@1065b26 :

	// use multi kprobe only if there's support and multiple kprobes defined
	useMulti = bpf.HasKprobeMulti() && len(kprobes) > 1

I'd call HaveKprobeMultiLink instead of HasKprobeMulti

@olsajiri
Copy link
Contributor

olsajiri commented Aug 14, 2022

Probably better to make the multi attach itself return ErrNotSupported instead of adding arbitrary feature probes. Ask for forgiveness, not permission etc.

there's lot of different configuration code for standard and multi kprobes,
and the link attachment comes as last, so I'd like to know before all that

@mmat11 mmat11 force-pushed the matt/multikp branch 2 times, most recently from 0ee4bc5 to 3e3109e Compare August 30, 2022 08:51
internal/cmd/gentypes/main.go Outdated Show resolved Hide resolved
Copy link
Collaborator

@ti-mo ti-mo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed offline, leaving this review to highlight the main points I'd liked to see differently while hacking on this code. Mostly cleaned up the middle part of kprobeMulti and moved all input validation to the top. Will push my changes shortly.

link/kprobe_multi.go Outdated Show resolved Hide resolved
link/kprobe_multi.go Outdated Show resolved Hide resolved
link/kprobe_multi.go Outdated Show resolved Hide resolved
link/kprobe_multi.go Outdated Show resolved Hide resolved
link/kprobe_multi.go Outdated Show resolved Hide resolved
link/kprobe_multi.go Outdated Show resolved Hide resolved
link/kprobe_multi.go Outdated Show resolved Hide resolved
link/kprobe_multi_test.go Outdated Show resolved Hide resolved
link/kprobe_multi_test.go Outdated Show resolved Hide resolved
link/link.go Outdated Show resolved Hide resolved
@mmat11
Copy link
Collaborator Author

mmat11 commented Sep 6, 2022

As discussed offline, leaving this review to highlight the main points I'd liked to see differently while hacking on this code. Mostly cleaned up the middle part of kprobeMulti and moved all input validation to the top. Will push my changes shortly.

Thanks, looks better!

@lmb lmb force-pushed the matt/multikp branch 2 times, most recently from 1894450 to 586b751 Compare September 15, 2022 11:14
var _ Link = (*kprobeMultiLink)(nil)

func (kml *kprobeMultiLink) Update(prog *ebpf.Program) error {
return fmt.Errorf("update kprobe_multi: %w", ErrNotSupported)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoding ErrNotSupported here for each link type really sucks, we should change the kernel to return a sensible errno.

link/kprobe_multi.go Outdated Show resolved Hide resolved
}
defer prog.Close()

fd, err := sys.LinkCreateKprobeMulti(&sys.LinkCreateKprobeMultiAttr{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it enough to check that AttachTraceKprobeMulti is accepted by the kernel?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like it's accepted even when not supported

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh boy...

link/kprobe_multi_test.go Outdated Show resolved Hide resolved
ProgFd uint32
TargetFd uint32
AttachType AttachType
Flags uint32
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joamaki somewhat OT, but why does kprobe_multi not use the existing flags field?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lmb I think you mean @olsajiri 😉

ti-mo and others added 3 commits September 15, 2022 13:41
Signed-off-by: Timo Beckers <timo@isovalent.com>
Having both a switch statement to initialize the metadata struct pointer
as well as a list of link types was a bit redundant.

Signed-off-by: Timo Beckers <timo@isovalent.com>
Co-authored-by: Lorenz Bauer <i@lmb.io>
@mmat11 mmat11 force-pushed the matt/multikp branch 2 times, most recently from b7b10a6 to 9208bf5 Compare September 15, 2022 11:55
As of Linux 5.18, or commit 5a5c11ee3e65 ("Merge branch 'bpf: Add kprobe
multi link'"), attaching multiple k(ret)probes using a single system call
is now possible.

This commit adds support for this through the KprobeMulti() and
KretprobeMulti() APIs in package link.

Co-authored-by: Timo Beckers <timo@isovalent.com>
Copy link
Collaborator

@ti-mo ti-mo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@ti-mo ti-mo merged commit aaa9af2 into cilium:master Sep 15, 2022
@mmat11 mmat11 deleted the matt/multikp branch November 1, 2022 15:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants