[PATCH 4/5] sched_ext: Factor out scx_cpuperf_set()

From: Tejun Heo

Date: Fri Jul 24 2026 - 14:27:11 EST


Factor the cpuperf target write out of scx_bpf_cpuperf_set() into
scx_cpuperf_set() which takes the acting sched and returns 0 or -errno, and
flatten the nested validation into early returns. No functional change.
Prep for gating the write behind a cap and reporting the outcome from the
cid-form kfunc.

Signed-off-by: Tejun Heo <tj@xxxxxxxxxx>
---
kernel/sched/ext/ext.c | 77 ++++++++++++++++++++++++------------------
1 file changed, 44 insertions(+), 33 deletions(-)

diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
index 5d02bb99c09d..366245daab68 100644
--- a/kernel/sched/ext/ext.c
+++ b/kernel/sched/ext/ext.c
@@ -9796,49 +9796,60 @@ __bpf_kfunc u32 scx_bpf_cidperf_cur(s32 cid, const struct bpf_prog_aux *aux)
* use. Consult hardware and cpufreq documentation for more information. The
* current performance level can be monitored using scx_bpf_cpuperf_cur().
*/
-__bpf_kfunc void scx_bpf_cpuperf_set(s32 cpu, u32 perf, const struct bpf_prog_aux *aux)
+static s32 scx_cpuperf_set(struct scx_sched *sch, s32 cpu, u32 perf)
{
- struct scx_sched *sch;
-
- guard(rcu)();
-
- sch = scx_prog_sched(aux);
- if (unlikely(!sch))
- return;
+ struct rq *rq, *locked_rq;
+ struct rq_flags rf;

if (unlikely(perf > SCX_CPUPERF_ONE)) {
scx_error(sch, "Invalid cpuperf target %u for CPU %d", perf, cpu);
- return;
+ return -EINVAL;
}

- if (scx_cpu_valid(sch, cpu, NULL)) {
- struct rq *rq = cpu_rq(cpu), *locked_rq = scx_locked_rq();
- struct rq_flags rf;
-
- /*
- * When called with an rq lock held, restrict the operation
- * to the corresponding CPU to prevent ABBA deadlocks.
- */
- if (locked_rq && rq != locked_rq) {
- scx_error(sch, "Invalid target CPU %d", cpu);
- return;
- }
+ if (!scx_cpu_valid(sch, cpu, NULL))
+ return -EINVAL;

- /*
- * If no rq lock is held, allow to operate on any CPU by
- * acquiring the corresponding rq lock.
- */
- if (!locked_rq) {
- rq_lock_irqsave(rq, &rf);
- update_rq_clock(rq);
- }
+ rq = cpu_rq(cpu);
+ locked_rq = scx_locked_rq();

- rq->scx.cpuperf_target = perf;
- cpufreq_update_util(rq, 0);
+ /*
+ * When called with an rq lock held, restrict the operation to the
+ * corresponding CPU to prevent ABBA deadlocks.
+ */
+ if (locked_rq && rq != locked_rq) {
+ scx_error(sch, "Invalid target CPU %d", cpu);
+ return -EINVAL;
+ }

- if (!locked_rq)
- rq_unlock_irqrestore(rq, &rf);
+ /*
+ * If no rq lock is held, allow to operate on any CPU by acquiring
+ * the corresponding rq lock.
+ */
+ if (!locked_rq) {
+ rq_lock_irqsave(rq, &rf);
+ update_rq_clock(rq);
}
+
+ rq->scx.cpuperf_target = perf;
+ cpufreq_update_util(rq, 0);
+
+ if (!locked_rq)
+ rq_unlock_irqrestore(rq, &rf);
+
+ return 0;
+}
+
+__bpf_kfunc void scx_bpf_cpuperf_set(s32 cpu, u32 perf, const struct bpf_prog_aux *aux)
+{
+ struct scx_sched *sch;
+
+ guard(rcu)();
+
+ sch = scx_prog_sched(aux);
+ if (unlikely(!sch))
+ return;
+
+ scx_cpuperf_set(sch, cpu, perf);
}

/**
--
2.55.0