All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Valente <paolo.valente@linaro.org>
To: Jens Axboe <axboe@kernel.dk>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Tejun Heo <tj@kernel.org>, Li Zefan <lizefan@huawei.com>,
	Angelo Ruocco <angeloruocco90@gmail.com>,
	Dennis Zhou <dennis@kernel.org>,
	Josef Bacik <josef@toxicpanda.com>,
	Liu Bo <bo.liu@linux.alibaba.com>,
	Bart Van Assche <bvanassche@acm.org>,
	Johannes Weiner <hannes@cmpxchg.org>
Cc: linux-block@vger.kernel.org, linux-kernel@vger.kernel.org,
	ulf.hansson@linaro.org, linus.walleij@linaro.org,
	broonie@kernel.org, bfq-iosched@googlegroups.com,
	oleksandr@natalenko.name, cgroups@vger.kernel.org,
	linux-doc@vger.kernel.org, Jonathan Corbet <corbet@lwn.net>,
	Paolo Valente <paolo.valente@linaro.org>
Subject: [PATCH 07/12] cgroup: make all functions of all cftypes be invoked
Date: Mon, 12 Nov 2018 10:56:27 +0100	[thread overview]
Message-ID: <20181112095632.69114-8-paolo.valente@linaro.org> (raw)
In-Reply-To: <20181112095632.69114-1-paolo.valente@linaro.org>

From: Angelo Ruocco <angeloruocco90@gmail.com>

When two or more policies share a file their respective cftypes are
linked together. The allowed operations on those files are: open,
release, write and show, mapped to the functions defined in the
cftypes.

This commit makes the cgroup core invoke, whenever one of those
operations is requested, the respective function of all the cftypes
linked together.

Signed-off-by: Angelo Ruocco <angeloruocco90@gmail.com>
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
---
 kernel/cgroup/cgroup.c | 181 ++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 132 insertions(+), 49 deletions(-)

diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index e3cc437669a8..6d4cfd6395ec 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -3481,66 +3481,107 @@ static int cgroup_cpu_pressure_show(struct seq_file *seq, void *v)
 static int cgroup_file_open(struct kernfs_open_file *of)
 {
 	struct cftype *cft = of->kn->priv;
+	struct cftype *n;
+	int ret = 0;
 
+	list_for_each_cft(cft, n) {
+		if (cft->open)
+			ret = cft->open(of);
+		/*
+		 * If there has been an error with the open function of one of
+		 * the cft associated with the file, we call the release
+		 * function of all the cftype associated to cft whose open
+		 * function succeded.
+		 */
+		if (ret) {
+			struct cftype *c = of->kn->priv;
+			struct cftype *n;
+
+			list_for_each_cft(c, n) {
+				if (cft == c)
+					break;
+				if (c->release)
+					c->release(of);
+			}
+			break;
+		}
+	}
 
-	if (cft->open)
-		return cft->open(of);
-	return 0;
+	return ret;
 }
 
 static void cgroup_file_release(struct kernfs_open_file *of)
 {
 	struct cftype *cft = of->kn->priv;
+	struct cftype *n;
 
-	if (cft->release)
-		cft->release(of);
+	list_for_each_cft(cft, n)
+		if (cft->release)
+			cft->release(of);
 }
 
