All of lore.kernel.org
 help / color / mirror / Atom feed
From: Djalal Harouni <tixxdz@gmail.com>
To: tixxdz@gmail.com
Cc: Tejun Heo <tj@kernel.org>, Zefan Li <lizefan.x@bytedance.com>,
	Johannes Weiner <hannes@cmpxchg.org>,
	Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Andrii Nakryiko <andrii@kernel.org>,
	Martin KaFai Lau <martin.lau@linux.dev>,
	Eduard Zingerman <eddyz87@gmail.com>, Song Liu <song@kernel.org>,
	Yonghong Song <yonghong.song@linux.dev>,
	John Fastabend <john.fastabend@gmail.com>,
	KP Singh <kpsingh@kernel.org>,
	Stanislav Fomichev <sdf@google.com>, Hao Luo <haoluo@google.com>,
	Jiri Olsa <jolsa@kernel.org>, Mykola Lysenko <mykolal@fb.com>,
	Shuah Khan <shuah@kernel.org>,
	linux-kernel@vger.kernel.org, cgroups@vger.kernel.org,
	bpf@vger.kernel.org, linux-kselftest@vger.kernel.org
Subject: [RFC PATCH bpf-next 1/3] cgroup: add cgroup_freeze_no_kn() to freeze a cgroup from bpf
Date: Wed, 27 Mar 2024 23:53:23 +0100	[thread overview]
Message-ID: <20240327225334.58474-2-tixxdz@gmail.com> (raw)
In-Reply-To: <20240327225334.58474-1-tixxdz@gmail.com>

This patch adds a new cgroup helper cgroup_freeze_no_kn() to freeze a
cgroup hierarchy that is on a default cgroup v2 without going through
kernfs interface.

For some cases we want to freeze the cgroup of a task based on some
signals, doing so from bpf is better than user space which could be
too late.

The cgroup_freeze_no_kn() will acquire the cgroup_mutex and release it
at the end.

It also checks if the cgroup is on the default hierarchy and it is not
a root cgroup.

Signed-off-by: Djalal Harouni <tixxdz@gmail.com>
---
 include/linux/cgroup.h |  2 ++
 kernel/cgroup/cgroup.c | 69 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 71 insertions(+)

diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 34aaf0e87def..5019b32ea933 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -137,6 +137,8 @@ int cgroup_init(void);
 
 int cgroup_parse_float(const char *input, unsigned dec_shift, s64 *v);
 
+int cgroup_freeze_no_kn(struct cgroup *cgrp, int freeze);
+
 /*
  * Iteration helpers and macros.
  */
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index a66c088c851c..0aafcd9e39b5 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -1595,6 +1595,26 @@ static u16 cgroup_calc_subtree_ss_mask(u16 subtree_control, u16 this_ss_mask)
 	return cur_ss_mask;
 }
 
+/**
+ * cgroup_dfl_write_no_kn - check if direct writes to cgroup without going
+ * through kernfs is allowed.
+ * @cgrp: the target cgroup
+ *
+ * This helper ensures that the cgroup is on the default hierarchy and it
+ * is not a root cgroup.
+ *
+ * Return: %0 on success or a negative errno code on failure.
+ */
+static int cgroup_dfl_write_no_kn(struct cgroup *cgrp)
+{
+	lockdep_assert_held(&cgroup_mutex);
+
+	if (!cgroup_on_dfl(cgrp) || !cgroup_parent(cgrp))
+		return -EOPNOTSUPP;
+
+	return 0;
+}
+
 /**
  * cgroup_kn_unlock - unlocking helper for cgroup kernfs methods
  * @kn: the kernfs_node being serviced
@@ -1668,6 +1688,25 @@ struct cgroup *cgroup_kn_lock_live(struct kernfs_node *kn, bool drain_offline)
 	return NULL;
 }
 
+/**
+ * cgroup_lock_live_no_kn - locking helper for direct writes to cgroup without
+ * going through kernfs interface.
+ * @cgrp: the target cgroup
+ *
+ * This helper performs cgroup locking and verifies that the associated cgroup
+ * is alive. Returns the cgroup if alive; otherwise, %NULL.
+ * A successful return should be undone by a matching cgroup_unlock()
+ * invocation.
+ */
+static struct cgroup *cgroup_lock_live_no_kn(struct cgroup *cgrp)
+{
+	cgroup_lock();
+	if (!cgroup_is_dead(cgrp))
+		return cgrp;
+	cgroup_unlock();
+	return NULL;
+}
+
 static void cgroup_rm_file(struct cgroup *cgrp, const struct cftype *cft)
 {
 	char name[CGROUP_FILE_NAME_MAX];
@@ -3930,6 +3969,36 @@ static int cgroup_freeze_show(struct seq_file *seq, void *v)
 	return 0;
 }
 
