[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <aCQgFIxz82oxLf8v@mtj.duckdns.org>
Date: Wed, 14 May 2025 00:46:12 -0400
From: Tejun Heo <tj@...nel.org>
To: Johannes Weiner <hannes@...xchg.org>,
Michal Koutný <mkoutny@...e.com>
Cc: cgroups@...r.kernel.org, linux-kernel@...r.kernel.org,
bpf@...r.kernel.org
Subject: [PATCH 3/3 cgroup/for-6.16] sched_ext: Convert cgroup BPF support to
use cgroup_lifetime_notifier
Replace explicit cgroup_bpf_inherit/offline() calls from cgroup
creation/destruction paths with notification callback registered on
cgroup_lifetime_notifier.
Signed-off-by: Tejun Heo <tj@...nel.org>
---
include/linux/bpf-cgroup.h | 9 +++++----
kernel/bpf/cgroup.c | 38 ++++++++++++++++++++++++++++++++++++--
kernel/cgroup/cgroup.c | 20 +++-----------------
3 files changed, 44 insertions(+), 23 deletions(-)
--- a/include/linux/bpf-cgroup.h
+++ b/include/linux/bpf-cgroup.h
@@ -114,8 +114,7 @@ struct bpf_prog_list {
u32 flags;
};
-int cgroup_bpf_inherit(struct cgroup *cgrp);
-void cgroup_bpf_offline(struct cgroup *cgrp);
+void __init cgroup_bpf_lifetime_notifier_init(void);
int __cgroup_bpf_run_filter_skb(struct sock *sk,
struct sk_buff *skb,
@@ -431,8 +430,10 @@ const struct bpf_func_proto *
cgroup_current_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog);
#else
-static inline int cgroup_bpf_inherit(struct cgroup *cgrp) { return 0; }
-static inline void cgroup_bpf_offline(struct cgroup *cgrp) {}
+static inline void cgroup_bpf_lifetime_notifier_init(void)
+{
+ return;
+}
static inline int cgroup_bpf_prog_attach(const union bpf_attr *attr,
enum bpf_prog_type ptype,
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -41,6 +41,19 @@ static int __init cgroup_bpf_wq_init(voi
}
core_initcall(cgroup_bpf_wq_init);
+static int cgroup_bpf_lifetime_notify(struct notifier_block *nb,
+ unsigned long action, void *data);
+
+static struct notifier_block cgroup_bpf_lifetime_nb = {
+ .notifier_call = cgroup_bpf_lifetime_notify,
+};
+
+void __init cgroup_bpf_lifetime_notifier_init(void)
+{
+ BUG_ON(blocking_notifier_chain_register(&cgroup_lifetime_notifier,
+ &cgroup_bpf_lifetime_nb));
+}
+
/* __always_inline is necessary to prevent indirect call through run_prog
* function pointer.
*/
@@ -206,7 +219,7 @@ bpf_cgroup_atype_find(enum bpf_attach_ty
}
#endif /* CONFIG_BPF_LSM */
-void cgroup_bpf_offline(struct cgroup *cgrp)
+static void cgroup_bpf_offline(struct cgroup *cgrp)
{
cgroup_get(cgrp);
percpu_ref_kill(&cgrp->bpf.refcnt);
@@ -491,7 +504,7 @@ static void activate_effective_progs(str
* cgroup_bpf_inherit() - inherit effective programs from parent
* @cgrp: the cgroup to modify
*/
-int cgroup_bpf_inherit(struct cgroup *cgrp)
+static int cgroup_bpf_inherit(struct cgroup *cgrp)
{
/* has to use marco instead of const int, since compiler thinks
* that array below is variable length
@@ -534,6 +547,27 @@ cleanup:
return -ENOMEM;
}
+static int cgroup_bpf_lifetime_notify(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct cgroup *cgrp = data;
+ int ret = 0;
+
+ if (cgrp->root != &cgrp_dfl_root)
+ return NOTIFY_OK;
+
+ switch (action) {
+ case CGROUP_LIFETIME_ONLINE:
+ ret = cgroup_bpf_inherit(cgrp);
+ break;
+ case CGROUP_LIFETIME_OFFLINE:
+ cgroup_bpf_offline(cgrp);
+ break;
+ }
+
+ return notifier_from_errno(ret);
+}
+
static int update_effective_progs(struct cgroup *cgrp,
enum cgroup_bpf_attach_type atype)
{
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -2162,11 +2162,6 @@ int cgroup_setup_root(struct cgroup_root
if (ret)
goto exit_stats;
- if (root == &cgrp_dfl_root) {
- ret = cgroup_bpf_inherit(root_cgrp);
- WARN_ON_ONCE(ret);
- }
-
ret = blocking_notifier_call_chain(&cgroup_lifetime_notifier,
CGROUP_LIFETIME_ONLINE, root_cgrp);
WARN_ON_ONCE(notifier_to_errno(ret));
@@ -5759,20 +5754,12 @@ static struct cgroup *cgroup_create(stru
cgrp->self.serial_nr = css_serial_nr_next++;
- if (cgrp->root == &cgrp_dfl_root) {
- ret = cgroup_bpf_inherit(cgrp);
- if (ret)
- goto out_psi_free;
- }
-
ret = blocking_notifier_call_chain_robust(&cgroup_lifetime_notifier,
CGROUP_LIFETIME_ONLINE,
CGROUP_LIFETIME_OFFLINE, cgrp);
ret = notifier_to_errno(ret);
- if (ret) {
- cgroup_bpf_offline(cgrp);
+ if (ret)
goto out_psi_free;
- }
/* allocation complete, commit to creation */
spin_lock_irq(&css_set_lock);
@@ -6059,9 +6046,6 @@ static int cgroup_destroy_locked(struct
cgroup1_check_for_release(parent);
- if (cgrp->root == &cgrp_dfl_root)
- cgroup_bpf_offline(cgrp);
-
ret = blocking_notifier_call_chain(&cgroup_lifetime_notifier,
CGROUP_LIFETIME_OFFLINE, cgrp);
WARN_ON_ONCE(notifier_to_errno(ret));
@@ -6215,6 +6199,8 @@ int __init cgroup_init(void)
hash_add(css_set_table, &init_css_set.hlist,
css_set_hash(init_css_set.subsys));
+ cgroup_bpf_lifetime_notifier_init();
+
BUG_ON(cgroup_setup_root(&cgrp_dfl_root, 0));
cgroup_unlock();
Powered by blists - more mailing lists