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

Commit 4fc3e1cf authored by Olav Haugan's avatar Olav Haugan Committed by Vinayak Menon
Browse files

cgroup: add provision to move task to root cgroup



In some cases we may need to a move task out its cgroup to avoid
priority inversion, when it is holding critical resources
required by other higher priority tasks. So add a mechanism to
move a task out of its cgroup to avoid the task being starved.

CRs-Fixed: 983539
Change-Id: I167d7f965d133ec996bd13f57183468e8399bacc
Signed-off-by: default avatarOlav Haugan <ohaugan@codeaurora.org>
Signed-off-by: default avatarVinayak Menon <vinmenon@codeaurora.org>
parent 53d1dd96
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -912,6 +912,7 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from);

struct cgroup_subsys_state *css_tryget_online_from_dir(struct dentry *dentry,
						       struct cgroup_subsys *ss);
int cgroup_attach_task_to_root(struct task_struct *tsk, int wait);

/*
 * Default Android check for whether the current process is allowed to move a
@@ -950,6 +951,11 @@ static inline int subsys_cgroup_allow_attach(struct cgroup_subsys_state *css,
{
	return -EINVAL;
}

static inline int cgroup_attach_task_to_root(struct task_struct *tsk, int wait)
{
	return 0;
}
#endif /* !CONFIG_CGROUPS */

#endif /* _LINUX_CGROUP_H */
+52 −0
Original line number Diff line number Diff line
@@ -2505,6 +2505,58 @@ static ssize_t cgroup_tasks_write(struct kernfs_open_file *of,
	return __cgroup_procs_write(of, buf, nbytes, off, false);
}

#ifdef CONFIG_CGROUP_SCHED
int cgroup_attach_task_to_root(struct task_struct *tsk, int wait)
{
	int ret = 0;
	struct cgroup *cgrp;
	struct cgroup *root_cgrp = NULL;

	if (!mutex_trylock(&cgroup_mutex)) {
		/*This can be a case of recursion, so bail out */
		if (!wait)
			return -EBUSY;
		mutex_lock(&cgroup_mutex);
	}

	cgrp = task_cgroup(tsk, cpu_cgrp_id);

	if (cgrp && cgrp->root)
		root_cgrp = &cgrp->root->cgrp;

	if (root_cgrp && cgrp != root_cgrp)
		cgrp = root_cgrp;
	else
		goto out_unlock_cgroup;

	if (cgroup_is_dead(cgrp)) {
		ret = -ENODEV;
		goto out_unlock_cgroup;
	}

	rcu_read_lock();

	get_task_struct(tsk);
	rcu_read_unlock();

	threadgroup_lock(tsk);

	ret = cgroup_attach_task(cgrp, tsk, false);

	threadgroup_unlock(tsk);

	put_task_struct(tsk);
out_unlock_cgroup:
	mutex_unlock(&cgroup_mutex);
	return ret;
}
#else
int cgroup_attach_task_to_root(struct task_struct *tsk, int wait)
{
	return 0;
}
#endif

static ssize_t cgroup_procs_write(struct kernfs_open_file *of,
				  char *buf, size_t nbytes, loff_t off)
{