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

Commit b29b126f authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "BACKPORT: FROMGIT: cgroup: Use separate src/dst nodes when preloading...

Merge "BACKPORT: FROMGIT: cgroup: Use separate src/dst nodes when preloading css_sets for migration"
parents 6e5a826a 064252c4
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -277,6 +277,13 @@ struct css_set {
	struct rcu_head rcu_head;
};

struct ext_css_set {
	struct css_set cset;

	struct list_head mg_src_preload_node;
	struct list_head mg_dst_preload_node;
};

struct cgroup_base_stat {
	struct task_cputime cputime;
};
+2 −1
Original line number Diff line number Diff line
@@ -70,7 +70,8 @@ struct css_task_iter {
};

extern struct cgroup_root cgrp_dfl_root;
extern struct css_set init_css_set;
extern struct ext_css_set init_ext_css_set;
#define init_css_set init_ext_css_set.cset

#define SUBSYS(_x) extern struct cgroup_subsys _x ## _cgrp_subsys;
#include <linux/cgroup_subsys.h>
+61 −42
Original line number Diff line number Diff line
@@ -751,7 +751,8 @@ EXPORT_SYMBOL_GPL(of_css);
 * reference-counted, to improve performance when child cgroups
 * haven't been created.
 */
struct css_set init_css_set = {
struct ext_css_set init_ext_css_set = {
	.cset = {
		.refcount               = REFCOUNT_INIT(1),
		.dom_cset               = &init_css_set,
		.tasks                  = LIST_HEAD_INIT(init_css_set.tasks),
@@ -762,7 +763,6 @@ struct css_set init_css_set = {
		.cgrp_links             = LIST_HEAD_INIT(init_css_set.cgrp_links),
		.mg_preload_node        = LIST_HEAD_INIT(init_css_set.mg_preload_node),
		.mg_node                = LIST_HEAD_INIT(init_css_set.mg_node),

		/*
		 * The following field is re-initialized when this cset gets linked
		 * in cgroup_init().  However, let's initialize the field
@@ -770,6 +770,9 @@ struct css_set init_css_set = {
		 * early during boot.
		 */
		.dfl_cgrp               = &cgrp_dfl_root.cgrp,
	},
	.mg_src_preload_node	= LIST_HEAD_INIT(init_ext_css_set.mg_src_preload_node),
	.mg_dst_preload_node	= LIST_HEAD_INIT(init_ext_css_set.mg_dst_preload_node),
};

static int css_set_count	= 1;	/* 1 for init_css_set */
@@ -1197,6 +1200,7 @@ static struct css_set *find_css_set(struct css_set *old_cset,
				    struct cgroup *cgrp)
{
	struct cgroup_subsys_state *template[CGROUP_SUBSYS_COUNT] = { };
	struct ext_css_set *ext_cset;
	struct css_set *cset;
	struct list_head tmp_links;
	struct cgrp_cset_link *link;
@@ -1217,9 +1221,10 @@ static struct css_set *find_css_set(struct css_set *old_cset,
	if (cset)
		return cset;

	cset = kzalloc(sizeof(*cset), GFP_KERNEL);
	if (!cset)
	ext_cset = kzalloc(sizeof(*ext_cset), GFP_KERNEL);
	if (!ext_cset)
		return NULL;
	cset = &ext_cset->cset;

	/* Allocate all the cgrp_cset_link objects that we'll need */
	if (allocate_cgrp_cset_links(cgroup_root_count, &tmp_links) < 0) {
@@ -1237,6 +1242,8 @@ static struct css_set *find_css_set(struct css_set *old_cset,
	INIT_HLIST_NODE(&cset->hlist);
	INIT_LIST_HEAD(&cset->cgrp_links);
	INIT_LIST_HEAD(&cset->mg_preload_node);
	INIT_LIST_HEAD(&ext_cset->mg_src_preload_node);
	INIT_LIST_HEAD(&ext_cset->mg_dst_preload_node);
	INIT_LIST_HEAD(&cset->mg_node);

	/* Copy the set of subsystem state objects generated in
@@ -2687,22 +2694,28 @@ int cgroup_migrate_vet_dst(struct cgroup *dst_cgrp)
 */
void cgroup_migrate_finish(struct cgroup_mgctx *mgctx)
{
	LIST_HEAD(preloaded);
	struct css_set *cset, *tmp_cset;
	struct ext_css_set *cset, *tmp_cset;

	lockdep_assert_held(&cgroup_mutex);

	spin_lock_irq(&css_set_lock);

	list_splice_tail_init(&mgctx->preloaded_src_csets, &preloaded);
	list_splice_tail_init(&mgctx->preloaded_dst_csets, &preloaded);
	list_for_each_entry_safe(cset, tmp_cset, &mgctx->preloaded_src_csets,
				 mg_src_preload_node) {
		cset->cset.mg_src_cgrp = NULL;
		cset->cset.mg_dst_cgrp = NULL;
		cset->cset.mg_dst_cset = NULL;
		list_del_init(&cset->mg_src_preload_node);
		put_css_set_locked(&cset->cset);
	}

	list_for_each_entry_safe(cset, tmp_cset, &preloaded, mg_preload_node) {
		cset->mg_src_cgrp = NULL;
		cset->mg_dst_cgrp = NULL;
		cset->mg_dst_cset = NULL;
		list_del_init(&cset->mg_preload_node);
		put_css_set_locked(cset);
	list_for_each_entry_safe(cset, tmp_cset, &mgctx->preloaded_dst_csets,
				 mg_dst_preload_node) {
		cset->cset.mg_src_cgrp = NULL;
		cset->cset.mg_dst_cgrp = NULL;
		cset->cset.mg_dst_cset = NULL;
		list_del_init(&cset->mg_dst_preload_node);
		put_css_set_locked(&cset->cset);
	}

	spin_unlock_irq(&css_set_lock);
@@ -2729,6 +2742,7 @@ void cgroup_migrate_add_src(struct css_set *src_cset,
			    struct cgroup_mgctx *mgctx)
{
	struct cgroup *src_cgrp;
	struct ext_css_set *ext_src_cset;

	lockdep_assert_held(&cgroup_mutex);
	lockdep_assert_held(&css_set_lock);
@@ -2742,8 +2756,9 @@ void cgroup_migrate_add_src(struct css_set *src_cset,
		return;

	src_cgrp = cset_cgroup_from_root(src_cset, dst_cgrp->root);
	ext_src_cset = container_of(src_cset, struct ext_css_set, cset);

	if (!list_empty(&src_cset->mg_preload_node))
	if (!list_empty(&ext_src_cset->mg_src_preload_node))
		return;

	WARN_ON(src_cset->mg_src_cgrp);
@@ -2754,7 +2769,7 @@ void cgroup_migrate_add_src(struct css_set *src_cset,
	src_cset->mg_src_cgrp = src_cgrp;
	src_cset->mg_dst_cgrp = dst_cgrp;
	get_css_set(src_cset);
	list_add_tail(&src_cset->mg_preload_node, &mgctx->preloaded_src_csets);
	list_add_tail(&ext_src_cset->mg_src_preload_node, &mgctx->preloaded_src_csets);
}

/**
@@ -2773,20 +2788,23 @@ void cgroup_migrate_add_src(struct css_set *src_cset,
 */
int cgroup_migrate_prepare_dst(struct cgroup_mgctx *mgctx)
{
	struct css_set *src_cset, *tmp_cset;
	struct ext_css_set *ext_src_set, *tmp_cset;

	lockdep_assert_held(&cgroup_mutex);

	/* look up the dst cset for each src cset and link it to src */
	list_for_each_entry_safe(src_cset, tmp_cset, &mgctx->preloaded_src_csets,
				 mg_preload_node) {
	list_for_each_entry_safe(ext_src_set, tmp_cset, &mgctx->preloaded_src_csets,
				 mg_src_preload_node) {
		struct css_set *src_cset = &ext_src_set->cset;
		struct css_set *dst_cset;
		struct ext_css_set *ext_dst_cset;
		struct cgroup_subsys *ss;
		int ssid;

		dst_cset = find_css_set(src_cset, src_cset->mg_dst_cgrp);
		if (!dst_cset)
			return -ENOMEM;
		ext_dst_cset = container_of(dst_cset, struct ext_css_set, cset);

		WARN_ON_ONCE(src_cset->mg_dst_cset || dst_cset->mg_dst_cset);

@@ -2798,7 +2816,7 @@ int cgroup_migrate_prepare_dst(struct cgroup_mgctx *mgctx)
		if (src_cset == dst_cset) {
			src_cset->mg_src_cgrp = NULL;
			src_cset->mg_dst_cgrp = NULL;
			list_del_init(&src_cset->mg_preload_node);
			list_del_init(&ext_src_set->mg_src_preload_node);
			put_css_set(src_cset);
			put_css_set(dst_cset);
			continue;
@@ -2806,8 +2824,8 @@ int cgroup_migrate_prepare_dst(struct cgroup_mgctx *mgctx)

		src_cset->mg_dst_cset = dst_cset;

		if (list_empty(&dst_cset->mg_preload_node))
			list_add_tail(&dst_cset->mg_preload_node,
		if (list_empty(&ext_dst_cset->mg_dst_preload_node))
			list_add_tail(&ext_dst_cset->mg_dst_preload_node,
				      &mgctx->preloaded_dst_csets);
		else
			put_css_set(dst_cset);
@@ -3026,8 +3044,8 @@ static int cgroup_update_dfl_csses(struct cgroup *cgrp)
	DEFINE_CGROUP_MGCTX(mgctx);
	struct cgroup_subsys_state *d_css;
	struct cgroup *dsct;
	struct css_set *src_cset;
	bool has_tasks;
	struct ext_css_set *ext_src_set;
	int ret;

	lockdep_assert_held(&cgroup_mutex);
@@ -3057,11 +3075,12 @@ static int cgroup_update_dfl_csses(struct cgroup *cgrp)
		goto out_finish;

	spin_lock_irq(&css_set_lock);
	list_for_each_entry(src_cset, &mgctx.preloaded_src_csets, mg_preload_node) {
	list_for_each_entry(ext_src_set, &mgctx.preloaded_src_csets,
			    mg_src_preload_node) {
		struct task_struct *task, *ntask;

		/* all tasks in src_csets need to be migrated */
		list_for_each_entry_safe(task, ntask, &src_cset->tasks, cg_list)
		list_for_each_entry_safe(task, ntask, &ext_src_set->cset.tasks, cg_list)
			cgroup_migrate_add_task(task, &mgctx);
	}
	spin_unlock_irq(&css_set_lock);