summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2026-07-24 09:09:28 -1000
committerTejun Heo <tj@kernel.org>2026-07-24 12:10:22 -1000
commit3a21e34eb2588e135190cf5c48e64397bc18d0b5 (patch)
tree7664b3a2ed5243869c37c6ffdc824e4429564d6f /tools
parent49d6247d64aec7ba1590223d277c47ae09037d4d (diff)
sched_ext: Gate scx_bpf_cidperf_set() behind a new SCX_CAP_PERF
scx_bpf_cidperf_set() reaches cpufreq with no cap check, so any cid-form sub-sched can steer the frequency of any cid in its view, including ones it holds nothing on. Gate it behind a new SCX_CAP_PERF rather than SCX_CAP_BASE: hardware control is a separate axis from queue access - a parent may well delegate scheduling on a cid without handing over its frequency. PERF neither implies nor is implied by the other caps. The check runs under the target rq's lock, which ecaps updates are also folded under, so it is authoritative - a write can never land after a revoke has taken effect. Denials are counted in SCX_EV_SUB_CIDPERF_DENIED. The operation is synchronous and the outcome is reported to the caller: scx_bpf_cidperf_set() now returns 0 or -errno, -EACCES on denial. The cid-form interface is still under initial development, so the signature is changed in place without versioning. scx_qmap grants PERF alongside its existing cid grants so the cpuperf demo keeps working in sub-scheds. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/sched_ext/include/scx/common.bpf.h2
-rw-r--r--tools/sched_ext/scx_qmap.bpf.c17
2 files changed, 12 insertions, 7 deletions
diff --git a/tools/sched_ext/include/scx/common.bpf.h b/tools/sched_ext/include/scx/common.bpf.h
index acc2b131ea8f..6035d007c43f 100644
--- a/tools/sched_ext/include/scx/common.bpf.h
+++ b/tools/sched_ext/include/scx/common.bpf.h
@@ -112,7 +112,7 @@ u32 scx_bpf_nr_cids(void) __ksym __weak;
u32 scx_bpf_nr_online_cids(void) __ksym __weak;
u32 scx_bpf_cidperf_cap(s32 cid) __ksym __weak;
u32 scx_bpf_cidperf_cur(s32 cid) __ksym __weak;
-void scx_bpf_cidperf_set(s32 cid, u32 perf) __ksym __weak;
+s32 scx_bpf_cidperf_set(s32 cid, u32 perf) __ksym __weak;
/* sub-scheduler cap control, scx_bpf_sub_caps() cgroup_id 0 == self */
s32 scx_bpf_sub_grant(u64 cgroup_id, u64 caps, const struct scx_cmask *cmask,
diff --git a/tools/sched_ext/scx_qmap.bpf.c b/tools/sched_ext/scx_qmap.bpf.c
index aead17658573..8822ed11c0d8 100644
--- a/tools/sched_ext/scx_qmap.bpf.c
+++ b/tools/sched_ext/scx_qmap.bpf.c
@@ -1585,11 +1585,13 @@ __noinline void apply_partition(void)
cmask_copy(&qa.to_grant_cids.mask, &ssc->granted_cids.mask);
cmask_andnot(&qa.to_grant_cids.mask, &ssc->prev_granted.mask);
- scx_bpf_sub_revoke(cgid, SCX_CAP_ENQ_IMMED,
+ scx_bpf_sub_revoke(cgid, SCX_CAP_ENQ_IMMED | SCX_CAP_PERF,
(void *)(long)&qa.prev_rr_cids.mask);
- scx_bpf_sub_revoke(cgid, SCX_CAP_ENQ | SCX_CAP_PREEMPT | SCX_CAP_ENQ_IMMED,
+ scx_bpf_sub_revoke(cgid, SCX_CAP_ENQ | SCX_CAP_PREEMPT |
+ SCX_CAP_ENQ_IMMED | SCX_CAP_PERF,
(void *)(long)&qa.to_revoke_cids.mask);
- scx_bpf_sub_grant(cgid, SCX_CAP_ENQ | SCX_CAP_PREEMPT | SCX_CAP_ENQ_IMMED,
+ scx_bpf_sub_grant(cgid, SCX_CAP_ENQ | SCX_CAP_PREEMPT |
+ SCX_CAP_ENQ_IMMED | SCX_CAP_PERF,
(void *)(long)&qa.to_grant_cids.mask, NULL);
}
@@ -1605,7 +1607,8 @@ __noinline void apply_partition(void)
holder_cgid = qa.part.rr_slots[pos]; /* 0 = self, nothing to grant */
if (holder_cgid)
- scx_bpf_sub_grant(holder_cgid, SCX_CAP_ENQ_IMMED,
+ scx_bpf_sub_grant(holder_cgid,
+ SCX_CAP_ENQ_IMMED | SCX_CAP_PERF,
(void *)(long)&qa.rr_cids.mask, NULL);
}
}
@@ -1696,10 +1699,12 @@ static void rr_advance(void)
* time-share.
*/
if (old_cgid)
- scx_bpf_sub_revoke(old_cgid, SCX_CAP_ENQ_IMMED,
+ scx_bpf_sub_revoke(old_cgid,
+ SCX_CAP_ENQ_IMMED | SCX_CAP_PERF,
(void *)(long)&qa.rr_cids.mask);
if (new_cgid)
- scx_bpf_sub_grant(new_cgid, SCX_CAP_ENQ_IMMED,
+ scx_bpf_sub_grant(new_cgid,
+ SCX_CAP_ENQ_IMMED | SCX_CAP_PERF,
(void *)(long)&qa.rr_cids.mask, NULL);
}