Merge branch 'for-3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
Pull cgroup updates from Tejun Heo:
"The bulk of changes are cleanups and preparations for the upcoming
kernfs conversion.
- cgroup_event mechanism which is and will be used only by memcg is
moved to memcg.
- pidlist handling is updated so that it can be served by seq_file.
Also, the list is not sorted if sane_behavior. cgroup
documentation explicitly states that the file is not sorted but it
has been for quite some time.
- All cgroup file handling now happens on top of seq_file. This is
to prepare for kernfs conversion. In addition, all operations are
restructured so that they map 1-1 to kernfs operations.
- Other cleanups and low-pri fixes"
* 'for-3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup: (40 commits)
cgroup: trivial style updates
cgroup: remove stray references to css_id
doc: cgroups: Fix typo in doc/cgroups
cgroup: fix fail path in cgroup_load_subsys()
cgroup: fix missing unlock on error in cgroup_load_subsys()
cgroup: remove for_each_root_subsys()
cgroup: implement for_each_css()
cgroup: factor out cgroup_subsys_state creation into create_css()
cgroup: combine css handling loops in cgroup_create()
cgroup: reorder operations in cgroup_create()
cgroup: make for_each_subsys() useable under cgroup_root_mutex
cgroup: css iterations and css_from_dir() are safe under cgroup_mutex
cgroup: unify pidlist and other file handling
cgroup: replace cftype->read_seq_string() with cftype->seq_show()
cgroup: attach cgroup_open_file to all cgroup files
cgroup: generalize cgroup_pidlist_open_file
cgroup: unify read path so that seq_file is always used
cgroup: unify cgroup_write_X64() and cgroup_write_string()
cgroup: remove cftype->read(), ->read_map() and ->write()
hugetlb_cgroup: convert away from cftype->read()
...
This commit is contained in:
+485
-727
File diff suppressed because it is too large
Load Diff
@@ -301,10 +301,9 @@ out_unlock:
|
||||
spin_unlock_irq(&freezer->lock);
|
||||
}
|
||||
|
||||
static int freezer_read(struct cgroup_subsys_state *css, struct cftype *cft,
|
||||
struct seq_file *m)
|
||||
static int freezer_read(struct seq_file *m, void *v)
|
||||
{
|
||||
struct cgroup_subsys_state *pos;
|
||||
struct cgroup_subsys_state *css = seq_css(m), *pos;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
@@ -458,7 +457,7 @@ static struct cftype files[] = {
|
||||
{
|
||||
.name = "state",
|
||||
.flags = CFTYPE_NOT_ON_ROOT,
|
||||
.read_seq_string = freezer_read,
|
||||
.seq_show = freezer_read,
|
||||
.write_string = freezer_write,
|
||||
},
|
||||
{
|
||||
|
||||
+24
-49
@@ -1731,66 +1731,41 @@ out_unlock:
|
||||
* used, list of ranges of sequential numbers, is variable length,
|
||||
* and since these maps can change value dynamically, one could read
|
||||
* gibberish by doing partial reads while a list was changing.
|
||||
* A single large read to a buffer that crosses a page boundary is
|
||||
* ok, because the result being copied to user land is not recomputed
|
||||
* across a page fault.
|
||||
*/
|
||||
|
||||
static size_t cpuset_sprintf_cpulist(char *page, struct cpuset *cs)
|
||||
static int cpuset_common_seq_show(struct seq_file *sf, void *v)
|
||||
{
|
||||
size_t count;
|
||||
struct cpuset *cs = css_cs(seq_css(sf));
|
||||
cpuset_filetype_t type = seq_cft(sf)->private;
|
||||
ssize_t count;
|
||||
char *buf, *s;
|
||||
int ret = 0;
|
||||
|
||||
count = seq_get_buf(sf, &buf);
|
||||
s = buf;
|
||||
|
||||
mutex_lock(&callback_mutex);
|
||||
count = cpulist_scnprintf(page, PAGE_SIZE, cs->cpus_allowed);
|
||||
mutex_unlock(&callback_mutex);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static size_t cpuset_sprintf_memlist(char *page, struct cpuset *cs)
|
||||
{
|
||||
size_t count;
|
||||
|
||||
mutex_lock(&callback_mutex);
|
||||
count = nodelist_scnprintf(page, PAGE_SIZE, cs->mems_allowed);
|
||||
mutex_unlock(&callback_mutex);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t cpuset_common_file_read(struct cgroup_subsys_state *css,
|
||||
struct cftype *cft, struct file *file,
|
||||
char __user *buf, size_t nbytes,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct cpuset *cs = css_cs(css);
|
||||
cpuset_filetype_t type = cft->private;
|
||||
char *page;
|
||||
ssize_t retval = 0;
|
||||
char *s;
|
||||
|
||||
if (!(page = (char *)__get_free_page(GFP_TEMPORARY)))
|
||||
return -ENOMEM;
|
||||
|
||||
s = page;
|
||||
|
||||
switch (type) {
|
||||
case FILE_CPULIST:
|
||||
s += cpuset_sprintf_cpulist(s, cs);
|
||||
s += cpulist_scnprintf(s, count, cs->cpus_allowed);
|
||||
break;
|
||||
case FILE_MEMLIST:
|
||||
s += cpuset_sprintf_memlist(s, cs);
|
||||
s += nodelist_scnprintf(s, count, cs->mems_allowed);
|
||||
break;
|
||||
default:
|
||||
retval = -EINVAL;
|
||||
goto out;
|
||||
ret = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
*s++ = '\n';
|
||||
|
||||
retval = simple_read_from_buffer(buf, nbytes, ppos, page, s - page);
|
||||
out:
|
||||
free_page((unsigned long)page);
|
||||
return retval;
|
||||
if (s < buf + count - 1) {
|
||||
*s++ = '\n';
|
||||
seq_commit(sf, s - buf);
|
||||
} else {
|
||||
seq_commit(sf, -1);
|
||||
}
|
||||
out_unlock:
|
||||
mutex_unlock(&callback_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u64 cpuset_read_u64(struct cgroup_subsys_state *css, struct cftype *cft)
|
||||
@@ -1847,7 +1822,7 @@ static s64 cpuset_read_s64(struct cgroup_subsys_state *css, struct cftype *cft)
|
||||
static struct cftype files[] = {
|
||||
{
|
||||
.name = "cpus",
|
||||
.read = cpuset_common_file_read,
|
||||
.seq_show = cpuset_common_seq_show,
|
||||
.write_string = cpuset_write_resmask,
|
||||
.max_write_len = (100U + 6 * NR_CPUS),
|
||||
.private = FILE_CPULIST,
|
||||
@@ -1855,7 +1830,7 @@ static struct cftype files[] = {
|
||||
|
||||
{
|
||||
.name = "mems",
|
||||
.read = cpuset_common_file_read,
|
||||
.seq_show = cpuset_common_seq_show,
|
||||
.write_string = cpuset_write_resmask,
|
||||
.max_write_len = (100U + 6 * MAX_NUMNODES),
|
||||
.private = FILE_MEMLIST,
|
||||
|
||||
+6
-7
@@ -7852,15 +7852,14 @@ static int __cfs_schedulable(struct task_group *tg, u64 period, u64 quota)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cpu_stats_show(struct cgroup_subsys_state *css, struct cftype *cft,
|
||||
struct cgroup_map_cb *cb)
|
||||
static int cpu_stats_show(struct seq_file *sf, void *v)
|
||||
{
|
||||
struct task_group *tg = css_tg(css);
|
||||
struct task_group *tg = css_tg(seq_css(sf));
|
||||
struct cfs_bandwidth *cfs_b = &tg->cfs_bandwidth;
|
||||
|
||||
cb->fill(cb, "nr_periods", cfs_b->nr_periods);
|
||||
cb->fill(cb, "nr_throttled", cfs_b->nr_throttled);
|
||||
cb->fill(cb, "throttled_time", cfs_b->throttled_time);
|
||||
seq_printf(sf, "nr_periods %d\n", cfs_b->nr_periods);
|
||||
seq_printf(sf, "nr_throttled %d\n", cfs_b->nr_throttled);
|
||||
seq_printf(sf, "throttled_time %llu\n", cfs_b->throttled_time);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -7914,7 +7913,7 @@ static struct cftype cpu_files[] = {
|
||||
},
|
||||
{
|
||||
.name = "stat",
|
||||
.read_map = cpu_stats_show,
|
||||
.seq_show = cpu_stats_show,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_RT_GROUP_SCHED
|
||||
|
||||
+8
-10
@@ -163,10 +163,9 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int cpuacct_percpu_seq_read(struct cgroup_subsys_state *css,
|
||||
struct cftype *cft, struct seq_file *m)
|
||||
static int cpuacct_percpu_seq_show(struct seq_file *m, void *V)
|
||||
{
|
||||
struct cpuacct *ca = css_ca(css);
|
||||
struct cpuacct *ca = css_ca(seq_css(m));
|
||||
u64 percpu;
|
||||
int i;
|
||||
|
||||
@@ -183,10 +182,9 @@ static const char * const cpuacct_stat_desc[] = {
|
||||
[CPUACCT_STAT_SYSTEM] = "system",
|
||||
};
|
||||
|
||||
static int cpuacct_stats_show(struct cgroup_subsys_state *css,
|
||||
struct cftype *cft, struct cgroup_map_cb *cb)
|
||||
static int cpuacct_stats_show(struct seq_file *sf, void *v)
|
||||
{
|
||||
struct cpuacct *ca = css_ca(css);
|
||||
struct cpuacct *ca = css_ca(seq_css(sf));
|
||||
int cpu;
|
||||
s64 val = 0;
|
||||
|
||||
@@ -196,7 +194,7 @@ static int cpuacct_stats_show(struct cgroup_subsys_state *css,
|
||||
val += kcpustat->cpustat[CPUTIME_NICE];
|
||||
}
|
||||
val = cputime64_to_clock_t(val);
|
||||
cb->fill(cb, cpuacct_stat_desc[CPUACCT_STAT_USER], val);
|
||||
seq_printf(sf, "%s %lld\n", cpuacct_stat_desc[CPUACCT_STAT_USER], val);
|
||||
|
||||
val = 0;
|
||||
for_each_online_cpu(cpu) {
|
||||
@@ -207,7 +205,7 @@ static int cpuacct_stats_show(struct cgroup_subsys_state *css,
|
||||
}
|
||||
|
||||
val = cputime64_to_clock_t(val);
|
||||
cb->fill(cb, cpuacct_stat_desc[CPUACCT_STAT_SYSTEM], val);
|
||||
seq_printf(sf, "%s %lld\n", cpuacct_stat_desc[CPUACCT_STAT_SYSTEM], val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -220,11 +218,11 @@ static struct cftype files[] = {
|
||||
},
|
||||
{
|
||||
.name = "usage_percpu",
|
||||
.read_seq_string = cpuacct_percpu_seq_read,
|
||||
.seq_show = cpuacct_percpu_seq_show,
|
||||
},
|
||||
{
|
||||
.name = "stat",
|
||||
.read_map = cpuacct_stats_show,
|
||||
.seq_show = cpuacct_stats_show,
|
||||
},
|
||||
{ } /* terminate */
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user