* [PATCH v2 0/2] sched_ext cleanup and toolchain compatibility fixes
@ 2026-03-09 2:28 Zhao Mengmeng
2026-03-09 2:28 ` [PATCH v2 1/2] sched_ext: remove SCX_OPS_HAS_CGROUP_WEIGHT Zhao Mengmeng
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Zhao Mengmeng @ 2026-03-09 2:28 UTC (permalink / raw)
To: tj, void, arighi, changwoo, nathan, nick.desaulniers+lkml, morbo,
justinstitt, emil
Cc: sched-ext, linux-kernel, bpf, llvm, zhaomengmeng
From: Zhao Mengmeng <zhaomengmeng@kylinos.cn>
This series contains commits rebase on lastest for-next branch:
1. remove SCX_OPS_HAS_CGROUP_WEIGHT, which was documented to
be deleted on 6.18.
2. Make scheduler scx_sdt runnable on older clang version. clang 17 and
18 tested with no verifier rejections.
Zhao Mengmeng (2):
sched_ext: remove SCX_OPS_HAS_CGROUP_WEIGHT
tools/sched_ext: scx_sdt: Fix BPF verifier rejection on older LLVMs
kernel/sched/ext.c | 3 ---
kernel/sched/ext_internal.h | 8 +-------
.../sched_ext/include/scx/enum_defs.autogen.h | 1 -
tools/sched_ext/scx_flatcg.bpf.c | 2 +-
tools/sched_ext/scx_sdt.bpf.c | 20 ++++++++++++++++++-
5 files changed, 21 insertions(+), 13 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 1/2] sched_ext: remove SCX_OPS_HAS_CGROUP_WEIGHT
2026-03-09 2:28 [PATCH v2 0/2] sched_ext cleanup and toolchain compatibility fixes Zhao Mengmeng
@ 2026-03-09 2:28 ` Zhao Mengmeng
2026-03-09 2:28 ` [PATCH v2 2/2] tools/sched_ext: scx_sdt: Fix BPF verifier rejection on older LLVMs Zhao Mengmeng
2026-03-09 19:49 ` [PATCH v2 0/2] sched_ext: cleanup and toolchain compatibility fixes Tejun Heo
2 siblings, 0 replies; 8+ messages in thread
From: Zhao Mengmeng @ 2026-03-09 2:28 UTC (permalink / raw)
To: tj, void, arighi, changwoo, nathan, nick.desaulniers+lkml, morbo,
justinstitt, emil
Cc: sched-ext, linux-kernel, bpf, llvm, zhaomengmeng
From: Zhao Mengmeng <zhaomengmeng@kylinos.cn>
While running scx_flatcg, dmesg prints "SCX_OPS_HAS_CGROUP_WEIGHT is
deprecated and a noop", in code, SCX_OPS_HAS_CGROUP_WEIGHT has been
marked as DEPRECATED, and will be removed on 6.18. Now it's time to do it.
Signed-off-by: Zhao Mengmeng <zhaomengmeng@kylinos.cn>
---
kernel/sched/ext.c | 3 ---
kernel/sched/ext_internal.h | 8 +-------
tools/sched_ext/include/scx/enum_defs.autogen.h | 1 -
tools/sched_ext/scx_flatcg.bpf.c | 2 +-
4 files changed, 2 insertions(+), 12 deletions(-)
diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
index d6d807337013..69bb2e5b1adb 100644
--- a/kernel/sched/ext.c
+++ b/kernel/sched/ext.c
@@ -6282,9 +6282,6 @@ static int validate_ops(struct scx_sched *sch, const struct sched_ext_ops *ops)
return -EINVAL;
}
- if (ops->flags & SCX_OPS_HAS_CGROUP_WEIGHT)
- pr_warn("SCX_OPS_HAS_CGROUP_WEIGHT is deprecated and a noop\n");
-
if (ops->cpu_acquire || ops->cpu_release)
pr_warn("ops->cpu_acquire/release() are deprecated, use sched_switch TP instead\n");
diff --git a/kernel/sched/ext_internal.h b/kernel/sched/ext_internal.h
index f8df73044515..bec4d22890b0 100644
--- a/kernel/sched/ext_internal.h
+++ b/kernel/sched/ext_internal.h
@@ -180,19 +180,13 @@ enum scx_ops_flags {
*/
SCX_OPS_BUILTIN_IDLE_PER_NODE = 1LLU << 6,
- /*
- * CPU cgroup support flags
- */
- SCX_OPS_HAS_CGROUP_WEIGHT = 1LLU << 16, /* DEPRECATED, will be removed on 6.18 */
-
SCX_OPS_ALL_FLAGS = SCX_OPS_KEEP_BUILTIN_IDLE |
SCX_OPS_ENQ_LAST |
SCX_OPS_ENQ_EXITING |
SCX_OPS_ENQ_MIGRATION_DISABLED |
SCX_OPS_ALLOW_QUEUED_WAKEUP |
SCX_OPS_SWITCH_PARTIAL |
- SCX_OPS_BUILTIN_IDLE_PER_NODE |
- SCX_OPS_HAS_CGROUP_WEIGHT,
+ SCX_OPS_BUILTIN_IDLE_PER_NODE,
/* high 8 bits are internal, don't include in SCX_OPS_ALL_FLAGS */
__SCX_OPS_INTERNAL_MASK = 0xffLLU << 56,
diff --git a/tools/sched_ext/include/scx/enum_defs.autogen.h b/tools/sched_ext/include/scx/enum_defs.autogen.h
index 78d34f0c29f0..40b30dad8ede 100644
--- a/tools/sched_ext/include/scx/enum_defs.autogen.h
+++ b/tools/sched_ext/include/scx/enum_defs.autogen.h
@@ -114,7 +114,6 @@
#define HAVE_SCX_OPS_ENQ_MIGRATION_DISABLED
#define HAVE_SCX_OPS_ALLOW_QUEUED_WAKEUP
#define HAVE_SCX_OPS_BUILTIN_IDLE_PER_NODE
-#define HAVE_SCX_OPS_HAS_CGROUP_WEIGHT
#define HAVE_SCX_OPS_ALL_FLAGS
#define HAVE___SCX_OPS_INTERNAL_MASK
#define HAVE_SCX_OPS_HAS_CPU_PREEMPT
diff --git a/tools/sched_ext/scx_flatcg.bpf.c b/tools/sched_ext/scx_flatcg.bpf.c
index 0e785cff0f24..a8a9234bb41e 100644
--- a/tools/sched_ext/scx_flatcg.bpf.c
+++ b/tools/sched_ext/scx_flatcg.bpf.c
@@ -960,5 +960,5 @@ SCX_OPS_DEFINE(flatcg_ops,
.cgroup_move = (void *)fcg_cgroup_move,
.init = (void *)fcg_init,
.exit = (void *)fcg_exit,
- .flags = SCX_OPS_HAS_CGROUP_WEIGHT | SCX_OPS_ENQ_EXITING,
+ .flags = SCX_OPS_ENQ_EXITING,
.name = "flatcg");
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 2/2] tools/sched_ext: scx_sdt: Fix BPF verifier rejection on older LLVMs
2026-03-09 2:28 [PATCH v2 0/2] sched_ext cleanup and toolchain compatibility fixes Zhao Mengmeng
2026-03-09 2:28 ` [PATCH v2 1/2] sched_ext: remove SCX_OPS_HAS_CGROUP_WEIGHT Zhao Mengmeng
@ 2026-03-09 2:28 ` Zhao Mengmeng
2026-03-09 16:36 ` Emil Tsalapatis
2026-03-09 19:49 ` [PATCH v2 0/2] sched_ext: cleanup and toolchain compatibility fixes Tejun Heo
2 siblings, 1 reply; 8+ messages in thread
From: Zhao Mengmeng @ 2026-03-09 2:28 UTC (permalink / raw)
To: tj, void, arighi, changwoo, nathan, nick.desaulniers+lkml, morbo,
justinstitt, emil
Cc: sched-ext, linux-kernel, bpf, llvm, zhaomengmeng
From: Zhao Mengmeng <zhaomengmeng@kylinos.cn>
Under Clang 17/18, when running scx_sdt scheduler, it fails with:
libbpf: prog 'sdt_init_task': BPF program load failed: -EACCES
libbpf: prog 'sdt_init_task': -- BEGIN PROG LOAD LOG --
...
; desc = desc_find_empty(alloc->root, &idx); @ scx_sdt.bpf.c:479
43: (79) r8 = *(u64 *)(r6 +32) ; frame1: R6=map_value(map=scx_sdt.bss,ks=4,vs=200,off=120) R8=scalar()
; for (level = zero; level < SDT_TASK_LEVELS && can_loop; level++) { @ scx_sdt.bpf.c:407
44: (e5) may_goto pc+51
; idx |= pos; @ scx_sdt.bpf.c:418
96: (bf) r7 = r2 ; frame1: R2=0 R7=0
97: (bf) r1 = r10 ; frame1: R1=fp0 R10=fp0
; @ scx_sdt.bpf.c:0
98: (07) r1 += -56 ; frame1: R1=fp-56
; bpf_for(u, 0, SDT_TASK_LEVELS) { @ scx_sdt.bpf.c:447
99: (b4) w2 = 0 ; frame1: R2=0
100: (b4) w3 = 3 ; frame1: R3=3
101: (85) call bpf_iter_num_new#82234 ; frame1: R0=scalar() fp-56=iter_num(ref_id=2,state=active,depth=0)
102: (18) r9 = 0x1ffffffffffffff8 ; frame1: R9=0x1ffffffffffffff8
104: (bf) r1 = r10 ; frame1: R1=fp0 R10=fp0
; @ scx_sdt.bpf.c:0
105: (07) r1 += -56 ; frame1: R1=fp-56
; bpf_for(u, 0, SDT_TASK_LEVELS) { @ scx_sdt.bpf.c:447
106: (85) call bpf_iter_num_next#82235 ; frame1: R0=0 fp-56=iter_num(ref_id=2,state=drained,depth=0)
107: (15) if r0 == 0x0 goto pc+29 ; frame1: R0=0
; if (tmp->nr_free > 0) @ scx_sdt.bpf.c:456
137: (bf) r1 = r10 ; frame1: R1=fp0 R10=fp0
; bpf_for(u, 0, SDT_TASK_LEVELS) { @ scx_sdt.bpf.c:447
138: (07) r1 += -56 ; frame1: R1=fp-56
139: (85) call bpf_iter_num_destroy#82232 ; frame1:
140: (b7) r9 = 0 ; frame1: R9=0
; if (unlikely(desc == NULL)) { @ scx_sdt.bpf.c:480
141: (15) if r8 == 0x0 goto pc+15 ; frame1: R8=scalar(umin=1)
; chunk = desc->chunk; @ scx_sdt.bpf.c:485
142: (79) r4 = *(u64 *)(r8 +72)
R8 invalid mem access 'scalar'
The reason is these older compilers lacks native support for
__BPF_FEATURE_ADDR_SPACE_CAST, __arena macro is defined as empty.
Fix it by adding cast_kern when dereferencing variables with __arena tag.
Signed-off-by: Zhao Mengmeng <zhaomengmeng@kylinos.cn>
---
tools/sched_ext/scx_sdt.bpf.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/tools/sched_ext/scx_sdt.bpf.c b/tools/sched_ext/scx_sdt.bpf.c
index 31b09958e8d5..caacc55bd7a5 100644
--- a/tools/sched_ext/scx_sdt.bpf.c
+++ b/tools/sched_ext/scx_sdt.bpf.c
@@ -148,6 +148,7 @@ static sdt_desc_t *scx_alloc_chunk(void)
out = desc;
+ cast_kern(desc);
desc->nr_free = SDT_TASK_ENTS_PER_CHUNK;
desc->chunk = chunk;
@@ -244,6 +245,7 @@ int mark_nodes_avail(sdt_desc_t *lv_desc[SDT_TASK_LEVELS], __u64 lv_pos[SDT_TASK
/* Only propagate upwards if we are the parent's only free chunk. */
desc = lv_desc[level];
+ cast_kern(desc);
ret = set_idx_state(desc, lv_pos[level], false);
if (unlikely(ret != 0))
return ret;
@@ -298,20 +300,26 @@ int scx_alloc_free_idx(struct scx_allocator *alloc, __u64 idx)
if (level == SDT_TASK_LEVELS - 1)
break;
+ cast_kern(desc);
chunk = desc->chunk;
+ cast_kern(chunk);
desc_children = (sdt_desc_t * __arena *)chunk->descs;
+ cast_kern(desc_children);
desc = desc_children[pos];
if (unlikely(!desc))
return -EINVAL;
}
+ cast_kern(desc);
chunk = desc->chunk;
pos = idx & mask;
+ cast_kern(chunk);
data = chunk->data[pos];
if (likely(data)) {
+ cast_kern(data);
*data = (struct sdt_data) {
.tid.genn = data->tid.genn + 1,
};
@@ -378,6 +386,7 @@ __u64 chunk_find_empty(sdt_desc_t __arg_arena *desc)
__u64 freeslots;
__u64 i;
+ cast_kern(desc);
for (i = 0; i < SDT_TASK_CHUNK_BITMAP_U64S; i++) {
freeslots = ~desc->allocated[i];
if (freeslots == (__u64)0)
@@ -426,9 +435,12 @@ static sdt_desc_t * desc_find_empty(sdt_desc_t *desc, __u64 *idxp)
break;
/* Allocate an internal node if necessary. */
+ cast_kern(desc);
chunk = desc->chunk;
+ cast_kern(chunk);
desc_children = (sdt_desc_t * __arena *)chunk->descs;
+ cast_kern(desc_children);
desc = desc_children[pos];
if (!desc) {
desc = scx_alloc_chunk();
@@ -448,6 +460,7 @@ static sdt_desc_t * desc_find_empty(sdt_desc_t *desc, __u64 *idxp)
level = SDT_TASK_LEVELS - 1 - u;
tmp = lv_desc[level];
+ cast_kern(tmp);
ret = set_idx_state(tmp, lv_pos[level], true);
if (ret != 0)
break;
@@ -482,10 +495,12 @@ void __arena *scx_alloc(struct scx_allocator *alloc)
return NULL;
}
+ cast_kern(desc);
chunk = desc->chunk;
/* Populate the leaf node if necessary. */
pos = idx & (SDT_TASK_ENTS_PER_CHUNK - 1);
+ cast_kern(chunk);
data = chunk->data[pos];
if (!data) {
data = scx_alloc_from_pool(&alloc->pool);
@@ -503,10 +518,12 @@ void __arena *scx_alloc(struct scx_allocator *alloc)
alloc_stats.alloc_ops += 1;
alloc_stats.active_allocs += 1;
+ cast_kern(data);
data->tid.idx = idx;
bpf_spin_unlock(&alloc_lock);
+ cast_user(data);
return data;
}
@@ -544,9 +561,10 @@ void __arena *scx_task_alloc(struct task_struct *p)
if (unlikely(!data))
return NULL;
+ mval->data = data;
+ cast_kern(data);
mval->tid = data->tid;
mval->tptr = (__u64) p;
- mval->data = data;
return (void __arena *)data->payload;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] tools/sched_ext: scx_sdt: Fix BPF verifier rejection on older LLVMs
2026-03-09 2:28 ` [PATCH v2 2/2] tools/sched_ext: scx_sdt: Fix BPF verifier rejection on older LLVMs Zhao Mengmeng
@ 2026-03-09 16:36 ` Emil Tsalapatis
2026-03-09 16:43 ` Alexei Starovoitov
2026-03-09 16:44 ` Tejun Heo
0 siblings, 2 replies; 8+ messages in thread
From: Emil Tsalapatis @ 2026-03-09 16:36 UTC (permalink / raw)
To: Zhao Mengmeng, tj, void, arighi, changwoo, nathan,
nick.desaulniers+lkml, morbo, justinstitt
Cc: sched-ext, linux-kernel, bpf, llvm, zhaomengmeng
On Sun Mar 8, 2026 at 10:28 PM EDT, Zhao Mengmeng wrote:
> From: Zhao Mengmeng <zhaomengmeng@kylinos.cn>
>
> Under Clang 17/18, when running scx_sdt scheduler, it fails with:
>
> libbpf: prog 'sdt_init_task': BPF program load failed: -EACCES
> libbpf: prog 'sdt_init_task': -- BEGIN PROG LOAD LOG --
> ...
> ; desc = desc_find_empty(alloc->root, &idx); @ scx_sdt.bpf.c:479
> 43: (79) r8 = *(u64 *)(r6 +32) ; frame1: R6=map_value(map=scx_sdt.bss,ks=4,vs=200,off=120) R8=scalar()
> ; for (level = zero; level < SDT_TASK_LEVELS && can_loop; level++) { @ scx_sdt.bpf.c:407
> 44: (e5) may_goto pc+51
> ; idx |= pos; @ scx_sdt.bpf.c:418
> 96: (bf) r7 = r2 ; frame1: R2=0 R7=0
> 97: (bf) r1 = r10 ; frame1: R1=fp0 R10=fp0
> ; @ scx_sdt.bpf.c:0
> 98: (07) r1 += -56 ; frame1: R1=fp-56
> ; bpf_for(u, 0, SDT_TASK_LEVELS) { @ scx_sdt.bpf.c:447
> 99: (b4) w2 = 0 ; frame1: R2=0
> 100: (b4) w3 = 3 ; frame1: R3=3
> 101: (85) call bpf_iter_num_new#82234 ; frame1: R0=scalar() fp-56=iter_num(ref_id=2,state=active,depth=0)
> 102: (18) r9 = 0x1ffffffffffffff8 ; frame1: R9=0x1ffffffffffffff8
> 104: (bf) r1 = r10 ; frame1: R1=fp0 R10=fp0
> ; @ scx_sdt.bpf.c:0
> 105: (07) r1 += -56 ; frame1: R1=fp-56
> ; bpf_for(u, 0, SDT_TASK_LEVELS) { @ scx_sdt.bpf.c:447
> 106: (85) call bpf_iter_num_next#82235 ; frame1: R0=0 fp-56=iter_num(ref_id=2,state=drained,depth=0)
> 107: (15) if r0 == 0x0 goto pc+29 ; frame1: R0=0
> ; if (tmp->nr_free > 0) @ scx_sdt.bpf.c:456
> 137: (bf) r1 = r10 ; frame1: R1=fp0 R10=fp0
> ; bpf_for(u, 0, SDT_TASK_LEVELS) { @ scx_sdt.bpf.c:447
> 138: (07) r1 += -56 ; frame1: R1=fp-56
> 139: (85) call bpf_iter_num_destroy#82232 ; frame1:
> 140: (b7) r9 = 0 ; frame1: R9=0
> ; if (unlikely(desc == NULL)) { @ scx_sdt.bpf.c:480
> 141: (15) if r8 == 0x0 goto pc+15 ; frame1: R8=scalar(umin=1)
> ; chunk = desc->chunk; @ scx_sdt.bpf.c:485
> 142: (79) r4 = *(u64 *)(r8 +72)
> R8 invalid mem access 'scalar'
>
> The reason is these older compilers lacks native support for
> __BPF_FEATURE_ADDR_SPACE_CAST, __arena macro is defined as empty.
>
> Fix it by adding cast_kern when dereferencing variables with __arena tag.
>
I am not sure if we want to support older Clang versions at this point.
This issue is fixed for Clang 19, and adding the macros back in makes it
confusing for those who use the code as a starting point. And while
it would be nice to support older Clang versions, we already don't
handle Clang 15/16 that don't have arena support. So it's not
unreasonable if we say Clang 17/18 are also incompatible with this
example.
On the other hand, maybe the extra compatibility is worth re-adding
cast_kern/cast_user to the code. I am slightly in favor of keeping it
as-is to avoid churn, but can easily see why we'd go the other way.
@htejun WDYT?
> Signed-off-by: Zhao Mengmeng <zhaomengmeng@kylinos.cn>
> ---
> tools/sched_ext/scx_sdt.bpf.c | 20 +++++++++++++++++++-
> 1 file changed, 19 insertions(+), 1 deletion(-)
>
> diff --git a/tools/sched_ext/scx_sdt.bpf.c b/tools/sched_ext/scx_sdt.bpf.c
> index 31b09958e8d5..caacc55bd7a5 100644
> --- a/tools/sched_ext/scx_sdt.bpf.c
> +++ b/tools/sched_ext/scx_sdt.bpf.c
> @@ -148,6 +148,7 @@ static sdt_desc_t *scx_alloc_chunk(void)
>
> out = desc;
>
> + cast_kern(desc);
> desc->nr_free = SDT_TASK_ENTS_PER_CHUNK;
> desc->chunk = chunk;
>
> @@ -244,6 +245,7 @@ int mark_nodes_avail(sdt_desc_t *lv_desc[SDT_TASK_LEVELS], __u64 lv_pos[SDT_TASK
> /* Only propagate upwards if we are the parent's only free chunk. */
> desc = lv_desc[level];
>
> + cast_kern(desc);
> ret = set_idx_state(desc, lv_pos[level], false);
> if (unlikely(ret != 0))
> return ret;
> @@ -298,20 +300,26 @@ int scx_alloc_free_idx(struct scx_allocator *alloc, __u64 idx)
> if (level == SDT_TASK_LEVELS - 1)
> break;
>
> + cast_kern(desc);
> chunk = desc->chunk;
>
> + cast_kern(chunk);
> desc_children = (sdt_desc_t * __arena *)chunk->descs;
> + cast_kern(desc_children);
> desc = desc_children[pos];
>
> if (unlikely(!desc))
> return -EINVAL;
> }
>
> + cast_kern(desc);
> chunk = desc->chunk;
>
> pos = idx & mask;
> + cast_kern(chunk);
> data = chunk->data[pos];
> if (likely(data)) {
> + cast_kern(data);
> *data = (struct sdt_data) {
> .tid.genn = data->tid.genn + 1,
> };
> @@ -378,6 +386,7 @@ __u64 chunk_find_empty(sdt_desc_t __arg_arena *desc)
> __u64 freeslots;
> __u64 i;
>
> + cast_kern(desc);
> for (i = 0; i < SDT_TASK_CHUNK_BITMAP_U64S; i++) {
> freeslots = ~desc->allocated[i];
> if (freeslots == (__u64)0)
> @@ -426,9 +435,12 @@ static sdt_desc_t * desc_find_empty(sdt_desc_t *desc, __u64 *idxp)
> break;
>
> /* Allocate an internal node if necessary. */
> + cast_kern(desc);
> chunk = desc->chunk;
> + cast_kern(chunk);
> desc_children = (sdt_desc_t * __arena *)chunk->descs;
>
> + cast_kern(desc_children);
> desc = desc_children[pos];
> if (!desc) {
> desc = scx_alloc_chunk();
> @@ -448,6 +460,7 @@ static sdt_desc_t * desc_find_empty(sdt_desc_t *desc, __u64 *idxp)
> level = SDT_TASK_LEVELS - 1 - u;
> tmp = lv_desc[level];
>
> + cast_kern(tmp);
> ret = set_idx_state(tmp, lv_pos[level], true);
> if (ret != 0)
> break;
> @@ -482,10 +495,12 @@ void __arena *scx_alloc(struct scx_allocator *alloc)
> return NULL;
> }
>
> + cast_kern(desc);
> chunk = desc->chunk;
>
> /* Populate the leaf node if necessary. */
> pos = idx & (SDT_TASK_ENTS_PER_CHUNK - 1);
> + cast_kern(chunk);
> data = chunk->data[pos];
> if (!data) {
> data = scx_alloc_from_pool(&alloc->pool);
> @@ -503,10 +518,12 @@ void __arena *scx_alloc(struct scx_allocator *alloc)
> alloc_stats.alloc_ops += 1;
> alloc_stats.active_allocs += 1;
>
> + cast_kern(data);
> data->tid.idx = idx;
>
> bpf_spin_unlock(&alloc_lock);
>
> + cast_user(data);
> return data;
> }
>
> @@ -544,9 +561,10 @@ void __arena *scx_task_alloc(struct task_struct *p)
> if (unlikely(!data))
> return NULL;
>
> + mval->data = data;
> + cast_kern(data);
> mval->tid = data->tid;
> mval->tptr = (__u64) p;
> - mval->data = data;
>
> return (void __arena *)data->payload;
> }
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] tools/sched_ext: scx_sdt: Fix BPF verifier rejection on older LLVMs
2026-03-09 16:36 ` Emil Tsalapatis
@ 2026-03-09 16:43 ` Alexei Starovoitov
2026-03-09 16:44 ` Tejun Heo
1 sibling, 0 replies; 8+ messages in thread
From: Alexei Starovoitov @ 2026-03-09 16:43 UTC (permalink / raw)
To: Emil Tsalapatis
Cc: Zhao Mengmeng, Tejun Heo, David Vernet, Andrea Righi,
Changwoo Min, Nathan Chancellor, Nick Desaulniers, Bill Wendling,
Justin Stitt, sched-ext, LKML, bpf, clang-built-linux,
zhaomengmeng
On Mon, Mar 9, 2026 at 9:40 AM Emil Tsalapatis <emil@etsalapatis.com> wrote:
>
> On Sun Mar 8, 2026 at 10:28 PM EDT, Zhao Mengmeng wrote:
> > From: Zhao Mengmeng <zhaomengmeng@kylinos.cn>
> >
> > Under Clang 17/18, when running scx_sdt scheduler, it fails with:
> >
> > libbpf: prog 'sdt_init_task': BPF program load failed: -EACCES
> > libbpf: prog 'sdt_init_task': -- BEGIN PROG LOAD LOG --
> > ...
> > ; desc = desc_find_empty(alloc->root, &idx); @ scx_sdt.bpf.c:479
> > 43: (79) r8 = *(u64 *)(r6 +32) ; frame1: R6=map_value(map=scx_sdt.bss,ks=4,vs=200,off=120) R8=scalar()
> > ; for (level = zero; level < SDT_TASK_LEVELS && can_loop; level++) { @ scx_sdt.bpf.c:407
> > 44: (e5) may_goto pc+51
> > ; idx |= pos; @ scx_sdt.bpf.c:418
> > 96: (bf) r7 = r2 ; frame1: R2=0 R7=0
> > 97: (bf) r1 = r10 ; frame1: R1=fp0 R10=fp0
> > ; @ scx_sdt.bpf.c:0
> > 98: (07) r1 += -56 ; frame1: R1=fp-56
> > ; bpf_for(u, 0, SDT_TASK_LEVELS) { @ scx_sdt.bpf.c:447
> > 99: (b4) w2 = 0 ; frame1: R2=0
> > 100: (b4) w3 = 3 ; frame1: R3=3
> > 101: (85) call bpf_iter_num_new#82234 ; frame1: R0=scalar() fp-56=iter_num(ref_id=2,state=active,depth=0)
> > 102: (18) r9 = 0x1ffffffffffffff8 ; frame1: R9=0x1ffffffffffffff8
> > 104: (bf) r1 = r10 ; frame1: R1=fp0 R10=fp0
> > ; @ scx_sdt.bpf.c:0
> > 105: (07) r1 += -56 ; frame1: R1=fp-56
> > ; bpf_for(u, 0, SDT_TASK_LEVELS) { @ scx_sdt.bpf.c:447
> > 106: (85) call bpf_iter_num_next#82235 ; frame1: R0=0 fp-56=iter_num(ref_id=2,state=drained,depth=0)
> > 107: (15) if r0 == 0x0 goto pc+29 ; frame1: R0=0
> > ; if (tmp->nr_free > 0) @ scx_sdt.bpf.c:456
> > 137: (bf) r1 = r10 ; frame1: R1=fp0 R10=fp0
> > ; bpf_for(u, 0, SDT_TASK_LEVELS) { @ scx_sdt.bpf.c:447
> > 138: (07) r1 += -56 ; frame1: R1=fp-56
> > 139: (85) call bpf_iter_num_destroy#82232 ; frame1:
> > 140: (b7) r9 = 0 ; frame1: R9=0
> > ; if (unlikely(desc == NULL)) { @ scx_sdt.bpf.c:480
> > 141: (15) if r8 == 0x0 goto pc+15 ; frame1: R8=scalar(umin=1)
> > ; chunk = desc->chunk; @ scx_sdt.bpf.c:485
> > 142: (79) r4 = *(u64 *)(r8 +72)
> > R8 invalid mem access 'scalar'
> >
> > The reason is these older compilers lacks native support for
> > __BPF_FEATURE_ADDR_SPACE_CAST, __arena macro is defined as empty.
> >
> > Fix it by adding cast_kern when dereferencing variables with __arena tag.
> >
>
> I am not sure if we want to support older Clang versions at this point.
> This issue is fixed for Clang 19, and adding the macros back in makes it
> confusing for those who use the code as a starting point. And while
> it would be nice to support older Clang versions, we already don't
> handle Clang 15/16 that don't have arena support. So it's not
> unreasonable if we say Clang 17/18 are also incompatible with this
> example.
+1
People should upgrade their compilers.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] tools/sched_ext: scx_sdt: Fix BPF verifier rejection on older LLVMs
2026-03-09 16:36 ` Emil Tsalapatis
2026-03-09 16:43 ` Alexei Starovoitov
@ 2026-03-09 16:44 ` Tejun Heo
2026-03-09 16:58 ` Zhao mengmeng
1 sibling, 1 reply; 8+ messages in thread
From: Tejun Heo @ 2026-03-09 16:44 UTC (permalink / raw)
To: Emil Tsalapatis
Cc: Zhao Mengmeng, void, arighi, changwoo, nathan,
nick.desaulniers+lkml, morbo, justinstitt, sched-ext,
linux-kernel, bpf, llvm, zhaomengmeng
On Mon, Mar 09, 2026 at 12:36:40PM -0400, Emil Tsalapatis wrote:
> On the other hand, maybe the extra compatibility is worth re-adding
> cast_kern/cast_user to the code. I am slightly in favor of keeping it
> as-is to avoid churn, but can easily see why we'd go the other way.
>
> @htejun WDYT?
Let's leave it as-is. The main purpose is to serve as an example for future
arena users. The benefit of keeping it simple trumps over supporting older
compilers.
thanks.
--
tejun
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] tools/sched_ext: scx_sdt: Fix BPF verifier rejection on older LLVMs
2026-03-09 16:44 ` Tejun Heo
@ 2026-03-09 16:58 ` Zhao mengmeng
0 siblings, 0 replies; 8+ messages in thread
From: Zhao mengmeng @ 2026-03-09 16:58 UTC (permalink / raw)
To: Tejun Heo, Emil Tsalapatis
Cc: void, arighi, changwoo, nathan, nick.desaulniers+lkml, morbo,
justinstitt, sched-ext, linux-kernel, bpf, llvm, zhaomengmeng
On March 10, 2026 12:44:56 AM GMT+08:00, Tejun Heo <tj@kernel.org> wrote:
>On Mon, Mar 09, 2026 at 12:36:40PM -0400, Emil Tsalapatis wrote:
>> On the other hand, maybe the extra compatibility is worth re-adding
>> cast_kern/cast_user to the code. I am slightly in favor of keeping it
>> as-is to avoid churn, but can easily see why we'd go the other way.
>>
>> @htejun WDYT?
>
>Let's leave it as-is. The main purpose is to serve as an example for future
>arena users. The benefit of keeping it simple trumps over supporting older
>compilers.
>
>thanks.
>
That's reasonable. I was hesitated to send this patch because it actually is a compiler problem, but I also has seen cast_kern/cast_user macros already defined to address the compatible problem. Shall we use __BPF_FEATURE_ADDR_SPACE_CAST to guard the code or check the llvm version before compiling these arena based schedules, or add some information on README? After all, it only demands llvm >=16 in README.md
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 0/2] sched_ext: cleanup and toolchain compatibility fixes
2026-03-09 2:28 [PATCH v2 0/2] sched_ext cleanup and toolchain compatibility fixes Zhao Mengmeng
2026-03-09 2:28 ` [PATCH v2 1/2] sched_ext: remove SCX_OPS_HAS_CGROUP_WEIGHT Zhao Mengmeng
2026-03-09 2:28 ` [PATCH v2 2/2] tools/sched_ext: scx_sdt: Fix BPF verifier rejection on older LLVMs Zhao Mengmeng
@ 2026-03-09 19:49 ` Tejun Heo
2 siblings, 0 replies; 8+ messages in thread
From: Tejun Heo @ 2026-03-09 19:49 UTC (permalink / raw)
To: Zhao Mengmeng, Zhao Mengmeng
Cc: void, arighi, changwoo, nathan, nick.desaulniers+lkml, morbo,
justinstitt, emil, sched-ext, linux-kernel, bpf, llvm
> Zhao Mengmeng (2):
> sched_ext: remove SCX_OPS_HAS_CGROUP_WEIGHT
> tools/sched_ext: scx_sdt: Fix BPF verifier rejection on older LLVMs
Applied 1 to sched_ext/for-7.1.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-03-09 19:49 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-09 2:28 [PATCH v2 0/2] sched_ext cleanup and toolchain compatibility fixes Zhao Mengmeng
2026-03-09 2:28 ` [PATCH v2 1/2] sched_ext: remove SCX_OPS_HAS_CGROUP_WEIGHT Zhao Mengmeng
2026-03-09 2:28 ` [PATCH v2 2/2] tools/sched_ext: scx_sdt: Fix BPF verifier rejection on older LLVMs Zhao Mengmeng
2026-03-09 16:36 ` Emil Tsalapatis
2026-03-09 16:43 ` Alexei Starovoitov
2026-03-09 16:44 ` Tejun Heo
2026-03-09 16:58 ` Zhao mengmeng
2026-03-09 19:49 ` [PATCH v2 0/2] sched_ext: cleanup and toolchain compatibility fixes Tejun Heo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox