On Wed, Jun 16, 2021 at 7:19 PM Jonathan Edwards <jonathan.edwards@xxxxxxxxxxxxxxxxxxxxx> wrote: > > eBPF has been backported for RHEL 7 w/ kernel 3.10-940+ (https://www.redhat.com/en/blog/introduction-ebpf-red-hat-enterprise-linux-7). > > However only the following program types are supported (https://access.redhat.com/articles/3550581) > > BPF_PROG_TYPE_KPROBE > BPF_PROG_TYPE_TRACEPOINT > BPF_PROG_TYPE_PERF_EVENT > > Source is here: https://access.redhat.com/labs/rhcb/RHEL-7.9/kernel-3.10.0-1160.25.1.el7/sources/raw/kernel/bpf/syscall.c#_code.1177 > > For libbpf 0.4.0 (db9614b6bd69746809d506c2786f914b0f812c37) this causes an EINVAL return during the bpf_object__probe_loading call which only checks to see if programs of type BPF_PROG_TYPE_SOCKET_FILTER can load as a test. > > Quick discussion with anakryiko (https://github.com/libbpf/libbpf/issues/320) indicated a preference for trying to load multiple program types before failing (e.g SOCKET_FILTER, then KPROBE). On older kernels KPROBE requires attr.kern_version == LINUX_VERSION_CODE, which may not always be available (out of tree builds). TRACEPOINT will work without needing to know the version. We can use multiple tests. > > The following suggestion will try multiple program types and return successfully if one passes. TRACEPOINT works for the ebpf backport for RHEL 7, KPROBE on newer kernels (e.g 5+) > So few high-level points about formatting the patch itself: - please use [PATCH bpf-next] subject prefix when submitting patches against bpf-next tree; - please wrap all the lines at 80 and please look through general kernel patch submission guidelines ([0]) - note how I didn't include URL directly and used [0] (and [1], [2], etc, if necessary). Please do the same, that keeps text more readable and shorter. [0] https://www.kernel.org/doc/html/latest/process/submitting-patches.html > --- > src/libbpf.c | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/src/libbpf.c b/src/libbpf.c > index 5e13c9d..c33acf1 100644 > --- a/src/libbpf.c > +++ b/src/libbpf.c > @@ -4002,6 +4002,12 @@ bpf_object__probe_loading(struct bpf_object *obj) > attr.license = "GPL"; > > ret = bpf_load_program_xattr(&attr, NULL, 0); > + > + attr.prog_type = BPF_PROG_TYPE_KPROBE; > + ret = (ret < 0) ? bpf_load_program_xattr(&attr, NULL, 0) : ret; > + attr.prog_type = BPF_PROG_TYPE_TRACEPOINT; > + ret = (ret < 0) ? bpf_load_program_xattr(&attr, NULL, 0) : ret; As for this logic, I think let's drop KPROBE altogether. Ubuntu has problems with LINUX_VERSION_CODE. Let's try SOCKET_FILTER and fallback to TRACEPOINT before giving up. Very old upstream kernels allow SOCKET_FILTER, so that is covered. And then backported RHEL will know about TRACEPOINT. That should be good enough. Also, explicit if in this case is more appropriate: if (ret < 0) { attr.prog_type = BPF_PROG_TYPE_TRACEPOINT; ret = bpf_load_program_xattr(...); } if (ret < 0) { /* warn and error out */ } > + > if (ret < 0) { > ret = errno; > cp = libbpf_strerror_r(ret, errmsg, sizeof(errmsg)); > -- > 2.17.1