diff options
| author | Tejun Heo <tj@kernel.org> | 2026-07-24 09:09:28 -1000 |
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2026-07-24 12:10:22 -1000 |
| commit | 3a21e34eb2588e135190cf5c48e64397bc18d0b5 (patch) | |
| tree | 7664b3a2ed5243869c37c6ffdc824e4429564d6f /tools | |
| parent | 49d6247d64aec7ba1590223d277c47ae09037d4d (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.h | 2 | ||||
| -rw-r--r-- | tools/sched_ext/scx_qmap.bpf.c | 17 |
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); } |
