[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.