Commit 82648b8b authored by Tejun Heo's avatar Tejun Heo
Browse files

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: default avatarTejun Heo <tj@kernel.org>
parent 9e8c67a9
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -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,
+36 −2
Original line number Diff line number Diff line
@@ -41,6 +41,19 @@ static int __init cgroup_bpf_wq_init(void)
}
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_type attach_type, u32 attach_btf_id)
}
#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(struct cgroup *cgrp,
 * 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 @@ int cgroup_bpf_inherit(struct cgroup *cgrp)
	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)
{
+3 −17
Original line number Diff line number Diff line
@@ -2143,11 +2143,6 @@ int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask)
	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));
@@ -5739,20 +5734,12 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name,

	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);
@@ -6045,9 +6032,6 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)

	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));
@@ -6206,6 +6190,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();