All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHSET sched_ext/for-7.3] sched_ext: Rename the cid-form cgroup ops to cpuctl_*
@ 2026-07-18 10:10 Tejun Heo
  2026-07-18 10:10 ` [PATCH 1/2] tools/sched_ext: Add SCX_OPS_CID_OPEN for cid-form schedulers Tejun Heo
  2026-07-18 10:10 ` [PATCH 2/2] sched_ext: Rename the cid-form cgroup ops to cpuctl_* Tejun Heo
  0 siblings, 2 replies; 3+ messages in thread
From: Tejun Heo @ 2026-07-18 10:10 UTC (permalink / raw)
  To: David Vernet, Andrea Righi, Changwoo Min
  Cc: sched-ext, Emil Tsalapatis, linux-kernel, Tejun Heo

Hello,

Two unrelated things go by "cgroup" in the cid form. Sub-schedulers attach
to cgroups, and the cgroup_*() ops deliver cpu controller events. While the
ops names suggest cgroup2 hierarchy, they actually operate on the cpu
controller. The cid form has no users beyond scx_qmap yet, so rename the
ops to cpuctl_* while the ABI can still change. The cpu form is deployed
ABI and keeps the old names.

- 0001 factors the skeleton open path out of SCX_OPS_OPEN() and adds
  SCX_OPS_CID_OPEN() so that cid-form skeletons don't depend on the
  cpu-form member names dereferenced by the compat clears.

- 0002 renames the ops to cpuctl_* in struct sched_ext_ops_cid and updates
  scx_qmap, the only cid-form scheduler.

Based on sched_ext/for-7.3 (7c2cd767705d) plus the cgroup migration
patchset:

  https://lore.kernel.org/r/20260718081727.582037-1-tj@kernel.org

Tejun Heo (2):
  tools/sched_ext: Add SCX_OPS_CID_OPEN for cid-form schedulers
  sched_ext: Rename the cid-form cgroup ops to cpuctl_*

Git tree: git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext.git scx-cpuctl-rename

 kernel/sched/ext/ext.c               | 36 ++++++++++++++++++------------------
 kernel/sched/ext/internal.h          | 25 ++++++++++++-------------
 tools/sched_ext/include/scx/compat.h | 30 ++++++++++++++++++++++--------
 tools/sched_ext/scx_qmap.bpf.c       | 22 +++++++++++-----------
 tools/sched_ext/scx_qmap.c           |  4 ++--
 tools/sched_ext/scx_qmap.h           |  2 +-
 6 files changed, 66 insertions(+), 53 deletions(-)

--
tejun

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] tools/sched_ext: Add SCX_OPS_CID_OPEN for cid-form schedulers
  2026-07-18 10:10 [PATCHSET sched_ext/for-7.3] sched_ext: Rename the cid-form cgroup ops to cpuctl_* Tejun Heo
@ 2026-07-18 10:10 ` Tejun Heo
  2026-07-18 10:10 ` [PATCH 2/2] sched_ext: Rename the cid-form cgroup ops to cpuctl_* Tejun Heo
  1 sibling, 0 replies; 3+ messages in thread
From: Tejun Heo @ 2026-07-18 10:10 UTC (permalink / raw)
  To: David Vernet, Andrea Righi, Changwoo Min
  Cc: sched-ext, Emil Tsalapatis, linux-kernel, Tejun Heo

SCX_OPS_OPEN() clears compat-gated ops fields which the running kernel
lacks. The clears dereference cpu-form member names and compile for
cid-form skeletons only because both ops structs currently name their
cgroup ops identically, which an upcoming rename will end. No load-time
fix-up can apply to a cid-form scheduler anyway as the cid form postdates
every compat-gated op.

Factor the skeleton open path out of SCX_OPS_OPEN() and add
SCX_OPS_CID_OPEN() which uses only that shared part. Switch scx_qmap, the
only cid-form scheduler, over.

