summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorCheng-Yang Chou <yphbchou0911@gmail.com>2026-03-31 12:18:33 +0300
committerTejun Heo <tj@kernel.org>2026-04-06 21:06:24 +0300
commita3c3fb2f86f8a1f266747622037f90eab58186ad (patch)
tree2487a9b7c8454b0e786963112186915ac1a23b7d /tools
parent744ab12a5bd1a0dc59c5ba5354ae40030c834a46 (diff)
downloadlinux-a3c3fb2f86f8a1f266747622037f90eab58186ad.tar.xz
tools/sched_ext: Fix off-by-one in scx_sdt payload zeroing
scx_alloc_free_idx() zeroes the payload of a freed arena allocation one word at a time. The loop bound was alloc->pool.elem_size / 8, but elem_size includes sizeof(struct sdt_data) (the 8-byte union sdt_id header). This caused the loop to write one extra u64 past the allocation, corrupting the tid field of the adjacent pool element. Fix the loop bound to (elem_size - sizeof(struct sdt_data)) / 8 so only the payload portion is zeroed. Test plan: - Add a temporary sanity check in scx_task_free() before the free call: if (mval->data->tid.idx != mval->tid.idx) scx_bpf_error("tid corruption: arena=%d storage=%d", mval->data->tid.idx, (int)mval->tid.idx); - stress-ng --fork 100 -t 10 & sudo ./build/bin/scx_sdt Without this fix, running scx_sdt under fork-heavy load triggers the corruption error. With the fix applied, the same workload completes without error. Fixes: 36929ebd17ae ("tools/sched_ext: add arena based scheduler") Signed-off-by: Cheng-Yang Chou <yphbchou0911@gmail.com> Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/sched_ext/scx_sdt.bpf.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/tools/sched_ext/scx_sdt.bpf.c b/tools/sched_ext/scx_sdt.bpf.c
index 10248b71ef02..a1e33e6c412b 100644
--- a/tools/sched_ext/scx_sdt.bpf.c
+++ b/tools/sched_ext/scx_sdt.bpf.c
@@ -317,7 +317,8 @@ int scx_alloc_free_idx(struct scx_allocator *alloc, __u64 idx)
};
/* Zero out one word at a time. */
- for (i = zero; i < alloc->pool.elem_size / 8 && can_loop; i++) {
+ for (i = zero; i < (alloc->pool.elem_size - sizeof(struct sdt_data)) / 8
+ && can_loop; i++) {
data->payload[i] = 0;
}
}