[PATCH 5/6] tools/sched_ext/include: Add libbpf version guard for assoc_struct_ops
From: Tejun Heo
Date: Sat Mar 07 2026 - 21:46:59 EST
Extract the inline bpf_program__assoc_struct_ops() call in SCX_OPS_LOAD()
into a __scx_ops_assoc_prog() helper and wrap it with a libbpf >= 1.7
version guard. bpf_program__assoc_struct_ops() was added in libbpf 1.7;
the guard provides a no-op fallback for older versions. Add the
<bpf/libbpf.h> include needed by the helper, and fix "assumming" typo in
a nearby comment.
Signed-off-by: Tejun Heo <tj@xxxxxxxxxx>
---
tools/sched_ext/include/scx/compat.h | 35 +++++++++++++++++++++++-----
1 file changed, 29 insertions(+), 6 deletions(-)
diff --git a/tools/sched_ext/include/scx/compat.h b/tools/sched_ext/include/scx/compat.h
index 9b6df13b187b..50297d4b9533 100644
--- a/tools/sched_ext/include/scx/compat.h
+++ b/tools/sched_ext/include/scx/compat.h
@@ -8,6 +8,7 @@
#define __SCX_COMPAT_H
#include <bpf/btf.h>
+#include <bpf/libbpf.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
@@ -182,6 +183,31 @@ static inline long scx_hotplug_seq(void)
__skel; \
})
+/*
+ * Associate non-struct_ops BPF programs with the scheduler's struct_ops map so
+ * that scx_prog_sched() can determine which scheduler a BPF program belongs
+ * to. Requires libbpf >= 1.7.
+ */
+#if LIBBPF_MAJOR_VERSION > 1 || \
+ (LIBBPF_MAJOR_VERSION == 1 && LIBBPF_MINOR_VERSION >= 7)
+static inline void __scx_ops_assoc_prog(struct bpf_program *prog,
+ struct bpf_map *map,
+ const char *ops_name)
+{
+ s32 err = bpf_program__assoc_struct_ops(prog, map, NULL);
+ if (err)
+ fprintf(stderr,
+ "ERROR: Failed to associate %s with %s: %d\n",
+ bpf_program__name(prog), ops_name, err);
+}
+#else
+static inline void __scx_ops_assoc_prog(struct bpf_program *prog,
+ struct bpf_map *map,
+ const char *ops_name)
+{
+}
+#endif
+
#define SCX_OPS_LOAD(__skel, __ops_name, __scx_name, __uei_name) ({ \
struct bpf_program *__prog; \
UEI_SET_SIZE(__skel, __ops_name, __uei_name); \
@@ -189,18 +215,15 @@ static inline long scx_hotplug_seq(void)
bpf_object__for_each_program(__prog, (__skel)->obj) { \
if (bpf_program__type(__prog) == BPF_PROG_TYPE_STRUCT_OPS) \
continue; \
- s32 err = bpf_program__assoc_struct_ops(__prog, \
- (__skel)->maps.__ops_name, NULL); \
- if (err) \
- fprintf(stderr, "ERROR: Failed to associate %s with %s: %d\n", \
- bpf_program__name(__prog), #__ops_name, err); \
+ __scx_ops_assoc_prog(__prog, (__skel)->maps.__ops_name, \
+ #__ops_name); \
} \
})
/*
* New versions of bpftool now emit additional link placeholders for BPF maps,
* and set up BPF skeleton in such a way that libbpf will auto-attach BPF maps
- * automatically, assumming libbpf is recent enough (v1.5+). Old libbpf will do
+ * automatically, assuming libbpf is recent enough (v1.5+). Old libbpf will do
* nothing with those links and won't attempt to auto-attach maps.
*
* To maintain compatibility with older libbpf while avoiding trying to attach
--
2.53.0