Signed-off-by: Tejun Heo <tj@kernel.org>
---
 tools/sched_ext/include/scx/compat.h | 30 ++++++++++++++++++++--------
 tools/sched_ext/scx_qmap.c           |  2 +-
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/tools/sched_ext/include/scx/compat.h b/tools/sched_ext/include/scx/compat.h
index 23d9ef3e4c9d..7757252d52e2 100644
--- a/tools/sched_ext/include/scx/compat.h
+++ b/tools/sched_ext/include/scx/compat.h
@@ -154,7 +154,7 @@ static inline long scx_hotplug_seq(void)
  * struct sched_ext_ops can change over time. Two complementary mechanisms
  * keep BPF schedulers built against newer headers running on older kernels:
  *
- * 1. Load-time fix-up (this macro). For each optional ops callback or field
+ * 1. Load-time fix-up (SCX_OPS_OPEN()). For each optional ops callback or field
  *    added to struct sched_ext_ops, an explicit stanza below probes the
  *    running kernel's BTF via __COMPAT_struct_has_field() and, if the field
  *    is missing, clears it in the in-memory struct_ops (with a warning to
@@ -176,16 +176,23 @@ static inline long scx_hotplug_seq(void)
  * - v6.19: ops.cgroup_set_idle()
  * - v7.1:  ops.sub_attach(), ops.sub_detach(), ops.sub_cgroup_id
  */
+#define __SCX_OPS_OPEN(__ops_name, __scx_name, __ops_struct) ({			\
+	struct __scx_name *__oskel;						\
+										\
+	SCX_BUG_ON(!__COMPAT_struct_has_field(__ops_struct, "dump"),		\
+		   __ops_struct ".dump() missing, kernel too old?");		\
+										\
+	__oskel = __scx_name##__open();						\
+	SCX_BUG_ON(!__oskel, "Could not open " #__scx_name);			\
+	__oskel->struct_ops.__ops_name->hotplug_seq = scx_hotplug_seq();	\
+	SCX_ENUM_INIT(__oskel);							\
+	__oskel;								\
+})
+
 #define SCX_OPS_OPEN(__ops_name, __scx_name) ({					\
 	struct __scx_name *__skel;						\
 										\
-	SCX_BUG_ON(!__COMPAT_struct_has_field("sched_ext_ops", "dump"),		\
-		   "sched_ext_ops.dump() missing, kernel too old?");		\
-										\
-	__skel = __scx_name##__open();						\
-	SCX_BUG_ON(!__skel, "Could not open " #__scx_name);			\
-	__skel->struct_ops.__ops_name->hotplug_seq = scx_hotplug_seq();		\
-	SCX_ENUM_INIT(__skel);							\
+	__skel = __SCX_OPS_OPEN(__ops_name, __scx_name, "sched_ext_ops");	\
 	if (__skel->struct_ops.__ops_name->cgroup_set_bandwidth &&		\
 	    !__COMPAT_struct_has_field("sched_ext_ops", "cgroup_set_bandwidth")) { \
 		fprintf(stderr, "WARNING: kernel doesn't support ops.cgroup_set_bandwidth()\n"); \
@@ -214,6 +221,13 @@ static inline long scx_hotplug_seq(void)
 	__skel; 								\
 })
 