+/*
+ * Call all the write functions of the cftypes associated with the file.
+ *
+ * When a write fails, don't keep trying to write into the file via the write
+ * functions of the other cftypes associated with it.
+ */
 static ssize_t cgroup_file_write(struct kernfs_open_file *of, char *buf,
 				 size_t nbytes, loff_t off)
 {
 	struct cgroup_namespace *ns = current->nsproxy->cgroup_ns;
 	struct cgroup *cgrp = of->kn->parent->priv;
 	struct cftype *cft = of->kn->priv;
+	struct cftype *n;
 	struct cgroup_subsys_state *css;
-	int ret;
+	int ret = 0;
 
-	/*
-	 * If namespaces are delegation boundaries, disallow writes to
-	 * files in an non-init namespace root from inside the namespace
-	 * except for the files explicitly marked delegatable -
-	 * cgroup.procs and cgroup.subtree_control.
-	 */
-	if ((cgrp->root->flags & CGRP_ROOT_NS_DELEGATE) &&
-	    !(cft->flags & CFTYPE_NS_DELEGATABLE) &&
-	    ns != &init_cgroup_ns && ns->root_cset->dfl_cgrp == cgrp)
-		return -EPERM;
+	list_for_each_cft(cft, n) {
+		/*
+		 * If namespaces are delegation boundaries, disallow writes to
+		 * files in an non-init namespace root from inside the
+		 * namespace except for the files explicitly marked
+		 * delegatable - cgroup.procs and cgroup.subtree_control.
+		 */
+		if ((cgrp->root->flags & CGRP_ROOT_NS_DELEGATE) &&
+		    !(cft->flags & CFTYPE_NS_DELEGATABLE) &&
+		    ns != &init_cgroup_ns && ns->root_cset->dfl_cgrp == cgrp)
+			return -EPERM;
 
-	if (cft->write)
-		return cft->write(of, buf, nbytes, off);
+		if (cft->write) {
+			ret = cft->write(of, buf, nbytes, off);
 
-	/*
-	 * kernfs guarantees that a file isn't deleted with operations in
-	 * flight, which means that the matching css is and stays alive and
-	 * doesn't need to be pinned.  The RCU locking is not necessary
-	 * either.  It's just for the convenience of using cgroup_css().
-	 */
-	rcu_read_lock();
-	css = cgroup_css(cgrp, cft->ss);
-	rcu_read_unlock();
+			if (ret)
+				break;
+			continue;
+		}
 
-	if (cft->write_u64) {
-		unsigned long long v;
-		ret = kstrtoull(buf, 0, &v);
-		if (!ret)
-			ret = cft->write_u64(css, cft, v);
-	} else if (cft->write_s64) {
-		long long v;
-		ret = kstrtoll(buf, 0, &v);
-		if (!ret)
-			ret = cft->write_s64(css, cft, v);
-	} else {
-		ret = -EINVAL;
+		/*
+		 * kernfs guarantees that a file isn't deleted with operations
+		 * in flight, which means that the matching css is and stays
+		 * alive and doesn't need to be pinned.  The RCU locking is not
+		 * necessary either.  It's just for the convenience of using
+		 * cgroup_css().
+		 */
+		rcu_read_lock();
+		css = cgroup_css(cgrp, cft->ss);
+		rcu_read_unlock();
+
+		if (cft->write_u64) {
+			unsigned long long v;
+
+			ret = kstrtoull(buf, 0, &v);
+			if (!ret)
+				ret = cft->write_u64(css, cft, v);
+		} else if (cft->write_s64) {
+			long long v;
+
+			ret = kstrtoll(buf, 0, &v);
+			if (!ret)
+				ret = cft->write_s64(css, cft, v);
+		} else {
+			return -EINVAL;
+		}
 	}
 
 	return ret ?: nbytes;
@@ -3562,22 +3603,64 @@ static void cgroup_seqfile_stop(struct seq_file *seq, void *v)
 		seq_cft(seq)->seq_stop(seq, v);
 }
 
+/*
+ * A file shared by more cftypes may be showing different values. In that case
+ * call all the show functions and print the name of the owner that defined
+ * them.
+ */
 static int cgroup_seqfile_show(struct seq_file *m, void *arg)
 {
 	struct cftype *cft = seq_cft(m);
+	struct cftype *n;
 	struct cgroup_subsys_state *css = seq_css(m);
+	char *first_seqshow_str = NULL;
+	size_t first_str_size = 0;
+	size_t current_str_size = 0;
 	int ret = 0;
 
-	if (cft->seq_show)
-		ret = cft->seq_show(m, arg);
-	else if (cft->seq_show_cft)
-		ret = cft->seq_show_cft(m, cft, arg);
-	else if (cft->read_u64)
-		seq_printf(m, "%llu\n", cft->read_u64(css, cft));
-	else if (cft->read_s64)
-		seq_printf(m, "%lld\n", cft->read_s64(css, cft));
-	else
-		ret = -EINVAL;
+	list_for_each_cft(cft, n) {
+		if (cft->seq_show) {
+			ret = cft->seq_show(m, arg);
+			if (ret)
+				break;
+		} else if (cft->seq_show_cft) {
+			ret = cft->seq_show_cft(m, cft, arg);
+			if (ret)
+				break;
+		} else if (cft->read_u64) {
+			seq_printf(m, "%llu\n", cft->read_u64(css, cft));
+		} else if (cft->read_s64) {
+			seq_printf(m, "%lld\n", cft->read_s64(css, cft));
+		} else {
+			ret = -EINVAL;
+			break;
+		}
+		current_str_size = m->count - current_str_size;
+
+		if (first_seqshow_str == NULL) {
+			first_seqshow_str = kmalloc(m->size, GFP_KERNEL);
+			first_str_size = m->count;
+			strcpy(first_seqshow_str, m->buf);
+			first_str_size = m->count;
+		} else if (strcmp(first_seqshow_str,
+				  m->buf + m->count - current_str_size)) {
+			first_str_size = -1;
+		}
+
+		if (current_str_size) {
+			seq_printf(m, " - %s\n", cft->owner_name);
+			current_str_size = m->count;
+		}
+	}
+
+	/*
+	 * If all the cft->seqfile_show/read are equal, truncate the
+	 * output of the seqfile to the length of the first string.
+	 */
+	if (first_str_size != -1)
+		m->count = first_str_size;
+
+	kfree(first_seqshow_str);
 	return ret;
 }
 
-- 
2.16.1

  parent reply	other threads:[~2018-11-12  9:56 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-12  9:56 [PATCH 00/12] unify the interface of the proportional-share policy in blkio/io Paolo Valente
2018-11-12  9:56 ` [PATCH 01/12] kernfs: add function to find kernfs_node without increasing ref counter Paolo Valente
2018-11-12 12:28   ` Greg Kroah-Hartman
2018-11-13  1:56     ` Matthew Wilcox
2018-11-13 17:53     ` Paolo Valente
2018-11-13 19:35       ` Greg Kroah-Hartman
2018-11-12  9:56 ` [PATCH 02/12] cgroup: add hook seq_show_cft with also the owning cftype as parameter Paolo Valente
2018-11-12  9:56 ` [PATCH 03/12] block, cgroup: pass cftype to functions that need to use it Paolo Valente
2018-11-12  9:56 ` [PATCH 04/12] cgroup: link cftypes of the same subsystem with the same name Paolo Valente
2018-11-12  9:56 ` [PATCH 05/12] cgroup: add owner name to cftypes Paolo Valente
2018-11-12  9:56 ` [PATCH 06/12] block, bfq: align min and default weights with cfq Paolo Valente
2018-11-12  9:56 ` Paolo Valente [this message]
2018-11-12  9:56 ` [PATCH 08/12] block, cfq: allow cgroup files to be shared Paolo Valente
2018-11-12  9:56 ` [PATCH 09/12] block, bfq: use standard file names for the proportional-share policy Paolo Valente
2018-11-12  9:56 ` [PATCH 10/12] block, throttle: allow sharing cgroup statistic files Paolo Valente
2018-11-12  9:56 ` [PATCH 11/12] doc, bfq-iosched: fix a few clerical errors Paolo Valente
2018-11-12  9:56 ` [PATCH 12/12] doc, bfq-iosched: make it consistent with the new cgroup interface Paolo Valente
2018-11-12  9:58 ` [PATCH 00/12] unify the interface of the proportional-share policy in blkio/io Paolo Valente
2018-11-12  9:58   ` Paolo Valente
2018-11-12 10:00 ` Oleksandr Natalenko
2018-11-12 10:00   ` Oleksandr Natalenko
2018-11-12 10:14   ` Oleksandr Natalenko
2018-11-12 10:14     ` Oleksandr Natalenko
2018-11-12 10:17   ` Paolo Valente
2018-11-12 10:17     ` Paolo Valente
2018-11-12 10:17     ` Paolo Valente
2018-11-12 15:35     ` Jens Axboe
2018-11-12 15:35       ` Jens Axboe
2018-11-12 15:45       ` Paolo Valente
2018-11-12 15:45         ` Paolo Valente
2018-11-12 15:48         ` Jens Axboe
2018-11-12 15:54           ` Josef Bacik
2018-11-12 15:54             ` Josef Bacik
2018-11-12 16:05             ` Jens Axboe
2018-11-15 11:54       ` Angelo Ruocco
2018-11-15 11:54         ` Angelo Ruocco
     [not found]         ` <CADiTV-3tSpEMG7EHz3XGvfekNdtN8k_KQiDMtyykgOb81cvO0g@mail.gmail.com>
2018-11-15 15:42           ` Oleksandr Natalenko
2018-11-15 16:30         ` Jens Axboe
2018-11-15 16:30           ` Jens Axboe
2018-11-19  9:46           ` Angelo Ruocco
2018-11-19  9:46             ` Angelo Ruocco

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=20181112095632.69114-8-paolo.valente@linaro.org \
    --to=paolo.valente@linaro.org \
    --cc=angeloruocco90@gmail.com \
    --cc=axboe@kernel.dk \
    --cc=bfq-iosched@googlegroups.com \
    --cc=bo.liu@linux.alibaba.com \
    --cc=broonie@kernel.org \
    --cc=bvanassche@acm.org \
    --cc=cgroups@vger.kernel.org \
    --cc=corbet@lwn.net \
    --cc=dennis@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=hannes@cmpxchg.org \
    --cc=josef@toxicpanda.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lizefan@huawei.com \
    --cc=oleksandr@natalenko.name \
    --cc=tj@kernel.org \
    --cc=ulf.hansson@linaro.org \
    /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.