[PATCH 1/2] compat.bpf.h: Gate scx_bpf_dsq_peek kfunc behind kernel version 7.1.0

Changwoo Min <[email protected]>
Newsgroups dev.linux.lists.sched-ext,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
From: Gavin Guo <[email protected]>

__COMPAT_scx_bpf_dsq_peek() selects the lockless kfunc whenever the
symbol resolves in the kernel BTF. However, its lockless implementation
could return a stale task_struct pointer. The stale pointer issues are
resolved only after v7.1 kernel with the following patches:

commit 2f2ea7709266 ("sched_ext: Use dsq->first_task instead of list_empty() in dispatch_enqueue() FIFO-tail")
commit 71d7847cad44 ("sched_ext: Fix scx_bpf_dsq_peek() with FIFO DSQs")

Require bpf_ksym_exists(scx_bpf_dsq_peek) AND LINUX_KERNEL_VERSION >=
KERNEL_VERSION(7, 1, 0) before calling the kfunc to mitigate the issue;
otherwise fall through to the existing bpf_iter_scx_dsq path instead.

See also the lavd patch, working around the bug by avoiding calling
the kfunc when unnecessary and having more context explanation:
ac863374ce4f ("scx_lavd: Gate dsq_peek_task_load behind no-fast-lb")

Signed-off-by: Gavin Guo <[email protected]>
Signed-off-by: Changwoo Min <[email protected]>
---
 tools/sched_ext/include/scx/compat.bpf.h | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/tools/sched_ext/include/scx/compat.bpf.h b/tools/sched_ext/include/scx/compat.bpf.h
index 3ab642f92c8a..03976f5851d9 100644
--- a/tools/sched_ext/include/scx/compat.bpf.h
+++ b/tools/sched_ext/include/scx/compat.bpf.h
@@ -92,15 +92,20 @@ int bpf_cpumask_populate(struct bpf_cpumask *dst, void *src, size_t src__sz) __k
 
 /*
  * v6.19: Introduce lockless peek API for user DSQs.
+ * v7.1:  Resolve the stale pointer issue of the lockless peek API.
+ *
+ * The kfunc exists on earlier kernels but its lockless implementation could
+ * return stale task pointers. Require kernel version >= 7.1.0 before calling
+ * it; otherwise fall through to the bpf_iter_scx_dsq fallback below.
  *
- * Preserve the following macro until v6.21.
  */
 static inline struct task_struct *__COMPAT_scx_bpf_dsq_peek(u64 dsq_id)
 {
 	struct task_struct *p = NULL;
 	struct bpf_iter_scx_dsq it;
 
-	if (bpf_ksym_exists(scx_bpf_dsq_peek))
+	if (bpf_ksym_exists(scx_bpf_dsq_peek) &&
+	    LINUX_KERNEL_VERSION >= KERNEL_VERSION(7, 1, 0))
 		return scx_bpf_dsq_peek(dsq_id);
 	if (!bpf_iter_scx_dsq_new(&it, dsq_id, 0))
 		p = bpf_iter_scx_dsq_next(&it);
-- 
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.