+/*
+ * Open a cid-form (struct sched_ext_ops_cid) skeleton. The cid form postdates
+ * every op the load-time fix-ups above handle, so none of them apply.
+ */
+#define SCX_OPS_CID_OPEN(__ops_name, __scx_name)				\
+	__SCX_OPS_OPEN(__ops_name, __scx_name, "sched_ext_ops_cid")
+
 /*
  * Associate non-struct_ops BPF programs with the scheduler's struct_ops map so
  * that scx_prog_sched() can determine which scheduler a BPF program belongs
diff --git a/tools/sched_ext/scx_qmap.c b/tools/sched_ext/scx_qmap.c
index 46892b4bb448..ddb524b4946c 100644
--- a/tools/sched_ext/scx_qmap.c
+++ b/tools/sched_ext/scx_qmap.c
@@ -251,7 +251,7 @@ int main(int argc, char **argv)
 	}
 restart:
 	optind = 1;
-	skel = SCX_OPS_OPEN(qmap_ops, scx_qmap);
+	skel = SCX_OPS_CID_OPEN(qmap_ops, scx_qmap);
 
 	skel->rodata->slice_ns = __COMPAT_ENUM_OR_ZERO("scx_public_consts", "SCX_SLICE_DFL");
 	skel->rodata->max_tasks = 16384;
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] sched_ext: Rename the cid-form cgroup ops to cpuctl_*
  2026-07-18 10:10 [PATCHSET sched_ext/for-7.3] sched_ext: Rename the cid-form cgroup ops to cpuctl_* Tejun Heo
  2026-07-18 10:10 ` [PATCH 1/2] tools/sched_ext: Add SCX_OPS_CID_OPEN for cid-form schedulers Tejun Heo
@ 2026-07-18 10:10 ` Tejun Heo
  1 sibling, 0 replies; 3+ messages in thread
From: Tejun Heo @ 2026-07-18 10:10 UTC (permalink / raw)
  To: David Vernet, Andrea Righi, Changwoo Min
  Cc: sched-ext, Emil Tsalapatis, linux-kernel, Tejun Heo

Two unrelated things go by "cgroup" in the cid form. Sub-schedulers attach
to cgroups, and the cgroup_*() ops deliver cpu controller events. While the
ops names suggest cgroup2 hierarchy, they actually operate on the cpu
controller.

Rename them to cpuctl_* in struct sched_ext_ops_cid, which has no users
outside scx_qmap yet. The cpu form is deployed ABI and keeps the old names.
The layout is unchanged and the kernel keeps calling through the cpu-form
union view.

Signed-off-by: Tejun Heo <tj@kernel.org>
---
 kernel/sched/ext/ext.c         | 36 +++++++++++++++++-----------------
 kernel/sched/ext/internal.h    | 25 ++++++++++++-----------
 tools/sched_ext/scx_qmap.bpf.c | 22 ++++++++++-----------
 tools/sched_ext/scx_qmap.c     |  2 +-
 tools/sched_ext/scx_qmap.h     |  2 +-
 5 files changed, 43 insertions(+), 44 deletions(-)

diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
index 58cd971e5fc5..b730eac4b13f 100644
--- a/kernel/sched/ext/ext.c
+++ b/kernel/sched/ext/ext.c
@@ -7952,14 +7952,14 @@ static struct sched_ext_ops_cid __bpf_ops_sched_ext_ops_cid = {
 	.enable			= sched_ext_ops__enable,
 	.disable		= sched_ext_ops__disable,
 #ifdef CONFIG_EXT_GROUP_SCHED
-	.cgroup_init		= sched_ext_ops__cgroup_init,
-	.cgroup_exit		= sched_ext_ops__cgroup_exit,
-	.cgroup_prep_move	= sched_ext_ops__cgroup_prep_move,
-	.cgroup_move		= sched_ext_ops__cgroup_move,
-	.cgroup_cancel_move	= sched_ext_ops__cgroup_cancel_move,
-	.cgroup_set_weight	= sched_ext_ops__cgroup_set_weight,
-	.cgroup_set_bandwidth	= sched_ext_ops__cgroup_set_bandwidth,
-	.cgroup_set_idle	= sched_ext_ops__cgroup_set_idle,
+	.cpuctl_init		= sched_ext_ops__cgroup_init,
+	.cpuctl_exit		= sched_ext_ops__cgroup_exit,
+	.cpuctl_prep_move	= sched_ext_ops__cgroup_prep_move,
+	.cpuctl_move		= sched_ext_ops__cgroup_move,
+	.cpuctl_cancel_move	= sched_ext_ops__cgroup_cancel_move,
+	.cpuctl_set_weight	= sched_ext_ops__cgroup_set_weight,
+	.cpuctl_set_bandwidth	= sched_ext_ops__cgroup_set_bandwidth,
+	.cpuctl_set_idle	= sched_ext_ops__cgroup_set_idle,
 #endif
 	.sub_attach		= sched_ext_ops__sub_attach,
 	.sub_detach		= sched_ext_ops__sub_detach,
@@ -10479,22 +10479,22 @@ static int __init scx_init(void)
 	CID_OFFSET_MATCH(init_cids, init_cids);
 	CID_OFFSET_MATCH(init, init);
 	CID_OFFSET_MATCH(exit, exit);
-#ifdef CONFIG_EXT_GROUP_SCHED
-	CID_OFFSET_MATCH(cgroup_init, cgroup_init);
-	CID_OFFSET_MATCH(cgroup_exit, cgroup_exit);
-	CID_OFFSET_MATCH(cgroup_prep_move, cgroup_prep_move);
-	CID_OFFSET_MATCH(cgroup_move, cgroup_move);
-	CID_OFFSET_MATCH(cgroup_cancel_move, cgroup_cancel_move);
-	CID_OFFSET_MATCH(cgroup_set_weight, cgroup_set_weight);
-	CID_OFFSET_MATCH(cgroup_set_bandwidth, cgroup_set_bandwidth);
-	CID_OFFSET_MATCH(cgroup_set_idle, cgroup_set_idle);
-#endif
 	/* renamed callbacks must occupy the same slot as their cpu-form sibling */
 	CID_OFFSET_MATCH(select_cpu, select_cid);
 	CID_OFFSET_MATCH(set_cpumask, set_cmask);
 	CID_OFFSET_MATCH(cpu_online, cid_online);
 	CID_OFFSET_MATCH(cpu_offline, cid_offline);
 	CID_OFFSET_MATCH(dump_cpu, dump_cid);
