diff options
Diffstat (limited to 'kernel/cgroup/debug.c')
| -rw-r--r-- | kernel/cgroup/debug.c | 53 | 
1 files changed, 39 insertions, 14 deletions
| diff --git a/kernel/cgroup/debug.c b/kernel/cgroup/debug.c index dac46af22782..f661b4cc5efd 100644 --- a/kernel/cgroup/debug.c +++ b/kernel/cgroup/debug.c @@ -114,27 +114,49 @@ static int cgroup_css_links_read(struct seq_file *seq, void *v)  {  	struct cgroup_subsys_state *css = seq_css(seq);  	struct cgrp_cset_link *link; -	int dead_cnt = 0, extra_refs = 0; +	int dead_cnt = 0, extra_refs = 0, threaded_csets = 0;  	spin_lock_irq(&css_set_lock); +  	list_for_each_entry(link, &css->cgroup->cset_links, cset_link) {  		struct css_set *cset = link->cset;  		struct task_struct *task;  		int count = 0;  		int refcnt = refcount_read(&cset->refcount); -		seq_printf(seq, " %d", refcnt); -		if (refcnt - cset->nr_tasks > 0) { -			int extra = refcnt - cset->nr_tasks; - -			seq_printf(seq, " +%d", extra); -			/* -			 * Take out the one additional reference in -			 * init_css_set. -			 */ -			if (cset == &init_css_set) -				extra--; -			extra_refs += extra; +		/* +		 * Print out the proc_cset and threaded_cset relationship +		 * and highlight difference between refcount and task_count. +		 */ +		seq_printf(seq, "css_set %pK", cset); +		if (rcu_dereference_protected(cset->dom_cset, 1) != cset) { +			threaded_csets++; +			seq_printf(seq, "=>%pK", cset->dom_cset); +		} +		if (!list_empty(&cset->threaded_csets)) { +			struct css_set *tcset; +			int idx = 0; + +			list_for_each_entry(tcset, &cset->threaded_csets, +					    threaded_csets_node) { +				seq_puts(seq, idx ? "," : "<="); +				seq_printf(seq, "%pK", tcset); +				idx++; +			} +		} else { +			seq_printf(seq, " %d", refcnt); +			if (refcnt - cset->nr_tasks > 0) { +				int extra = refcnt - cset->nr_tasks; + +				seq_printf(seq, " +%d", extra); +				/* +				 * Take out the one additional reference in +				 * init_css_set. +				 */ +				if (cset == &init_css_set) +					extra--; +				extra_refs += extra; +			}  		}  		seq_puts(seq, "\n"); @@ -163,10 +185,12 @@ static int cgroup_css_links_read(struct seq_file *seq, void *v)  	}  	spin_unlock_irq(&css_set_lock); -	if (!dead_cnt && !extra_refs) +	if (!dead_cnt && !extra_refs && !threaded_csets)  		return 0;  	seq_puts(seq, "\n"); +	if (threaded_csets) +		seq_printf(seq, "threaded css_sets = %d\n", threaded_csets);  	if (extra_refs)  		seq_printf(seq, "extra references = %d\n", extra_refs);  	if (dead_cnt) @@ -352,6 +376,7 @@ static int __init enable_cgroup_debug(char *str)  {  	debug_cgrp_subsys.dfl_cftypes = debug_files;  	debug_cgrp_subsys.implicit_on_dfl = true; +	debug_cgrp_subsys.threaded = true;  	return 1;  }  __setup("cgroup_debug", enable_cgroup_debug); |