Merge branch 'for-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
Pull cgroup updates from Tejun Heo: - tracepoints for basic cgroup management operations added - kernfs and cgroup path formatting functions updated to behave in the style of strlcpy() - non-critical bug fixes * 'for-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup: blkcg: Unlock blkcg_pol_mutex only once when cpd == NULL cgroup: fix error handling regressions in proc_cgroup_show() and cgroup_release_agent() cpuset: fix error handling regression in proc_cpuset_show() cgroup: add tracepoints for basic operations cgroup: make cgroup_path() and friends behave in the style of strlcpy() kernfs: remove kernfs_path_len() kernfs: make kernfs_path*() behave in the style of strlcpy() kernfs: add dummy implementation of kernfs_path_from_node()
This commit is contained in:
@@ -64,6 +64,9 @@
|
||||
#include <linux/file.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/cgroup.h>
|
||||
|
||||
/*
|
||||
* pidlists linger the following amount before being destroyed. The goal
|
||||
* is avoiding frequent destruction in the middle of consecutive read calls
|
||||
@@ -1176,6 +1179,8 @@ static void cgroup_destroy_root(struct cgroup_root *root)
|
||||
struct cgroup *cgrp = &root->cgrp;
|
||||
struct cgrp_cset_link *link, *tmp_link;
|
||||
|
||||
trace_cgroup_destroy_root(root);
|
||||
|
||||
cgroup_lock_and_drain_offline(&cgrp_dfl_root.cgrp);
|
||||
|
||||
BUG_ON(atomic_read(&root->nr_cgrps));
|
||||
@@ -1874,6 +1879,9 @@ static int cgroup_remount(struct kernfs_root *kf_root, int *flags, char *data)
|
||||
strcpy(root->release_agent_path, opts.release_agent);
|
||||
spin_unlock(&release_agent_path_lock);
|
||||
}
|
||||
|
||||
trace_cgroup_remount(root);
|
||||
|
||||
out_unlock:
|
||||
kfree(opts.release_agent);
|
||||
kfree(opts.name);
|
||||
@@ -2031,6 +2039,8 @@ static int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask)
|
||||
if (ret)
|
||||
goto destroy_root;
|
||||
|
||||
trace_cgroup_setup_root(root);
|
||||
|
||||
/*
|
||||
* There must be no failure case after here, since rebinding takes
|
||||
* care of subsystems' refcounts, which are explicitly dropped in
|
||||
@@ -2315,22 +2325,18 @@ static struct file_system_type cgroup2_fs_type = {
|
||||
.fs_flags = FS_USERNS_MOUNT,
|
||||
};
|
||||
|
||||
static char *cgroup_path_ns_locked(struct cgroup *cgrp, char *buf, size_t buflen,
|
||||
struct cgroup_namespace *ns)
|
||||
static int cgroup_path_ns_locked(struct cgroup *cgrp, char *buf, size_t buflen,
|
||||
struct cgroup_namespace *ns)
|
||||
{
|
||||
struct cgroup *root = cset_cgroup_from_root(ns->root_cset, cgrp->root);
|
||||
int ret;
|
||||
|
||||
ret = kernfs_path_from_node(cgrp->kn, root->kn, buf, buflen);
|
||||
if (ret < 0 || ret >= buflen)
|
||||
return NULL;
|
||||
return buf;
|
||||
return kernfs_path_from_node(cgrp->kn, root->kn, buf, buflen);
|
||||
}
|
||||
|
||||
char *cgroup_path_ns(struct cgroup *cgrp, char *buf, size_t buflen,
|
||||
struct cgroup_namespace *ns)
|
||||
int cgroup_path_ns(struct cgroup *cgrp, char *buf, size_t buflen,
|
||||
struct cgroup_namespace *ns)
|
||||
{
|
||||
char *ret;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&cgroup_mutex);
|
||||
spin_lock_irq(&css_set_lock);
|
||||
@@ -2357,12 +2363,12 @@ EXPORT_SYMBOL_GPL(cgroup_path_ns);
|
||||
*
|
||||
* Return value is the same as kernfs_path().
|
||||
*/
|
||||
char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen)
|
||||
int task_cgroup_path(struct task_struct *task, char *buf, size_t buflen)
|
||||
{
|
||||
struct cgroup_root *root;
|
||||
struct cgroup *cgrp;
|
||||
int hierarchy_id = 1;
|
||||
char *path = NULL;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&cgroup_mutex);
|
||||
spin_lock_irq(&css_set_lock);
|
||||
@@ -2371,16 +2377,15 @@ char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen)
|
||||
|
||||
if (root) {
|
||||
cgrp = task_cgroup_from_root(task, root);
|
||||
path = cgroup_path_ns_locked(cgrp, buf, buflen, &init_cgroup_ns);
|
||||
ret = cgroup_path_ns_locked(cgrp, buf, buflen, &init_cgroup_ns);
|
||||
} else {
|
||||
/* if no hierarchy exists, everyone is in "/" */
|
||||
if (strlcpy(buf, "/", buflen) < buflen)
|
||||
path = buf;
|
||||
ret = strlcpy(buf, "/", buflen);
|
||||
}
|
||||
|
||||
spin_unlock_irq(&css_set_lock);
|
||||
mutex_unlock(&cgroup_mutex);
|
||||
return path;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(task_cgroup_path);
|
||||
|
||||
@@ -2830,6 +2835,10 @@ static int cgroup_attach_task(struct cgroup *dst_cgrp,
|
||||
ret = cgroup_migrate(leader, threadgroup, dst_cgrp->root);
|
||||
|
||||
cgroup_migrate_finish(&preloaded_csets);
|
||||
|
||||
if (!ret)
|
||||
trace_cgroup_attach_task(dst_cgrp, leader, threadgroup);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3611,6 +3620,8 @@ static int cgroup_rename(struct kernfs_node *kn, struct kernfs_node *new_parent,
|
||||
mutex_lock(&cgroup_mutex);
|
||||
|
||||
ret = kernfs_rename(kn, new_parent, new_name_str);
|
||||
if (!ret)
|
||||
trace_cgroup_rename(cgrp);
|
||||
|
||||
mutex_unlock(&cgroup_mutex);
|
||||
|
||||
@@ -4381,6 +4392,8 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from)
|
||||
|
||||
if (task) {
|
||||
ret = cgroup_migrate(task, false, to->root);
|
||||
if (!ret)
|
||||
trace_cgroup_transfer_tasks(to, task, false);
|
||||
put_task_struct(task);
|
||||
}
|
||||
} while (task && !ret);
|
||||
@@ -5046,6 +5059,8 @@ static void css_release_work_fn(struct work_struct *work)
|
||||
ss->css_released(css);
|
||||
} else {
|
||||
/* cgroup release path */
|
||||
trace_cgroup_release(cgrp);
|
||||
|
||||
cgroup_idr_remove(&cgrp->root->cgroup_idr, cgrp->id);
|
||||
cgrp->id = -1;
|
||||
|
||||
@@ -5332,6 +5347,8 @@ static int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name,
|
||||
if (ret)
|
||||
goto out_destroy;
|
||||
|
||||
trace_cgroup_mkdir(cgrp);
|
||||
|
||||
/* let's create and online css's */
|
||||
kernfs_activate(kn);
|
||||
|
||||
@@ -5507,6 +5524,9 @@ static int cgroup_rmdir(struct kernfs_node *kn)
|
||||
|
||||
ret = cgroup_destroy_locked(cgrp);
|
||||
|
||||
if (!ret)
|
||||
trace_cgroup_rmdir(cgrp);
|
||||
|
||||
cgroup_kn_unlock(kn);
|
||||
return ret;
|
||||
}
|
||||
@@ -5743,7 +5763,7 @@ core_initcall(cgroup_wq_init);
|
||||
int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns,
|
||||
struct pid *pid, struct task_struct *tsk)
|
||||
{
|
||||
char *buf, *path;
|
||||
char *buf;
|
||||
int retval;
|
||||
struct cgroup_root *root;
|
||||
|
||||
@@ -5786,17 +5806,17 @@ int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns,
|
||||
* " (deleted)" is appended to the cgroup path.
|
||||
*/
|
||||
if (cgroup_on_dfl(cgrp) || !(tsk->flags & PF_EXITING)) {
|
||||
path = cgroup_path_ns_locked(cgrp, buf, PATH_MAX,
|
||||
retval = cgroup_path_ns_locked(cgrp, buf, PATH_MAX,
|
||||
current->nsproxy->cgroup_ns);
|
||||
if (!path) {
|
||||
if (retval >= PATH_MAX)
|
||||
retval = -ENAMETOOLONG;
|
||||
if (retval < 0)
|
||||
goto out_unlock;
|
||||
}
|
||||
} else {
|
||||
path = "/";
|
||||
}
|
||||
|
||||
seq_puts(m, path);
|
||||
seq_puts(m, buf);
|
||||
} else {
|
||||
seq_puts(m, "/");
|
||||
}
|
||||
|
||||
if (cgroup_on_dfl(cgrp) && cgroup_is_dead(cgrp))
|
||||
seq_puts(m, " (deleted)\n");
|
||||
@@ -6062,8 +6082,9 @@ static void cgroup_release_agent(struct work_struct *work)
|
||||
{
|
||||
struct cgroup *cgrp =
|
||||
container_of(work, struct cgroup, release_agent_work);
|
||||
char *pathbuf = NULL, *agentbuf = NULL, *path;
|
||||
char *pathbuf = NULL, *agentbuf = NULL;
|
||||
char *argv[3], *envp[3];
|
||||
int ret;
|
||||
|
||||
mutex_lock(&cgroup_mutex);
|
||||
|
||||
@@ -6073,13 +6094,13 @@ static void cgroup_release_agent(struct work_struct *work)
|
||||
goto out;
|
||||
|
||||
spin_lock_irq(&css_set_lock);
|
||||
path = cgroup_path_ns_locked(cgrp, pathbuf, PATH_MAX, &init_cgroup_ns);
|
||||
ret = cgroup_path_ns_locked(cgrp, pathbuf, PATH_MAX, &init_cgroup_ns);
|
||||
spin_unlock_irq(&css_set_lock);
|
||||
if (!path)
|
||||
if (ret < 0 || ret >= PATH_MAX)
|
||||
goto out;
|
||||
|
||||
argv[0] = agentbuf;
|
||||
argv[1] = path;
|
||||
argv[1] = pathbuf;
|
||||
argv[2] = NULL;
|
||||
|
||||
/* minimal command environment */
|
||||
|
@@ -2715,7 +2715,7 @@ void __cpuset_memory_pressure_bump(void)
|
||||
int proc_cpuset_show(struct seq_file *m, struct pid_namespace *ns,
|
||||
struct pid *pid, struct task_struct *tsk)
|
||||
{
|
||||
char *buf, *p;
|
||||
char *buf;
|
||||
struct cgroup_subsys_state *css;
|
||||
int retval;
|
||||
|
||||
@@ -2724,14 +2724,15 @@ int proc_cpuset_show(struct seq_file *m, struct pid_namespace *ns,
|
||||
if (!buf)
|
||||
goto out;
|
||||
|
||||
retval = -ENAMETOOLONG;
|
||||
css = task_get_css(tsk, cpuset_cgrp_id);
|
||||
p = cgroup_path_ns(css->cgroup, buf, PATH_MAX,
|
||||
current->nsproxy->cgroup_ns);
|
||||
retval = cgroup_path_ns(css->cgroup, buf, PATH_MAX,
|
||||
current->nsproxy->cgroup_ns);
|
||||
css_put(css);
|
||||
if (!p)
|
||||
if (retval >= PATH_MAX)
|
||||
retval = -ENAMETOOLONG;
|
||||
if (retval < 0)
|
||||
goto out_free;
|
||||
seq_puts(m, p);
|
||||
seq_puts(m, buf);
|
||||
seq_putc(m, '\n');
|
||||
retval = 0;
|
||||
out_free:
|
||||
|
@@ -415,7 +415,8 @@ static char *task_group_path(struct task_group *tg)
|
||||
if (autogroup_path(tg, group_path, PATH_MAX))
|
||||
return group_path;
|
||||
|
||||
return cgroup_path(tg->css.cgroup, group_path, PATH_MAX);
|
||||
cgroup_path(tg->css.cgroup, group_path, PATH_MAX);
|
||||
return group_path;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user