+#ifdef CONFIG_EXT_GROUP_SCHED
+	CID_OFFSET_MATCH(cgroup_init, cpuctl_init);
+	CID_OFFSET_MATCH(cgroup_exit, cpuctl_exit);
+	CID_OFFSET_MATCH(cgroup_prep_move, cpuctl_prep_move);
+	CID_OFFSET_MATCH(cgroup_move, cpuctl_move);
+	CID_OFFSET_MATCH(cgroup_cancel_move, cpuctl_cancel_move);
+	CID_OFFSET_MATCH(cgroup_set_weight, cpuctl_set_weight);
+	CID_OFFSET_MATCH(cgroup_set_bandwidth, cpuctl_set_bandwidth);
+	CID_OFFSET_MATCH(cgroup_set_idle, cpuctl_set_idle);
+#endif
 	/* @priv tail must align since both share the same data block */
 	CID_OFFSET_MATCH(priv, priv);
 	/*
diff --git a/kernel/sched/ext/internal.h b/kernel/sched/ext/internal.h
index 0c0a8fdaa2c4..26bfda216524 100644
--- a/kernel/sched/ext/internal.h
+++ b/kernel/sched/ext/internal.h
@@ -992,6 +992,7 @@ struct sched_ext_ops {
  *   - cpu_online       -> cid_online
  *   - cpu_offline      -> cid_offline
  *   - dump_cpu         -> dump_cid
+ *   - cgroup_*         -> cpuctl_* (they track the cgroup cpu controller)
  *   - cpu_acquire/cpu_release  -> not present (deprecated in sched_ext_ops)
  *
  * BPF schedulers using this type cannot call cpu-form scx_bpf_* kfuncs;
@@ -1027,19 +1028,17 @@ struct sched_ext_ops_cid {
 	void (*dump_cid)(struct scx_dump_ctx *ctx, s32 cid, bool idle);
 	void (*dump_task)(struct scx_dump_ctx *ctx, struct task_struct *p);
 #ifdef CONFIG_EXT_GROUP_SCHED
-	s32 (*cgroup_init)(struct cgroup *cgrp,
-			    struct scx_cgroup_init_args *args);
-	void (*cgroup_exit)(struct cgroup *cgrp);
-	s32 (*cgroup_prep_move)(struct task_struct *p,
-				 struct cgroup *from, struct cgroup *to);
-	void (*cgroup_move)(struct task_struct *p,
-			     struct cgroup *from, struct cgroup *to);
-	void (*cgroup_cancel_move)(struct task_struct *p,
-				    struct cgroup *from, struct cgroup *to);
-	void (*cgroup_set_weight)(struct cgroup *cgrp, u32 weight);
-	void (*cgroup_set_bandwidth)(struct cgroup *cgrp,
-				      u64 period_us, u64 quota_us, u64 burst_us);
-	void (*cgroup_set_idle)(struct cgroup *cgrp, bool idle);
+	s32 (*cpuctl_init)(struct cgroup *cgrp, struct scx_cgroup_init_args *args);
+	void (*cpuctl_exit)(struct cgroup *cgrp);
+	s32 (*cpuctl_prep_move)(struct task_struct *p, struct cgroup *from,
+				struct cgroup *to);
+	void (*cpuctl_move)(struct task_struct *p, struct cgroup *from, struct cgroup *to);
+	void (*cpuctl_cancel_move)(struct task_struct *p, struct cgroup *from,
+				   struct cgroup *to);
+	void (*cpuctl_set_weight)(struct cgroup *cgrp, u32 weight);
+	void (*cpuctl_set_bandwidth)(struct cgroup *cgrp, u64 period_us, u64 quota_us,
+				     u64 burst_us);
+	void (*cpuctl_set_idle)(struct cgroup *cgrp, bool idle);
 #endif	/* CONFIG_EXT_GROUP_SCHED */
 	s32 (*sub_attach)(struct scx_sub_attach_args *args);
 	void (*sub_detach)(struct scx_sub_detach_args *args);
