From: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
To: lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org
Cc: cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
Subject: [PATCH v2 6/6] cgroup: implement for_each_[builtin_]subsys()
Date: Mon, 24 Jun 2013 17:22:36 -0700 [thread overview]
Message-ID: <20130625002236.GU1918@mtj.dyndns.org> (raw)
In-Reply-To: <1371864854-28364-7-git-send-email-tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
There are quite a few places where all loaded [builtin] subsys are
iterated. Implement for_each_[builtin_]subsys() and replace manual
iterations with those to simplify those places a bit. The new
iterators automatically skip NULL subsystems. This shouldn't cause
any functional difference.
Iteration loops which scan all subsystems and then skipping modular
ones explicitly are converted to use for_each_builtin_subsys().
While at it, reorder variable declarations and adjust whitespaces a
bit in the affected functions.
v2: Add lockdep_assert_held() in for_each_subsys() and add comments
about synchronization as suggested by Li.
Signed-off-by: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
kernel/cgroup.c | 147 +++++++++++++++++++++++++++-----------------------------
1 file changed, 71 insertions(+), 76 deletions(-)
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -259,6 +259,31 @@ static int notify_on_release(const struc
return test_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags);
}
+/**
+ * for_each_subsys - iterate all loaded cgroup subsystems
+ * @ss: the iteration cursor
+ * @i: the index of @ss, CGROUP_SUBSYS_COUNT after reaching the end
+ *
+ * Should be called under cgroup_mutex.
+ */
+#define for_each_subsys(ss, i) \
+ for ((i) = 0; (i) < CGROUP_SUBSYS_COUNT; (i)++) \
+ if (({ lockdep_assert_held(&cgroup_mutex); \
+ !((ss) = cgroup_subsys[i]); })) { } \
+ else
+
+/**
+ * for_each_builtin_subsys - iterate all built-in cgroup subsystems
+ * @ss: the iteration cursor
+ * @i: the index of @ss, CGROUP_BUILTIN_SUBSYS_COUNT after reaching the end
+ *
+ * Bulit-in subsystems are always present and iteration itself doesn't
+ * require any synchronization.
+ */
+#define for_each_builtin_subsys(ss, i) \
+ for ((i) = 0; (i) < CGROUP_BUILTIN_SUBSYS_COUNT && \
+ (((ss) = cgroup_subsys[i]) || true); (i)++)
+
/* iterate each subsystem attached to a hierarchy */
#define for_each_root_subsys(root, ss) \
list_for_each_entry((ss), &(root)->subsys_list, sibling)
@@ -356,10 +381,11 @@ static DEFINE_HASHTABLE(css_set_table, C
static unsigned long css_set_hash(struct cgroup_subsys_state *css[])
{
- int i;
unsigned long key = 0UL;
+ struct cgroup_subsys *ss;
+ int i;
- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++)
+ for_each_subsys(ss, i)
key += (unsigned long)css[i];
key = (key >> 16) ^ key;
@@ -514,6 +540,7 @@ static struct css_set *find_existing_css
struct cgroup_subsys_state *template[])
{
struct cgroupfs_root *root = cgrp->root;
+ struct cgroup_subsys *ss;
struct css_set *cset;
unsigned long key;
int i;
@@ -523,7 +550,7 @@ static struct css_set *find_existing_css
* new css_set. while subsystems can change globally, the entries here
* won't change, so no need for locking.
*/
- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+ for_each_subsys(ss, i) {
if (root->subsys_mask & (1UL << i)) {
/* Subsystem is in this hierarchy. So we want
* the subsystem state from the new
@@ -982,23 +1009,19 @@ static int rebind_subsystems(struct cgro
unsigned long added_mask, unsigned removed_mask)
{
struct cgroup *cgrp = &root->top_cgroup;
+ struct cgroup_subsys *ss;
int i;
BUG_ON(!mutex_is_locked(&cgroup_mutex));
BUG_ON(!mutex_is_locked(&cgroup_root_mutex));
/* Check that any added subsystems are currently free */
- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+ for_each_subsys(ss, i) {
unsigned long bit = 1UL << i;
- struct cgroup_subsys *ss = cgroup_subsys[i];
+
if (!(bit & added_mask))
continue;
- /*
- * Nobody should tell us to do a subsys that doesn't exist:
- * parse_cgroupfs_options should catch that case and refcounts
- * ensure that subsystems won't disappear once selected.
- */
- BUG_ON(ss == NULL);
+
if (ss->root != &cgroup_dummy_root) {
/* Subsystem isn't free */
return -EBUSY;
@@ -1013,12 +1036,11 @@ static int rebind_subsystems(struct cgro
return -EBUSY;
/* Process each subsystem */
- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
- struct cgroup_subsys *ss = cgroup_subsys[i];
+ for_each_subsys(ss, i) {
unsigned long bit = 1UL << i;
+
if (bit & added_mask) {
/* We're binding this subsystem to this hierarchy */
- BUG_ON(ss == NULL);
BUG_ON(cgrp->subsys[i]);
BUG_ON(!cgroup_dummy_top->subsys[i]);
BUG_ON(cgroup_dummy_top->subsys[i]->cgroup != cgroup_dummy_top);
@@ -1034,7 +1056,6 @@ static int rebind_subsystems(struct cgro
root->subsys_mask |= bit;
} else if (bit & removed_mask) {
/* We're removing this subsystem */
- BUG_ON(ss == NULL);
BUG_ON(cgrp->subsys[i] != cgroup_dummy_top->subsys[i]);
BUG_ON(cgrp->subsys[i]->cgroup != cgrp);
@@ -1050,7 +1071,6 @@ static int rebind_subsystems(struct cgro
root->subsys_mask &= ~bit;
} else if (bit & root->subsys_mask) {
/* Subsystem state should already exist */
- BUG_ON(ss == NULL);
BUG_ON(!cgrp->subsys[i]);
/*
* a refcount was taken, but we already had one, so
@@ -1117,8 +1137,9 @@ static int parse_cgroupfs_options(char *
char *token, *o = data;
bool all_ss = false, one_ss = false;
unsigned long mask = (unsigned long)-1;
- int i;
bool module_pin_failed = false;
+ struct cgroup_subsys *ss;
+ int i;
BUG_ON(!mutex_is_locked(&cgroup_mutex));
@@ -1195,10 +1216,7 @@ static int parse_cgroupfs_options(char *
continue;
}
- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
- struct cgroup_subsys *ss = cgroup_subsys[i];
- if (ss == NULL)
- continue;
+ for_each_subsys(ss, i) {
if (strcmp(token, ss->name))
continue;
if (ss->disabled)
@@ -1221,16 +1239,10 @@ static int parse_cgroupfs_options(char *
* otherwise if 'none', 'name=' and a subsystem name options
* were not specified, let's default to 'all'
*/
- if (all_ss || (!one_ss && !opts->none && !opts->name)) {
- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
- struct cgroup_subsys *ss = cgroup_subsys[i];
- if (ss == NULL)
- continue;
- if (ss->disabled)
- continue;
- set_bit(i, &opts->subsys_mask);
- }
- }
+ if (all_ss || (!one_ss && !opts->none && !opts->name))
+ for_each_subsys(ss, i)
+ if (!ss->disabled)
+ set_bit(i, &opts->subsys_mask);
/* Consistency checks */
@@ -1274,10 +1286,8 @@ static int parse_cgroupfs_options(char *
* take duplicate reference counts on a subsystem that's already used,
* but rebind_subsystems handles this case.
*/
- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
- unsigned long bit = 1UL << i;
-
- if (!(bit & opts->subsys_mask))
+ for_each_subsys(ss, i) {
+ if (!(opts->subsys_mask & (1UL << i)))
continue;
if (!try_module_get(cgroup_subsys[i]->module)) {
module_pin_failed = true;
@@ -1306,11 +1316,11 @@ static int parse_cgroupfs_options(char *
static void drop_parsed_module_refcounts(unsigned long subsys_mask)
{
+ struct cgroup_subsys *ss;
int i;
- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
- unsigned long bit = 1UL << i;
- if (!(bit & subsys_mask))
+ for_each_subsys(ss, i) {
+ if (!(subsys_mask & (1UL << i)))
continue;
module_put(cgroup_subsys[i]->module);
}
@@ -4822,7 +4832,9 @@ EXPORT_SYMBOL_GPL(cgroup_unload_subsys);
*/
int __init cgroup_init_early(void)
{
+ struct cgroup_subsys *ss;
int i;
+
atomic_set(&init_css_set.refcount, 1);
INIT_LIST_HEAD(&init_css_set.cgrp_links);
INIT_LIST_HEAD(&init_css_set.tasks);
@@ -4837,13 +4849,8 @@ int __init cgroup_init_early(void)
list_add(&init_cgrp_cset_link.cset_link, &cgroup_dummy_top->cset_links);
list_add(&init_cgrp_cset_link.cgrp_link, &init_css_set.cgrp_links);
- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
- struct cgroup_subsys *ss = cgroup_subsys[i];
-
- /* at bootup time, we don't worry about modular subsystems */
- if (!ss || ss->module)
- continue;
-
+ /* at bootup time, we don't worry about modular subsystems */
+ for_each_builtin_subsys(ss, i) {
BUG_ON(!ss->name);
BUG_ON(strlen(ss->name) > MAX_CGROUP_TYPE_NAMELEN);
BUG_ON(!ss->css_alloc);
@@ -4868,20 +4875,15 @@ int __init cgroup_init_early(void)
*/
int __init cgroup_init(void)
{
- int err;
- int i;
+ struct cgroup_subsys *ss;
unsigned long key;
+ int i, err;
err = bdi_init(&cgroup_backing_dev_info);
if (err)
return err;
- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
- struct cgroup_subsys *ss = cgroup_subsys[i];
-
- /* at bootup time, we don't worry about modular subsystems */
- if (!ss || ss->module)
- continue;
+ for_each_builtin_subsys(ss, i) {
if (!ss->early_init)
cgroup_init_subsys(ss);
if (ss->use_id)
@@ -4990,6 +4992,7 @@ out:
/* Display information about each subsystem and each hierarchy */
static int proc_cgroupstats_show(struct seq_file *m, void *v)
{
+ struct cgroup_subsys *ss;
int i;
seq_puts(m, "#subsys_name\thierarchy\tnum_cgroups\tenabled\n");
@@ -4999,14 +5002,12 @@ static int proc_cgroupstats_show(struct
* subsys/hierarchy state.
*/
mutex_lock(&cgroup_mutex);
- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
- struct cgroup_subsys *ss = cgroup_subsys[i];
- if (ss == NULL)
- continue;
+
+ for_each_subsys(ss, i)
seq_printf(m, "%s\t%d\t%d\t%d\n",
ss->name, ss->root->hierarchy_id,
ss->root->number_of_cgroups, !ss->disabled);
- }
+
mutex_unlock(&cgroup_mutex);
return 0;
}
@@ -5060,6 +5061,7 @@ void cgroup_fork(struct task_struct *chi
*/
void cgroup_post_fork(struct task_struct *child)
{
+ struct cgroup_subsys *ss;
int i;
/*
@@ -5096,12 +5098,9 @@ void cgroup_post_fork(struct task_struct
* of the array can be freed at module unload, so we
* can't touch that.
*/
- for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) {
- struct cgroup_subsys *ss = cgroup_subsys[i];
-
+ for_each_builtin_subsys(ss, i)
if (ss->fork)
ss->fork(child);
- }
}
}
@@ -5142,6 +5141,7 @@ void cgroup_post_fork(struct task_struct
*/
void cgroup_exit(struct task_struct *tsk, int run_callbacks)
{
+ struct cgroup_subsys *ss;
struct css_set *cset;
int i;
@@ -5167,13 +5167,12 @@ void cgroup_exit(struct task_struct *tsk
* fork/exit callbacks are supported only for builtin
* subsystems, see cgroup_post_fork() for details.
*/
- for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) {
- struct cgroup_subsys *ss = cgroup_subsys[i];
-
+ for_each_builtin_subsys(ss, i) {
if (ss->exit) {
struct cgroup *old_cgrp =
rcu_dereference_raw(cset->subsys[i])->cgroup;
struct cgroup *cgrp = task_cgroup(tsk, i);
+
ss->exit(cgrp, old_cgrp, tsk);
}
}
@@ -5280,23 +5279,19 @@ static void cgroup_release_agent(struct
static int __init cgroup_disable(char *str)
{
- int i;
+ struct cgroup_subsys *ss;
char *token;
+ int i;
while ((token = strsep(&str, ",")) != NULL) {
if (!*token)
continue;
- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
- struct cgroup_subsys *ss = cgroup_subsys[i];
-
- /*
- * cgroup_disable, being at boot time, can't
- * know about module subsystems, so we don't
- * worry about them.
- */
- if (!ss || ss->module)
- continue;
+ /*
+ * cgroup_disable, being at boot time, can't know about
+ * module subsystems, so we don't worry about them.
+ */
+ for_each_builtin_subsys(ss, i) {
if (!strcmp(token, ss->name)) {
ss->disabled = 1;
printk(KERN_INFO "Disabling %s control group"
next prev parent reply other threads:[~2013-06-25 0:22 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-06-22 1:34 [PATCHSET cgroup/for-3.11] cgroup: miscellaneous cleanups Tejun Heo
[not found] ` <1371864854-28364-1-git-send-email-tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2013-06-22 1:34 ` [PATCH 1/6] cgroup: convert CFTYPE_* flags to enums Tejun Heo
[not found] ` <1371864854-28364-2-git-send-email-tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2013-06-24 10:21 ` Li Zefan
2013-06-22 1:34 ` [PATCH 2/6] cgroup: prefix global variables with "cgroup_" Tejun Heo
[not found] ` <1371864854-28364-3-git-send-email-tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2013-06-24 10:22 ` Li Zefan
2013-06-22 1:34 ` [PATCH 3/6] cgroup: remove cgroup->actual_subsys_mask Tejun Heo
[not found] ` <1371864854-28364-4-git-send-email-tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2013-06-24 10:26 ` Li Zefan
2013-06-24 22:30 ` [PATCH v2 " Tejun Heo
2013-06-22 1:34 ` [PATCH 4/6] cgroup: clean up find_css_set() and friends Tejun Heo
[not found] ` <1371864854-28364-5-git-send-email-tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2013-06-24 10:33 ` Li Zefan
[not found] ` <51C8206F.90404-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
2013-06-24 20:03 ` Tejun Heo
2013-06-22 1:34 ` [PATCH 5/6] cgroup: s/for_each_subsys()/for_each_root_subsys()/ Tejun Heo
[not found] ` <1371864854-28364-6-git-send-email-tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2013-06-24 10:52 ` Li Zefan
2013-06-22 1:34 ` [PATCH 6/6] cgroup: implement for_each_[builtin_]subsys() Tejun Heo
[not found] ` <1371864854-28364-7-git-send-email-tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2013-06-24 10:50 ` Li Zefan
[not found] ` <51C82482.9020902-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
2013-06-24 20:04 ` Tejun Heo
2013-06-25 0:22 ` Tejun Heo [this message]
[not found] ` <20130625002236.GU1918-9pTldWuhBndy/B6EtB590w@public.gmane.org>
2013-06-25 1:35 ` [PATCH v2 " Li Zefan
[not found] ` <51C8F3EB.4090106-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
2013-06-25 18:42 ` Tejun Heo
2013-06-24 22:32 ` [PATCHSET cgroup/for-3.11] cgroup: miscellaneous cleanups Tejun Heo
2013-06-25 0:34 ` [PATCH 5.5/6] cgroup: move init_css_set initialization inside cgroup_mutex Tejun Heo
[not found] ` <20130625003434.GV1918-9pTldWuhBndy/B6EtB590w@public.gmane.org>
2013-06-25 1:36 ` Li Zefan
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=20130625002236.GU1918@mtj.dyndns.org \
--to=tj-dgejt+ai2ygdnm+yrofe0a@public.gmane.org \
--cc=cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org \
--cc=lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).