+/**
+ * cgroup_freeze_no_kn - Freeze a cgroup that is on the default hierarchy
+ * without going through kernfs interface.
+ *
+ * @cgrp: the target cgroup
+ * @freeze: freeze state, passing value 1 causes the freezing of the cgroup
+ * and all descendant cgroups. Processes under this cgroup hierarchy will
+ * be stopped and will not run until the cgroup is explicitly unfrozen.
+ * Passing value 0 unthaws the cgroup hierarchy.
+ *
+ * Return: %0 on success or a negative errno code on failure.
+ */
+int cgroup_freeze_no_kn(struct cgroup *cgrp, int freeze)
+{
+	int ret = 0;
+
+	if (freeze < 0 || freeze > 1)
+		return -ERANGE;
+
+	if (!cgroup_lock_live_no_kn(cgrp))
+		return -ENOENT;
+
+	ret = cgroup_dfl_write_no_kn(cgrp);
+	if (!ret)
+		cgroup_freeze(cgrp, freeze);
+
+	cgroup_unlock();
+	return ret;
+}
+
 static ssize_t cgroup_freeze_write(struct kernfs_open_file *of,
 				   char *buf, size_t nbytes, loff_t off)
 {
-- 
2.34.1


  reply	other threads:[~2024-03-27 22:55 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20240327-ccb56fc7a6e80136db80876c@djalal>
2024-03-27 22:53 ` [RFC PATCH bpf-next 0/3] bpf: freeze a task cgroup from bpf Djalal Harouni
2024-03-27 22:53   ` Djalal Harouni [this message]
2024-03-27 22:53   ` [RFC PATCH bpf-next 2/3] bpf: add bpf_task_freeze_cgroup() to freeze the cgroup of a task Djalal Harouni
2024-03-27 22:53   ` [RFC PATCH bpf-next 3/3] selftests/bpf: add selftest for bpf_task_freeze_cgroup Djalal Harouni
2024-03-28 17:22   ` [RFC PATCH bpf-next 0/3] bpf: freeze a task cgroup from bpf Tejun Heo
2024-03-28 17:32     ` Alexei Starovoitov
2024-03-28 17:58       ` Tejun Heo
2024-03-28 19:46         ` Alexei Starovoitov
2024-03-28 20:02           ` Tejun Heo
2024-03-28 20:45             ` Alexei Starovoitov
2024-03-28 21:01               ` Tejun Heo
2024-03-28 21:28                 ` Alexei Starovoitov
2024-03-28 23:23                   ` Tejun Heo
2024-03-29 13:22                 ` Djalal Harouni
2024-03-29 21:39                   ` Tejun Heo
2024-03-29 23:04                     ` Alexei Starovoitov
2024-04-02 17:40                       ` Djalal Harouni
2024-04-02 17:16   ` Michal Koutný
2024-04-02 18:20     ` Djalal Harouni
2024-04-09 15:32       ` Michal Koutný
2024-04-11  0:26         ` Yonghong Song
2024-04-11  8:25           ` Michal Koutný
2024-04-11  8:36         ` Djalal Harouni

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=20240327225334.58474-2-tixxdz@gmail.com \
    --to=tixxdz@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=cgroups@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=hannes@cmpxchg.org \
    --cc=haoluo@google.com \
    --cc=john.fastabend@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=kpsingh@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=lizefan.x@bytedance.com \
    --cc=martin.lau@linux.dev \
    --cc=mykolal@fb.com \
    --cc=sdf@google.com \
    --cc=shuah@kernel.org \
    --cc=song@kernel.org \
    --cc=tj@kernel.org \
    --cc=yonghong.song@linux.dev \
    /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 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.