[PATCH 2/2] compat.bpf.h: add scx_bpf_reenqueue_local_from_anywhere() compat helper
Changwoo Min <[email protected]>
| Newsgroups | dev.linux.lists.sched-ext,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
scx_bpf_reenqueue_local()'s generic compat wrapper inlines a v1 fallback that is only callable from ops.cpu_release, and veristat rejects it on kernels without v2. Callers draining a local DSQ from an arbitrary context (e.g. a tracepoint) must gate on a call-from-anywhere kfunc directly. Add scx_bpf_reenqueue_local_from_anywhere() to compat.bpf.h to encapsulate that: call a call-from-anywhere kfunc when present and return 0, else return -ENOTSUP so the caller knows the drain did not run. Two kfuncs qualify -- the v7.1 generic scx_bpf_dsq_reenq(), which will eventually deprecate scx_bpf_reenqueue_local(), and the v6.19 v2 reenqueue-local variant. Prefer the generic one; v1 cannot be called from anywhere, so it maps to -ENOTSUP. scx_bpf_reenqueue_local() itself grows the same generic-first preference, and the scx_bpf_dsq_reenq___compat declaration and __COMPAT_has_generic_reenq() helper move above the v6.19 block so both wrappers can use them. Test each ksym in its own branch: ORing two bpf_ksym_exists() checks folds into a bitwise OR of the two weak ksym addresses, which the verifier rejects. No functional change intended. Suggested-by: Andrea Righi <[email protected]> Signed-off-by: Changwoo Min <[email protected]> Signed-off-by: Tejun Heo <[email protected]> --- tools/sched_ext/include/scx/compat.bpf.h | 39 ++++++++++++++++++------ 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/tools/sched_ext/include/scx/compat.bpf.h b/tools/sched_ext/include/scx/compat.bpf.h index 03976f5851d9..55f118e40545 100644 --- a/tools/sched_ext/include/scx/compat.bpf.h +++ b/tools/sched_ext/include/scx/compat.bpf.h @@ -383,6 +383,17 @@ static inline void scx_bpf_task_set_dsq_vtime(struct task_struct *p, u64 vtime) p->scx.dsq_vtime = vtime; } +/* + * v7.1: New scx_bpf_dsq_reenq() that allows re-enqueues on more DSQs. This + * will eventually deprecate scx_bpf_reenqueue_local(). + */ +void scx_bpf_dsq_reenq___compat(u64 dsq_id, u64 reenq_flags) __ksym __weak; + +static inline bool __COMPAT_has_generic_reenq(void) +{ + return bpf_ksym_exists(scx_bpf_dsq_reenq___compat); +} + /* * v6.19: The new void variant can be called from anywhere while the older v1 * variant can only be called from ops.cpu_release(). The double ___ prefixes on @@ -400,21 +411,31 @@ static inline bool __COMPAT_scx_bpf_reenqueue_local_from_anywhere(void) static inline void scx_bpf_reenqueue_local(void) { - if (__COMPAT_scx_bpf_reenqueue_local_from_anywhere()) + if (__COMPAT_has_generic_reenq()) + scx_bpf_dsq_reenq___compat(SCX_DSQ_LOCAL, 0); + else if (__COMPAT_scx_bpf_reenqueue_local_from_anywhere()) scx_bpf_reenqueue_local___v2___compat(); else scx_bpf_reenqueue_local___v1(); } -/* - * v7.1: New scx_bpf_dsq_reenq() that allows re-enqueues on more DSQs. This - * will eventually deprecate scx_bpf_reenqueue_local(). - */ -void scx_bpf_dsq_reenq___compat(u64 dsq_id, u64 reenq_flags) __ksym __weak; - -static inline bool __COMPAT_has_generic_reenq(void) +static inline int scx_bpf_reenqueue_local_from_anywhere(void) { - return bpf_ksym_exists(scx_bpf_dsq_reenq___compat); + /* + * The generic reenq kfunc and the v2 reenqueue-local variant can both be + * called from anywhere; v1 cannot. Test each ksym in its own branch with a + * distinct call: combining them with || would fold into a bitwise OR of the + * two ksym addresses, which the verifier rejects. + */ + if (__COMPAT_has_generic_reenq()) { + scx_bpf_dsq_reenq___compat(SCX_DSQ_LOCAL, 0); + return 0; + } + if (__COMPAT_scx_bpf_reenqueue_local_from_anywhere()) { + scx_bpf_reenqueue_local___v2___compat(); + return 0; + } + return -ENOTSUP; } static inline void scx_bpf_dsq_reenq(u64 dsq_id, u64 reenq_flags) -- 2.55.0