Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e76ecaee authored by Tejun Heo's avatar Tejun Heo
Browse files

cgroup: use cgroup_kn_lock_live() in other cgroup kernfs methods



Make __cgroup_procs_write() and cgroup_release_agent_write() use
cgroup_kn_lock_live() and cgroup_kn_unlock() instead of
cgroup_lock_live_group().  This puts the operations under both
cgroup_tree_mutex and cgroup_mutex protection without circular
dependency from kernfs active protection.  Also, this means that
cgroup_mutex is no longer nested below kernfs active protection.
There is no longer any place where the two locks interact.

This leaves cgroup_lock_live_group() without any user.  Removed.

This will help simplifying cgroup locking.

Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Acked-by: default avatarLi Zefan <lizefan@huawei.com>
parent a9746d8d
Loading
Loading
Loading
Loading
+12 −27
Original line number Diff line number Diff line
@@ -386,23 +386,6 @@ static int notify_on_release(const struct cgroup *cgrp)
			;						\
		else

/**
 * cgroup_lock_live_group - take cgroup_mutex and check that cgrp is alive.
 * @cgrp: the cgroup to be checked for liveness
 *
 * On success, returns true; the mutex should be later unlocked.  On
 * failure returns false with no lock held.
 */
static bool cgroup_lock_live_group(struct cgroup *cgrp)
{
	mutex_lock(&cgroup_mutex);
	if (cgroup_is_dead(cgrp)) {
		mutex_unlock(&cgroup_mutex);
		return false;
	}
	return true;
}

/* the list of cgroups eligible for automatic release. Protected by
 * release_list_lock */
static LIST_HEAD(release_list);
@@ -2306,14 +2289,15 @@ static ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf,
{
	struct task_struct *tsk;
	const struct cred *cred = current_cred(), *tcred;
	struct cgroup *cgrp = of_css(of)->cgroup;
	struct cgroup *cgrp;
	pid_t pid;
	int ret;

	if (kstrtoint(strstrip(buf), 0, &pid) || pid < 0)
		return -EINVAL;

	if (!cgroup_lock_live_group(cgrp))
	cgrp = cgroup_kn_lock_live(of->kn);
	if (!cgrp)
		return -ENODEV;

retry_find_task:
@@ -2379,7 +2363,7 @@ static ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf,

	put_task_struct(tsk);
out_unlock_cgroup:
	mutex_unlock(&cgroup_mutex);
	cgroup_kn_unlock(of->kn);
	return ret ?: nbytes;
}

@@ -2429,17 +2413,18 @@ static ssize_t cgroup_procs_write(struct kernfs_open_file *of,
static ssize_t cgroup_release_agent_write(struct kernfs_open_file *of,
					  char *buf, size_t nbytes, loff_t off)
{
	struct cgroup *cgrp = of_css(of)->cgroup;
	struct cgroup_root *root = cgrp->root;
	struct cgroup *cgrp;

	BUILD_BUG_ON(sizeof(root->release_agent_path) < PATH_MAX);
	if (!cgroup_lock_live_group(cgrp))
	BUILD_BUG_ON(sizeof(cgrp->root->release_agent_path) < PATH_MAX);

	cgrp = cgroup_kn_lock_live(of->kn);
	if (!cgrp)
		return -ENODEV;
	spin_lock(&release_agent_path_lock);
	strlcpy(root->release_agent_path, strstrip(buf),
		sizeof(root->release_agent_path));
	strlcpy(cgrp->root->release_agent_path, strstrip(buf),
		sizeof(cgrp->root->release_agent_path));
	spin_unlock(&release_agent_path_lock);
	mutex_unlock(&cgroup_mutex);
	cgroup_kn_unlock(of->kn);
	return nbytes;
}