diff --git a/tools/sched_ext/scx_qmap.bpf.c b/tools/sched_ext/scx_qmap.bpf.c
index 925ae1a1d440..aead17658573 100644
--- a/tools/sched_ext/scx_qmap.bpf.c
+++ b/tools/sched_ext/scx_qmap.bpf.c
@@ -1014,7 +1014,7 @@ void BPF_STRUCT_OPS(qmap_dump_task, struct scx_dump_ctx *dctx, struct task_struc
 		     taskc->force_local, taskc->core_sched_seq);
 }
 
-s32 BPF_STRUCT_OPS(qmap_cgroup_init, struct cgroup *cgrp, struct scx_cgroup_init_args *args)
+s32 BPF_STRUCT_OPS(qmap_cpuctl_init, struct cgroup *cgrp, struct scx_cgroup_init_args *args)
 {
 	QMAP_TOUCH_ARENA();
 
@@ -1036,7 +1036,7 @@ s32 BPF_STRUCT_OPS(qmap_cgroup_init, struct cgroup *cgrp, struct scx_cgroup_init
 
 static void redistribute(void);
 
-void BPF_STRUCT_OPS(qmap_cgroup_set_weight, struct cgroup *cgrp, u32 weight)
+void BPF_STRUCT_OPS(qmap_cpuctl_set_weight, struct cgroup *cgrp, u32 weight)
 {
 	u64 cgid = cgrp->kn->id;
 	s32 i;
@@ -1062,16 +1062,16 @@ void BPF_STRUCT_OPS(qmap_cgroup_set_weight, struct cgroup *cgrp, u32 weight)
 	}
 }
 
-void BPF_STRUCT_OPS(qmap_cgroup_set_bandwidth, struct cgroup *cgrp,
-		    u64 period_us, u64 quota_us, u64 burst_us)
+void BPF_STRUCT_OPS(qmap_cpuctl_set_bandwidth, struct cgroup *cgrp, u64 period_us,
+		    u64 quota_us, u64 burst_us)
 {
 	if (print_msgs)
 		bpf_printk("CGRP SET %llu period=%lu quota=%ld burst=%lu",
 			   cgrp->kn->id, period_us, quota_us, burst_us);
 }
 
-void BPF_STRUCT_OPS(qmap_cgroup_move, struct task_struct *p,
-		    struct cgroup *from, struct cgroup *to)
+void BPF_STRUCT_OPS(qmap_cpuctl_move, struct task_struct *p, struct cgroup *from,
+		    struct cgroup *to)
 {
 	if (print_msgs)
 		bpf_printk("CGRP MOVE %d %llu -> %llu",
@@ -1890,7 +1890,7 @@ void BPF_STRUCT_OPS(qmap_exit, struct scx_exit_info *ei)
 
 /*
  * Seed a new sub slot with the cgroup's current weight. The kernel delivers
- * ops.cgroup_set_weight() only on value-changing writes, so a weight set
+ * ops.cpuctl_set_weight() only on value-changing writes, so a weight set
  * before the sub attached would otherwise go unnoticed.
  */
 static u32 cgrp_cur_weight(u64 cgid)
@@ -1989,10 +1989,10 @@ SCX_OPS_CID_DEFINE(qmap_ops,
 	       .dump			= (void *)qmap_dump,
 	       .dump_cid		= (void *)qmap_dump_cid,
 	       .dump_task		= (void *)qmap_dump_task,
-	       .cgroup_init		= (void *)qmap_cgroup_init,
-	       .cgroup_set_weight	= (void *)qmap_cgroup_set_weight,
-	       .cgroup_set_bandwidth	= (void *)qmap_cgroup_set_bandwidth,
-	       .cgroup_move		= (void *)qmap_cgroup_move,
+	       .cpuctl_init		= (void *)qmap_cpuctl_init,
+	       .cpuctl_set_weight	= (void *)qmap_cpuctl_set_weight,
+	       .cpuctl_set_bandwidth	= (void *)qmap_cpuctl_set_bandwidth,
+	       .cpuctl_move		= (void *)qmap_cpuctl_move,
 	       .sub_attach		= (void *)qmap_sub_attach,
 	       .sub_detach		= (void *)qmap_sub_detach,
 	       .sub_caps_updated	= (void *)qmap_sub_caps_updated,
diff --git a/tools/sched_ext/scx_qmap.c b/tools/sched_ext/scx_qmap.c
index ddb524b4946c..27ffda1c519e 100644
--- a/tools/sched_ext/scx_qmap.c
+++ b/tools/sched_ext/scx_qmap.c
@@ -70,7 +70,7 @@ const char help_fmt[] =
 "  -i SEC        Stats interval, seconds (default 5)\n"
 "  -R MS         Round-robin period for time-shared cpus, ms (default 200)\n"
 "  -J MODE       Fault injection (wrong-cid: dispatch to a cid not held,\n"
-"                init-fail/cgrp-init-fail: fail init_task/cgroup_init for\n"
+"                init-fail/cgrp-init-fail: fail init_task/cpuctl_init for\n"
 "                \"qmfail*\" comms/cgroups)\n"
 "  -v            Print libbpf debug messages\n"
 "  -h            Display this help and exit\n";
diff --git a/tools/sched_ext/scx_qmap.h b/tools/sched_ext/scx_qmap.h
index cc2840e7aa3c..c42f7ef74b89 100644
--- a/tools/sched_ext/scx_qmap.h
+++ b/tools/sched_ext/scx_qmap.h
@@ -65,7 +65,7 @@ enum qmap_inject {
 	QMAP_INJ_OFF		= 0,
 	QMAP_INJ_WRONG_CID	= 1,	/* dispatch to a cid we don't hold */
 	QMAP_INJ_INIT_FAIL	= 2,	/* fail init_task for "qmfail*" comms */
-	QMAP_INJ_CGRP_INIT_FAIL	= 3,	/* fail cgroup_init for "qmfail*" cgroups */
+	QMAP_INJ_CGRP_INIT_FAIL	= 3,	/* fail cpuctl_init for "qmfail*" cgroups */
 };
 
 /*
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-07-18 10:10 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-18 10:10 [PATCHSET sched_ext/for-7.3] sched_ext: Rename the cid-form cgroup ops to cpuctl_* Tejun Heo
2026-07-18 10:10 ` [PATCH 1/2] tools/sched_ext: Add SCX_OPS_CID_OPEN for cid-form schedulers Tejun Heo
2026-07-18 10:10 ` [PATCH 2/2] sched_ext: Rename the cid-form cgroup ops to cpuctl_* Tejun Heo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.