From: Tejun Heo <tj@kernel.org>
To: void@manifault.com, arighi@nvidia.com, multics69@gmail.com
Cc: linux-kernel@vger.kernel.org, sched-ext@lists.linux.dev,
memxor@gmail.com, bpf@vger.kernel.org, Tejun Heo <tj@kernel.org>
Subject: [PATCH 24/46] HACK_NOT_FOR_UPSTREAM: BPF: Implement prog grouping hack
Date: Fri, 19 Sep 2025 14:58:47 -1000 [thread overview]
Message-ID: <20250920005931.2753828-25-tj@kernel.org> (raw)
In-Reply-To: <20250920005931.2753828-1-tj@kernel.org>
Hopefully, we can have something better instead.
NOT_SIGNED_OFF
---
include/linux/bpf.h | 5 +++++
include/linux/sched.h | 2 ++
kernel/bpf/syscall.c | 23 +++++++++++++++++++++++
kernel/sched/ext.c | 36 ++++++++++++++++++++++++++++++++++++
tools/sched_ext/scx_qmap.c | 13 +++++++++++++
5 files changed, 79 insertions(+)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index cc700925b802..5101ae3ba2b6 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1581,6 +1581,11 @@ struct bpf_stream_stage {
struct bpf_prog_aux {
atomic64_t refcnt;
+
+ /* XXX - See kernel/sched/ext.c::scx_sub_enable() */
+ u64 priv_user;
+ void *priv;
+
u32 used_map_cnt;
u32 used_btf_cnt;
u32 max_ctx_offset;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 2b272382673d..576aed48beb2 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1596,6 +1596,8 @@ struct task_struct {
struct bpf_local_storage __rcu *bpf_storage;
/* Used for BPF run context */
struct bpf_run_ctx *bpf_ctx;
+ /* XXX - See kernel/sched/ext.c::scx_sub_enable() */
+ u64 bpf_prog_aux_priv;
#endif
/* Used by BPF for per-TASK xdp storage */
struct bpf_net_context *bpf_net_context;
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 0fbfa8532c39..e85dbe7fe5ce 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -2761,6 +2761,27 @@ static bool is_perfmon_prog_type(enum bpf_prog_type prog_type)
}
}
+static int prog_aux_priv_param_set(const char *input, const struct kernel_param *kp)
+{
+ return kstrtoull(input, 0, ¤t->bpf_prog_aux_priv);
+}
+
+static int prog_aux_priv_param_get(char *buf, const struct kernel_param *kp)
+{
+ return scnprintf(buf, PAGE_SIZE, "%llu\n", current->bpf_prog_aux_priv);
+}
+
+static const struct kernel_param_ops prog_aux_priv_param_ops = {
+ .set = prog_aux_priv_param_set,
+ .get = prog_aux_priv_param_get,
+};
+
+#undef MODULE_PARAM_PREFIX
+#define MODULE_PARAM_PREFIX "bpf."
+module_param_cb(prog_aux_priv, &prog_aux_priv_param_ops, NULL, 0664);
+MODULE_PARM_DESC("prog_aux_priv",
+ "Set prog->aux->priv to this value for all BPF programs loaded by %current");
+
/* last field in 'union bpf_attr' used by this command */
#define BPF_PROG_LOAD_LAST_FIELD fd_array_cnt
@@ -2898,6 +2919,8 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
prog->expected_attach_type = attr->expected_attach_type;
prog->sleepable = !!(attr->prog_flags & BPF_F_SLEEPABLE);
+ /* XXX - See kernel/sched/ext.c::scx_sub_enable() */
+ prog->aux->priv_user = current->bpf_prog_aux_priv;
prog->aux->attach_btf = attach_btf;
prog->aux->attach_btf_id = attr->attach_btf_id;
prog->aux->dst_prog = dst_prog;
diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
index 5eb1d6919595..a0251442b8ac 100644
--- a/kernel/sched/ext.c
+++ b/kernel/sched/ext.c
@@ -4116,6 +4116,24 @@ static void scx_sub_disable(struct scx_sched *sch)
if (sch->ops.exit)
SCX_CALL_OP(sch, SCX_KF_UNLOCKED, exit, NULL, sch->exit_info);
+
+ /*
+ * XXX - NULL prog->aux->priv is interpreted as scx_root, so use an
+ * ERR_PTR value to mark the associated progs dead. Note that this is
+ * racy as e.g. a tracepoint program associated with a scheduler which
+ * hasn't finished scx_sub_enable() yet may end up affecting scx_root
+ * inadvertently. Plug the hole when this hack is replaced with a proper
+ * BPF construct.
+ */
+ u32 prog_id = 0;
+ struct bpf_prog *prog;
+ while ((prog = bpf_prog_get_curr_or_next(&prog_id))) {
+ if (prog->aux->priv == sch)
+ RCU_INIT_POINTER(prog->aux->priv, ERR_PTR(-ENODEV));
+ bpf_prog_put(prog);
+ prog_id++;
+ }
+
kobject_del(&sch->kobj);
}
#else /* CONFIG_EXT_SUB_SCHED */
@@ -5148,6 +5166,24 @@ static int scx_sub_enable(struct sched_ext_ops *ops, struct bpf_link *link)
goto err_disable;
}
+ /*
+ * XXX - We want all BPF programs loaded together with this scheduler
+ * instance to point to this scheduler instance. BPF currently doesn't
+ * have such feature so work around with a hack. The loading userspace
+ * thread sets %current->bpf_prog_aux_priv to the associated cgroup ID
+ * which gets transferred to bpf->aux->priv_user in bpf_prog_load().
+ * Here, we can find all progs that have the matching cgroup ID and set
+ * their prog->aux->priv to $sch.
+ */
+ u32 prog_id = 0;
+ struct bpf_prog *prog;
+ while ((prog = bpf_prog_get_curr_or_next(&prog_id))) {
+ if (prog->aux->priv_user == cgroup_id(cgrp))
+ rcu_assign_pointer(prog->aux->priv, sch);
+ bpf_prog_put(prog);
+ prog_id++;
+ }
+
if (sch->ops.init) {
ret = SCX_CALL_OP_RET(sch, SCX_KF_UNLOCKED, init, NULL);
if (ret) {
diff --git a/tools/sched_ext/scx_qmap.c b/tools/sched_ext/scx_qmap.c
index 5d762d10f4db..cefc439c9e4a 100644
--- a/tools/sched_ext/scx_qmap.c
+++ b/tools/sched_ext/scx_qmap.c
@@ -99,12 +99,25 @@ int main(int argc, char **argv)
break;
case 'c': {
struct stat st;
+ int fd, len;
+ char buf[19];
if (stat(optarg, &st) < 0) {
perror("stat");
return 1;
}
skel->struct_ops.qmap_ops->sub_cgroup_id = st.st_ino;
skel->rodata->sub_cgroup_id = st.st_ino;
+ fd = open("/sys/module/bpf/parameters/prog_aux_priv", O_RDWR);
+ if (fd < 0) {
+ perror("open(\"/sys/module/bpf/parameters/prog_aux_priv\")");
+ return 1;
+ }
+ len = snprintf(buf, sizeof(buf), "0x%lx", st.st_ino);
+ if (write(fd, buf, len) != len) {
+ perror("write(\"/sys/module/bpf/parameters/prog_aux_priv\")");
+ return 1;
+ }
+ close(fd);
break;
}
case 'd':
--
2.51.0
next prev parent reply other threads:[~2025-09-20 0:59 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-20 0:58 [PATCHSET RFC] sched_ext: Implement cgroup sub-scheduler support Tejun Heo
2025-09-20 0:58 ` [PATCH 01/46] sched_ext: Use rhashtable_lookup() instead of rhashtable_lookup_fast() Tejun Heo
2025-09-20 0:58 ` [PATCH 02/46] sched_ext: Improve SCX_KF_DISPATCH comment Tejun Heo
2025-09-20 0:58 ` [PATCH 03/46] sched_ext: Fix stray scx_root usage in task_can_run_on_remote_rq() Tejun Heo
2025-09-20 0:58 ` [PATCH 04/46] sched_ext: Use bitfields for boolean warning flags Tejun Heo
2025-09-20 0:58 ` [PATCH 05/46] sched_ext: Add SCX_EFLAG_INITIALIZED to indicate successful ops.init() Tejun Heo
2025-09-20 0:58 ` [PATCH 06/46] sched_ext: Make qmap dump operation non-destructive Tejun Heo
2025-09-20 0:58 ` [PATCH 07/46] tools/sched_ext: scx_qmap: Make debug output quieter by default Tejun Heo
2025-09-20 0:58 ` [PATCH 08/46] sched_ext: Separate out scx_kick_cpu() and add @sch to it Tejun Heo
2025-09-20 0:58 ` [PATCH 09/46] sched_ext: Add the @sch parameter to __bstr_format() Tejun Heo
2025-09-20 0:58 ` [PATCH 10/46] sched_ext: Add the @sch parameter to ext_idle helpers Tejun Heo
2025-09-20 0:58 ` [PATCH 11/46] sched_ext: Drop kf_cpu_valid() Tejun Heo
2025-09-20 0:58 ` [PATCH 12/46] sched_ext: Add the @sch parameter to scx_dsq_insert_preamble/commit() Tejun Heo
2025-09-20 0:58 ` [PATCH 13/46] sched_ext: Drop scx_kf_exit() and scx_kf_error() Tejun Heo
2025-09-20 0:58 ` [PATCH 14/46] sched_ext: Misc updates around scx_sched instance pointer Tejun Heo
2025-09-20 0:58 ` [PATCH 15/46] sched_ext: Keep dying tasks on a separate list Tejun Heo
2025-09-20 0:58 ` [PATCH 16/46] sched_ext: Implement cgroup subtree iteration for scx_task_iter Tejun Heo
2025-09-20 0:58 ` [PATCH 17/46] sched_ext: Add @kargs to scx_fork() Tejun Heo
2025-09-20 0:58 ` [PATCH 18/46] sched/core: Swap the order between sched_post_fork() and cgroup_post_fork() Tejun Heo
2025-09-20 0:58 ` [PATCH 19/46] cgroup: Expose some cgroup helpers Tejun Heo
2025-09-20 0:58 ` [PATCH 20/46] sched_ext: Update p->scx.disallow warning in scx_init_task() Tejun Heo
2025-09-20 0:58 ` [PATCH 21/46] sched_ext: Minor reorganization of enable/disable path Tejun Heo
2025-09-20 0:58 ` [PATCH 22/46] sched_ext: Factor out scx_claim_exit() from scx_disable() Tejun Heo
2025-09-20 0:58 ` [PATCH 23/46] sched_ext: Introduce cgroup sub-sched support Tejun Heo
2025-09-20 0:58 ` Tejun Heo [this message]
2025-09-20 0:58 ` [PATCH 25/46] sched_ext: Introduce scx_task_sched[_rcu]() Tejun Heo
2025-09-20 0:58 ` [PATCH 26/46] sched_ext: Introduce scx_prog_sched() Tejun Heo
2025-09-20 0:58 ` [PATCH 27/46] sched_ext: Ignore insertions of not-owned tasks into DSQs Tejun Heo
2025-09-20 0:58 ` [PATCH 28/46] sched_ext: scx_dsq_move() should validate the task belongs to the right scheduler Tejun Heo
2025-09-20 0:58 ` [PATCH 29/46] sched_ext: Refactor task init/exit helpers Tejun Heo
2025-09-20 0:58 ` [PATCH 30/46] sched_ext: Make scx_prio_less() handle multiple schedulers Tejun Heo
2025-09-20 0:58 ` [PATCH 31/46] sched_ext: Move bypass_depth into scx_sched Tejun Heo
2025-09-20 0:58 ` [PATCH 32/46] sched_ext: Make bypass mode sub-sched aware Tejun Heo
2025-09-20 0:58 ` [PATCH 33/46] sched_ext: Factor out scx_dispatch_sched() Tejun Heo
2025-09-20 0:58 ` [PATCH 34/46] sched_ext: When calling ops.dispatch() @prev must be on the same scx_sched Tejun Heo
2025-09-20 0:58 ` [PATCH 35/46] sched_ext: Dispatch from all scx_sched instances Tejun Heo
2025-09-20 0:58 ` [PATCH 36/46] sched_ext: Move scx_dsp_ctx and scx_dsp_max_batch into scx_sched Tejun Heo
2025-09-20 0:59 ` [PATCH 37/46] sched_ext: Make watchdog sub-sched aware Tejun Heo
2025-09-20 0:59 ` [PATCH 38/46] sched_ext: Convert scx_dump_state() spinlock to raw spinlock Tejun Heo
2025-09-20 0:59 ` [PATCH 39/46] sched_ext: Support dumping multiple schedulers and add scheduler identification Tejun Heo
2025-09-20 0:59 ` [PATCH 40/46] sched_ext: Implement cgroup sub-sched enabling and disabling Tejun Heo
2025-09-20 0:59 ` [PATCH 41/46] HACK_NOT_FOR_UPSTREAM: sched_ext: Work around @aux__prog prototype mismatch Tejun Heo
2025-09-20 0:59 ` [PATCH 42/46] sched_ext: Wrap global DSQs in per-node structure Tejun Heo
2025-09-20 0:59 ` [PATCH 43/46] sched_ext: Add bypass DSQ for sub-schedulers Tejun Heo
2025-09-20 0:59 ` [PATCH 44/46] sched_ext: Factor out scx_link_sched() and scx_unlink_sched() Tejun Heo
2025-09-20 0:59 ` [PATCH 45/46] sched_ext: Add rhashtable lookup for sub-schedulers Tejun Heo
2025-09-20 0:59 ` [PATCH 46/46] sched_ext: Add basic building blocks for nested sub-scheduler dispatching Tejun Heo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250920005931.2753828-25-tj@kernel.org \
--to=tj@kernel.org \
--cc=arighi@nvidia.com \
--cc=bpf@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=memxor@gmail.com \
--cc=multics69@gmail.com \
--cc=sched-ext@lists.linux.dev \
--cc=void@manifault.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox