Skip to content

Commit e595cd7

Browse files
committed
cgroup: track migration context in cgroup_mgctx
cgroup migration is performed in four steps - css_set preloading, addition of target tasks, actual migration, and clean up. A list named preloaded_csets is used to track the preloading. This is a bit too restricted and the code is already depending on the subtlety that all source css_sets appear before destination ones. Let's create struct cgroup_mgctx which keeps track of everything during migration. Currently, it has separate preload lists for source and destination csets and also embeds cgroup_taskset which is used during the actual migration. This moves struct cgroup_taskset definition to cgroup-internal.h. This patch doesn't cause any functional changes. Signed-off-by: Tejun Heo <[email protected]> Acked-by: Zefan Li <[email protected]>
1 parent d8ebf51 commit e595cd7

File tree

3 files changed

+122
-98
lines changed

3 files changed

+122
-98
lines changed

kernel/cgroup/cgroup-internal.h

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,61 @@ struct cgrp_cset_link {
2626
struct list_head cgrp_link;
2727
};
2828

29+
/* used to track tasks and csets during migration */
30+
struct cgroup_taskset {
31+
/* the src and dst cset list running through cset->mg_node */
32+
struct list_head src_csets;
33+
struct list_head dst_csets;
34+
35+
/* the subsys currently being processed */
36+
int ssid;
37+
38+
/*
39+
* Fields for cgroup_taskset_*() iteration.
40+
*
41+
* Before migration is committed, the target migration tasks are on
42+
* ->mg_tasks of the csets on ->src_csets. After, on ->mg_tasks of
43+
* the csets on ->dst_csets. ->csets point to either ->src_csets
44+
* or ->dst_csets depending on whether migration is committed.
45+
*
46+
* ->cur_csets and ->cur_task point to the current task position
47+
* during iteration.
48+
*/
49+
struct list_head *csets;
50+
struct css_set *cur_cset;
51+
struct task_struct *cur_task;
52+
};
53+
54+
/* migration context also tracks preloading */
55+
struct cgroup_mgctx {
56+
/*
57+
* Preloaded source and destination csets. Used to guarantee
58+
* atomic success or failure on actual migration.
59+
*/
60+
struct list_head preloaded_src_csets;
61+
struct list_head preloaded_dst_csets;
62+
63+
/* tasks and csets to migrate */
64+
struct cgroup_taskset tset;
65+
};
66+
67+
#define CGROUP_TASKSET_INIT(tset) \
68+
{ \
69+
.src_csets = LIST_HEAD_INIT(tset.src_csets), \
70+
.dst_csets = LIST_HEAD_INIT(tset.dst_csets), \
71+
.csets = &tset.src_csets, \
72+
}
73+
74+
#define CGROUP_MGCTX_INIT(name) \
75+
{ \
76+
LIST_HEAD_INIT(name.preloaded_src_csets), \
77+
LIST_HEAD_INIT(name.preloaded_dst_csets), \
78+
CGROUP_TASKSET_INIT(name.tset), \
79+
}
80+
81+
#define DEFINE_CGROUP_MGCTX(name) \
82+
struct cgroup_mgctx name = CGROUP_MGCTX_INIT(name)
83+
2984
struct cgroup_sb_opts {
3085
u16 subsys_mask;
3186
unsigned int flags;
@@ -112,13 +167,12 @@ struct dentry *cgroup_do_mount(struct file_system_type *fs_type, int flags,
112167
struct cgroup_namespace *ns);
113168

114169
bool cgroup_may_migrate_to(struct cgroup *dst_cgrp);
115-
void cgroup_migrate_finish(struct list_head *preloaded_csets);
116-
void cgroup_migrate_add_src(struct css_set *src_cset,
117-
struct cgroup *dst_cgrp,
118-
struct list_head *preloaded_csets);
119-
int cgroup_migrate_prepare_dst(struct list_head *preloaded_csets);
170+
void cgroup_migrate_finish(struct cgroup_mgctx *mgctx);
171+
void cgroup_migrate_add_src(struct css_set *src_cset, struct cgroup *dst_cgrp,
172+
struct cgroup_mgctx *mgctx);
173+
int cgroup_migrate_prepare_dst(struct cgroup_mgctx *mgctx);
120174
int cgroup_migrate(struct task_struct *leader, bool threadgroup,
121-
struct cgroup_root *root);
175+
struct cgroup_mgctx *mgctx, struct cgroup_root *root);
122176

123177
int cgroup_attach_task(struct cgroup *dst_cgrp, struct task_struct *leader,
124178
bool threadgroup);

kernel/cgroup/cgroup-v1.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ EXPORT_SYMBOL_GPL(cgroup_attach_task_all);
8787
*/
8888
int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from)
8989
{
90-
LIST_HEAD(preloaded_csets);
90+
DEFINE_CGROUP_MGCTX(mgctx);
9191
struct cgrp_cset_link *link;
9292
struct css_task_iter it;
9393
struct task_struct *task;
@@ -106,10 +106,10 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from)
106106
/* all tasks in @from are being moved, all csets are source */
107107
spin_lock_irq(&css_set_lock);
108108
list_for_each_entry(link, &from->cset_links, cset_link)
109-
cgroup_migrate_add_src(link->cset, to, &preloaded_csets);
109+
cgroup_migrate_add_src(link->cset, to, &mgctx);
110110
spin_unlock_irq(&css_set_lock);
111111

112-
ret = cgroup_migrate_prepare_dst(&preloaded_csets);
112+
ret = cgroup_migrate_prepare_dst(&mgctx);
113113
if (ret)
114114
goto out_err;
115115

@@ -125,14 +125,14 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from)
125125
css_task_iter_end(&it);
126126

127127
if (task) {
128-
ret = cgroup_migrate(task, false, to->root);
128+
ret = cgroup_migrate(task, false, &mgctx, to->root);
129129
if (!ret)
130130
trace_cgroup_transfer_tasks(to, task, false);
131131
put_task_struct(task);
132132
}
133133
} while (task && !ret);
134134
out_err:
135-
cgroup_migrate_finish(&preloaded_csets);
135+
cgroup_migrate_finish(&mgctx);
136136
percpu_up_write(&cgroup_threadgroup_rwsem);
137137
mutex_unlock(&cgroup_mutex);
138138
return ret;

0 commit comments

Comments
 (0)