Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

sched_ext/tools: Restore backward compat with v6.12 kernels

Commit 111a79800aed ("tools/sched_ext: Strip compatibility macros for
cgroup and dispatch APIs") removed the compat layer for v6.12-v6.13 kfunc
renaming, but v6.12 is the current LTS kernel and will remain supported
through 2026. Restore backward compatibility so schedulers built with v6.19+
headers can run on v6.12 kernels.

The restored compat differs from the original in two ways:

1. Uses ___new/___old suffixes instead of ___compat for clarity. The new
macros check for v6.13+ names (scx_bpf_dsq_move*), fall back to v6.12
names (scx_bpf_dispatch_from_dsq*, scx_bpf_consume), then return safe
no-ops for missing symbols.

2. Integrates with the args-struct-packing changes added in c0d630ba347c
("sched_ext: Wrap kfunc args in struct to prepare for aux__prog").
scx_bpf_dsq_insert_vtime() now tries __scx_bpf_dsq_insert_vtime (args
struct), then scx_bpf_dsq_insert_vtime___compat (v6.13-v6.18), then
scx_bpf_dispatch_vtime___compat (pre-v6.13).

Forward compatibility is not restored - binaries built against v6.13 or
earlier headers won't run on v6.19+ kernels, as the old kfunc names are not
exported. This is acceptable since the priority is new binaries running on
older kernels.

Also add missing compat checks for ops.cgroup_set_bandwidth() (added v6.17)
and ops.cgroup_set_idle() (added v6.19). These need to be NULLed out in
userspace on older kernels.

Reported-by: Andrea Righi <arighi@nvidia.com>
Acked-and-tested-by: Andrea Righi <arighi@nvidia.com>
Signed-off-by: Tejun Heo <tj@kernel.org>

Tejun Heo 34423456 a3f5d482

+90 -8
-6
tools/sched_ext/include/scx/common.bpf.h
··· 65 65 bool __scx_bpf_dsq_insert_vtime(struct task_struct *p, struct scx_bpf_dsq_insert_vtime_args *args) __ksym __weak; 66 66 u32 scx_bpf_dispatch_nr_slots(void) __ksym; 67 67 void scx_bpf_dispatch_cancel(void) __ksym; 68 - bool scx_bpf_dsq_move_to_local(u64 dsq_id) __ksym __weak; 69 - void scx_bpf_dsq_move_set_slice(struct bpf_iter_scx_dsq *it__iter, u64 slice) __ksym __weak; 70 - void scx_bpf_dsq_move_set_vtime(struct bpf_iter_scx_dsq *it__iter, u64 vtime) __ksym __weak; 71 - bool scx_bpf_dsq_move(struct bpf_iter_scx_dsq *it__iter, struct task_struct *p, u64 dsq_id, u64 enq_flags) __ksym __weak; 72 - bool scx_bpf_dsq_move_vtime(struct bpf_iter_scx_dsq *it__iter, struct task_struct *p, u64 dsq_id, u64 enq_flags) __ksym __weak; 73 68 void scx_bpf_kick_cpu(s32 cpu, u64 flags) __ksym; 74 69 s32 scx_bpf_dsq_nr_queued(u64 dsq_id) __ksym; 75 70 void scx_bpf_destroy_dsq(u64 dsq_id) __ksym; ··· 99 104 struct rq *scx_bpf_cpu_rq(s32 cpu) __ksym; 100 105 struct rq *scx_bpf_locked_rq(void) __ksym; 101 106 struct task_struct *scx_bpf_cpu_curr(s32 cpu) __ksym __weak; 102 - struct cgroup *scx_bpf_task_cgroup(struct task_struct *p) __ksym __weak; 103 107 u64 scx_bpf_now(void) __ksym __weak; 104 108 void scx_bpf_events(struct scx_event_stats *events, size_t events__sz) __ksym __weak; 105 109
+76 -2
tools/sched_ext/include/scx/compat.bpf.h
··· 15 15 __ret; \ 16 16 }) 17 17 18 + /* v6.12: 819513666966 ("sched_ext: Add cgroup support") */ 19 + struct cgroup *scx_bpf_task_cgroup___new(struct task_struct *p) __ksym __weak; 20 + 21 + #define scx_bpf_task_cgroup(p) \ 22 + (bpf_ksym_exists(scx_bpf_task_cgroup___new) ? \ 23 + scx_bpf_task_cgroup___new((p)) : NULL) 24 + 25 + /* 26 + * v6.13: The verb `dispatch` was too overloaded and confusing. kfuncs are 27 + * renamed to unload the verb. 28 + * 29 + * scx_bpf_dispatch_from_dsq() and friends were added during v6.12 by 30 + * 4c30f5ce4f7a ("sched_ext: Implement scx_bpf_dispatch[_vtime]_from_dsq()"). 31 + */ 32 + bool scx_bpf_dsq_move_to_local___new(u64 dsq_id) __ksym __weak; 33 + void scx_bpf_dsq_move_set_slice___new(struct bpf_iter_scx_dsq *it__iter, u64 slice) __ksym __weak; 34 + void scx_bpf_dsq_move_set_vtime___new(struct bpf_iter_scx_dsq *it__iter, u64 vtime) __ksym __weak; 35 + bool scx_bpf_dsq_move___new(struct bpf_iter_scx_dsq *it__iter, struct task_struct *p, u64 dsq_id, u64 enq_flags) __ksym __weak; 36 + bool scx_bpf_dsq_move_vtime___new(struct bpf_iter_scx_dsq *it__iter, struct task_struct *p, u64 dsq_id, u64 enq_flags) __ksym __weak; 37 + 38 + bool scx_bpf_consume___old(u64 dsq_id) __ksym __weak; 39 + void scx_bpf_dispatch_from_dsq_set_slice___old(struct bpf_iter_scx_dsq *it__iter, u64 slice) __ksym __weak; 40 + void scx_bpf_dispatch_from_dsq_set_vtime___old(struct bpf_iter_scx_dsq *it__iter, u64 vtime) __ksym __weak; 41 + bool scx_bpf_dispatch_from_dsq___old(struct bpf_iter_scx_dsq *it__iter, struct task_struct *p, u64 dsq_id, u64 enq_flags) __ksym __weak; 42 + bool scx_bpf_dispatch_vtime_from_dsq___old(struct bpf_iter_scx_dsq *it__iter, struct task_struct *p, u64 dsq_id, u64 enq_flags) __ksym __weak; 43 + 44 + #define scx_bpf_dsq_move_to_local(dsq_id) \ 45 + (bpf_ksym_exists(scx_bpf_dsq_move_to_local___new) ? \ 46 + scx_bpf_dsq_move_to_local___new((dsq_id)) : \ 47 + scx_bpf_consume___old((dsq_id))) 48 + 49 + #define scx_bpf_dsq_move_set_slice(it__iter, slice) \ 50 + (bpf_ksym_exists(scx_bpf_dsq_move_set_slice___new) ? \ 51 + scx_bpf_dsq_move_set_slice___new((it__iter), (slice)) : \ 52 + (bpf_ksym_exists(scx_bpf_dispatch_from_dsq_set_slice___old) ? \ 53 + scx_bpf_dispatch_from_dsq_set_slice___old((it__iter), (slice)) : \ 54 + (void)0)) 55 + 56 + #define scx_bpf_dsq_move_set_vtime(it__iter, vtime) \ 57 + (bpf_ksym_exists(scx_bpf_dsq_move_set_vtime___new) ? \ 58 + scx_bpf_dsq_move_set_vtime___new((it__iter), (vtime)) : \ 59 + (bpf_ksym_exists(scx_bpf_dispatch_from_dsq_set_vtime___old) ? \ 60 + scx_bpf_dispatch_from_dsq_set_vtime___old((it__iter), (vtime)) : \ 61 + (void)0)) 62 + 63 + #define scx_bpf_dsq_move(it__iter, p, dsq_id, enq_flags) \ 64 + (bpf_ksym_exists(scx_bpf_dsq_move___new) ? \ 65 + scx_bpf_dsq_move___new((it__iter), (p), (dsq_id), (enq_flags)) : \ 66 + (bpf_ksym_exists(scx_bpf_dispatch_from_dsq___old) ? \ 67 + scx_bpf_dispatch_from_dsq___old((it__iter), (p), (dsq_id), (enq_flags)) : \ 68 + false)) 69 + 70 + #define scx_bpf_dsq_move_vtime(it__iter, p, dsq_id, enq_flags) \ 71 + (bpf_ksym_exists(scx_bpf_dsq_move_vtime___new) ? \ 72 + scx_bpf_dsq_move_vtime___new((it__iter), (p), (dsq_id), (enq_flags)) : \ 73 + (bpf_ksym_exists(scx_bpf_dispatch_vtime_from_dsq___old) ? \ 74 + scx_bpf_dispatch_vtime_from_dsq___old((it__iter), (p), (dsq_id), (enq_flags)) : \ 75 + false)) 76 + 18 77 /* 19 78 * v6.15: 950ad93df2fc ("bpf: add kfunc for populating cpumask bits") 20 79 * ··· 225 166 * replaced with variants that pack scalar arguments in a struct. Wrappers are 226 167 * provided to maintain source compatibility. 227 168 * 169 + * v6.13: scx_bpf_dsq_insert_vtime() renaming is also handled here. See the 170 + * block on dispatch renaming above for more details. 171 + * 228 172 * The kernel will carry the compat variants until v6.23 to maintain binary 229 173 * compatibility. After v6.23 release, remove the compat handling and move the 230 174 * wrappers to common.bpf.h. 231 175 */ 232 176 s32 scx_bpf_select_cpu_and___compat(struct task_struct *p, s32 prev_cpu, u64 wake_flags, 233 177 const struct cpumask *cpus_allowed, u64 flags) __ksym __weak; 178 + void scx_bpf_dispatch_vtime___compat(struct task_struct *p, u64 dsq_id, u64 slice, u64 vtime, u64 enq_flags) __ksym __weak; 234 179 void scx_bpf_dsq_insert_vtime___compat(struct task_struct *p, u64 dsq_id, u64 slice, u64 vtime, u64 enq_flags) __ksym __weak; 235 180 236 181 /** ··· 290 227 }; 291 228 292 229 return __scx_bpf_dsq_insert_vtime(p, &args); 293 - } else { 230 + } else if (bpf_ksym_exists(scx_bpf_dsq_insert_vtime___compat)) { 294 231 scx_bpf_dsq_insert_vtime___compat(p, dsq_id, slice, vtime, 295 232 enq_flags); 233 + return true; 234 + } else { 235 + scx_bpf_dispatch_vtime___compat(p, dsq_id, slice, vtime, 236 + enq_flags); 296 237 return true; 297 238 } 298 239 } ··· 306 239 * scx_bpf_dsq_insert() decl to common.bpf.h and drop compat helper after v6.22. 307 240 * The extra ___compat suffix is to work around libbpf not ignoring __SUFFIX on 308 241 * kernel side. The entire suffix can be dropped later. 242 + * 243 + * v6.13: scx_bpf_dsq_insert() renaming is also handled here. See the block on 244 + * dispatch renaming above for more details. 309 245 */ 310 246 bool scx_bpf_dsq_insert___v2___compat(struct task_struct *p, u64 dsq_id, u64 slice, u64 enq_flags) __ksym __weak; 311 247 void scx_bpf_dsq_insert___v1(struct task_struct *p, u64 dsq_id, u64 slice, u64 enq_flags) __ksym __weak; 248 + void scx_bpf_dispatch___compat(struct task_struct *p, u64 dsq_id, u64 slice, u64 enq_flags) __ksym __weak; 312 249 313 250 static inline bool 314 251 scx_bpf_dsq_insert(struct task_struct *p, u64 dsq_id, u64 slice, u64 enq_flags) 315 252 { 316 253 if (bpf_ksym_exists(scx_bpf_dsq_insert___v2___compat)) { 317 254 return scx_bpf_dsq_insert___v2___compat(p, dsq_id, slice, enq_flags); 318 - } else { 255 + } else if (bpf_ksym_exists(scx_bpf_dsq_insert___v1)) { 319 256 scx_bpf_dsq_insert___v1(p, dsq_id, slice, enq_flags); 257 + return true; 258 + } else { 259 + scx_bpf_dispatch___compat(p, dsq_id, slice, enq_flags); 320 260 return true; 321 261 } 322 262 }
+14
tools/sched_ext/include/scx/compat.h
··· 151 151 * 152 152 * ec7e3b0463e1 ("implement-ops") in https://github.com/sched-ext/sched_ext is 153 153 * the current minimum required kernel version. 154 + * 155 + * COMPAT: 156 + * - v6.17: ops.cgroup_set_bandwidth() 157 + * - v6.19: ops.cgroup_set_idle() 154 158 */ 155 159 #define SCX_OPS_OPEN(__ops_name, __scx_name) ({ \ 156 160 struct __scx_name *__skel; \ ··· 166 162 SCX_BUG_ON(!__skel, "Could not open " #__scx_name); \ 167 163 __skel->struct_ops.__ops_name->hotplug_seq = scx_hotplug_seq(); \ 168 164 SCX_ENUM_INIT(__skel); \ 165 + if (__skel->struct_ops.__ops_name->cgroup_set_bandwidth && \ 166 + !__COMPAT_struct_has_field("sched_ext_ops", "cgroup_set_bandwidth")) { \ 167 + fprintf(stderr, "WARNING: kernel doesn't support ops.cgroup_set_bandwidth()\n"); \ 168 + __skel->struct_ops.__ops_name->cgroup_set_bandwidth = NULL; \ 169 + } \ 170 + if (__skel->struct_ops.__ops_name->cgroup_set_idle && \ 171 + !__COMPAT_struct_has_field("sched_ext_ops", "cgroup_set_idle")) { \ 172 + fprintf(stderr, "WARNING: kernel doesn't support ops.cgroup_set_idle()\n"); \ 173 + __skel->struct_ops.__ops_name->cgroup_set_idle = NULL; \ 174 + } \ 169 175 __skel; \ 170 176 }) 171 177