The Linux Kernel Mailing List
 help / color / mirror / Atom feed
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, &current->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


  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