diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-03 21:25:03 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-03 21:25:03 -0400 |
commit | 32dad03d164206ea886885d0740284ba215b0970 (patch) | |
tree | 5fd89fe27295bfbe47dce5f274aa645099741a71 /kernel/cpuset.c | |
parent | 357397a14117f0c2eeafcac06a1f8412a02aa6af (diff) | |
parent | d1625964da51bda61306ad3ec45307a799c21f08 (diff) |
Merge branch 'for-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
Pull cgroup updates from Tejun Heo:
"A lot of activities on the cgroup front. Most changes aren't visible
to userland at all at this point and are laying foundation for the
planned unified hierarchy.
- The biggest change is decoupling the lifetime management of css
(cgroup_subsys_state) from that of cgroup's. Because controllers
(cpu, memory, block and so on) will need to be dynamically enabled
and disabled, css which is the association point between a cgroup
and a controller may come and go dynamically across the lifetime of
a cgroup. Till now, css's were created when the associated cgroup
was created and stayed till the cgroup got destroyed.
Assumptions around this tight coupling permeated through cgroup
core and controllers. These assumptions are gradually removed,
which consists bulk of patches, and css destruction path is
completely decoupled from cgroup destruction path. Note that
decoupling of creation path is relatively easy on top of these
changes and the patchset is pending for the next window.
- cgroup has its own event mechanism cgroup.event_control, which is
only used by memcg. It is overly complex trying to achieve high
flexibility whose benefits seem dubious at best. Going forward,
new events will simply generate file modified event and the
existing mechanism is being made specific to memcg. This pull
request contains prepatory patches for such change.
- Various fixes and cleanups"
Fixed up conflict in kernel/cgroup.c as per Tejun.
* 'for-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup: (69 commits)
cgroup: fix cgroup_css() invocation in css_from_id()
cgroup: make cgroup_write_event_control() use css_from_dir() instead of __d_cgrp()
cgroup: make cgroup_event hold onto cgroup_subsys_state instead of cgroup
cgroup: implement CFTYPE_NO_PREFIX
cgroup: make cgroup_css() take cgroup_subsys * instead and allow NULL subsys
cgroup: rename cgroup_css_from_dir() to css_from_dir() and update its syntax
cgroup: fix cgroup_write_event_control()
cgroup: fix subsystem file accesses on the root cgroup
cgroup: change cgroup_from_id() to css_from_id()
cgroup: use css_get() in cgroup_create() to check CSS_ROOT
cpuset: remove an unncessary forward declaration
cgroup: RCU protect each cgroup_subsys_state release
cgroup: move subsys file removal to kill_css()
cgroup: factor out kill_css()
cgroup: decouple cgroup_subsys_state destruction from cgroup destruction
cgroup: replace cgroup->css_kill_cnt with ->nr_css
cgroup: bounce cgroup_subsys_state ref kill confirmation to a work item
cgroup: move cgroup->subsys[] assignment to online_css()
cgroup: reorganize css init / exit paths
cgroup: add __rcu modifier to cgroup->subsys[]
...
Diffstat (limited to 'kernel/cpuset.c')
-rw-r--r-- | kernel/cpuset.c | 317 |
1 files changed, 153 insertions, 164 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index ea1966db34f2..6bf981e13c43 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -68,10 +68,6 @@ | |||
68 | */ | 68 | */ |
69 | int number_of_cpusets __read_mostly; | 69 | int number_of_cpusets __read_mostly; |
70 | 70 | ||
71 | /* Forward declare cgroup structures */ | ||
72 | struct cgroup_subsys cpuset_subsys; | ||
73 | struct cpuset; | ||
74 | |||
75 | /* See "Frequency meter" comments, below. */ | 71 | /* See "Frequency meter" comments, below. */ |
76 | 72 | ||
77 | struct fmeter { | 73 | struct fmeter { |
@@ -115,27 +111,20 @@ struct cpuset { | |||
115 | int relax_domain_level; | 111 | int relax_domain_level; |
116 | }; | 112 | }; |
117 | 113 | ||
118 | /* Retrieve the cpuset for a cgroup */ | 114 | static inline struct cpuset *css_cs(struct cgroup_subsys_state *css) |
119 | static inline struct cpuset *cgroup_cs(struct cgroup *cgrp) | ||
120 | { | 115 | { |
121 | return container_of(cgroup_subsys_state(cgrp, cpuset_subsys_id), | 116 | return css ? container_of(css, struct cpuset, css) : NULL; |
122 | struct cpuset, css); | ||
123 | } | 117 | } |
124 | 118 | ||
125 | /* Retrieve the cpuset for a task */ | 119 | /* Retrieve the cpuset for a task */ |
126 | static inline struct cpuset *task_cs(struct task_struct *task) | 120 | static inline struct cpuset *task_cs(struct task_struct *task) |
127 | { | 121 | { |
128 | return container_of(task_subsys_state(task, cpuset_subsys_id), | 122 | return css_cs(task_css(task, cpuset_subsys_id)); |
129 | struct cpuset, css); | ||
130 | } | 123 | } |
131 | 124 | ||
132 | static inline struct cpuset *parent_cs(const struct cpuset *cs) | 125 | static inline struct cpuset *parent_cs(struct cpuset *cs) |
133 | { | 126 | { |
134 | struct cgroup *pcgrp = cs->css.cgroup->parent; | 127 | return css_cs(css_parent(&cs->css)); |
135 | |||
136 | if (pcgrp) | ||
137 | return cgroup_cs(pcgrp); | ||
138 | return NULL; | ||
139 | } | 128 | } |
140 | 129 | ||
141 | #ifdef CONFIG_NUMA | 130 | #ifdef CONFIG_NUMA |
@@ -212,29 +201,30 @@ static struct cpuset top_cpuset = { | |||
212 | /** | 201 | /** |
213 | * cpuset_for_each_child - traverse online children of a cpuset | 202 | * cpuset_for_each_child - traverse online children of a cpuset |
214 | * @child_cs: loop cursor pointing to the current child | 203 | * @child_cs: loop cursor pointing to the current child |
215 | * @pos_cgrp: used for iteration | 204 | * @pos_css: used for iteration |
216 | * @parent_cs: target cpuset to walk children of | 205 | * @parent_cs: target cpuset to walk children of |
217 | * | 206 | * |
218 | * Walk @child_cs through the online children of @parent_cs. Must be used | 207 | * Walk @child_cs through the online children of @parent_cs. Must be used |
219 | * with RCU read locked. | 208 | * with RCU read locked. |
220 | */ | 209 | */ |
221 | #define cpuset_for_each_child(child_cs, pos_cgrp, parent_cs) \ | 210 | #define cpuset_for_each_child(child_cs, pos_css, parent_cs) \ |
222 | cgroup_for_each_child((pos_cgrp), (parent_cs)->css.cgroup) \ | 211 | css_for_each_child((pos_css), &(parent_cs)->css) \ |
223 | if (is_cpuset_online(((child_cs) = cgroup_cs((pos_cgrp))))) | 212 | if (is_cpuset_online(((child_cs) = css_cs((pos_css))))) |
224 | 213 | ||
225 | /** | 214 | /** |
226 | * cpuset_for_each_descendant_pre - pre-order walk of a cpuset's descendants | 215 | * cpuset_for_each_descendant_pre - pre-order walk of a cpuset's descendants |
227 | * @des_cs: loop cursor pointing to the current descendant | 216 | * @des_cs: loop cursor pointing to the current descendant |
228 | * @pos_cgrp: used for iteration | 217 | * @pos_css: used for iteration |
229 | * @root_cs: target cpuset to walk ancestor of | 218 | * @root_cs: target cpuset to walk ancestor of |
230 | * | 219 | * |
231 | * Walk @des_cs through the online descendants of @root_cs. Must be used | 220 | * Walk @des_cs through the online descendants of @root_cs. Must be used |
232 | * with RCU read locked. The caller may modify @pos_cgrp by calling | 221 | * with RCU read locked. The caller may modify @pos_css by calling |
233 | * cgroup_rightmost_descendant() to skip subtree. | 222 | * css_rightmost_descendant() to skip subtree. @root_cs is included in the |
223 | * iteration and the first node to be visited. | ||
234 | */ | 224 | */ |
235 | #define cpuset_for_each_descendant_pre(des_cs, pos_cgrp, root_cs) \ | 225 | #define cpuset_for_each_descendant_pre(des_cs, pos_css, root_cs) \ |
236 | cgroup_for_each_descendant_pre((pos_cgrp), (root_cs)->css.cgroup) \ | 226 | css_for_each_descendant_pre((pos_css), &(root_cs)->css) \ |
237 | if (is_cpuset_online(((des_cs) = cgroup_cs((pos_cgrp))))) | 227 | if (is_cpuset_online(((des_cs) = css_cs((pos_css))))) |
238 | 228 | ||
239 | /* | 229 | /* |
240 | * There are two global mutexes guarding cpuset structures - cpuset_mutex | 230 | * There are two global mutexes guarding cpuset structures - cpuset_mutex |
@@ -320,8 +310,7 @@ static struct file_system_type cpuset_fs_type = { | |||
320 | * | 310 | * |
321 | * Call with callback_mutex held. | 311 | * Call with callback_mutex held. |
322 | */ | 312 | */ |
323 | static void guarantee_online_cpus(const struct cpuset *cs, | 313 | static void guarantee_online_cpus(struct cpuset *cs, struct cpumask *pmask) |
324 | struct cpumask *pmask) | ||
325 | { | 314 | { |
326 | while (!cpumask_intersects(cs->cpus_allowed, cpu_online_mask)) | 315 | while (!cpumask_intersects(cs->cpus_allowed, cpu_online_mask)) |
327 | cs = parent_cs(cs); | 316 | cs = parent_cs(cs); |
@@ -339,7 +328,7 @@ static void guarantee_online_cpus(const struct cpuset *cs, | |||
339 | * | 328 | * |
340 | * Call with callback_mutex held. | 329 | * Call with callback_mutex held. |
341 | */ | 330 | */ |
342 | static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask) | 331 | static void guarantee_online_mems(struct cpuset *cs, nodemask_t *pmask) |
343 | { | 332 | { |
344 | while (!nodes_intersects(cs->mems_allowed, node_states[N_MEMORY])) | 333 | while (!nodes_intersects(cs->mems_allowed, node_states[N_MEMORY])) |
345 | cs = parent_cs(cs); | 334 | cs = parent_cs(cs); |
@@ -384,7 +373,7 @@ static int is_cpuset_subset(const struct cpuset *p, const struct cpuset *q) | |||
384 | * alloc_trial_cpuset - allocate a trial cpuset | 373 | * alloc_trial_cpuset - allocate a trial cpuset |
385 | * @cs: the cpuset that the trial cpuset duplicates | 374 | * @cs: the cpuset that the trial cpuset duplicates |
386 | */ | 375 | */ |
387 | static struct cpuset *alloc_trial_cpuset(const struct cpuset *cs) | 376 | static struct cpuset *alloc_trial_cpuset(struct cpuset *cs) |
388 | { | 377 | { |
389 | struct cpuset *trial; | 378 | struct cpuset *trial; |
390 | 379 | ||
@@ -431,9 +420,9 @@ static void free_trial_cpuset(struct cpuset *trial) | |||
431 | * Return 0 if valid, -errno if not. | 420 | * Return 0 if valid, -errno if not. |
432 | */ | 421 | */ |
433 | 422 | ||
434 | static int validate_change(const struct cpuset *cur, const struct cpuset *trial) | 423 | static int validate_change(struct cpuset *cur, struct cpuset *trial) |
435 | { | 424 | { |
436 | struct cgroup *cgrp; | 425 | struct cgroup_subsys_state *css; |
437 | struct cpuset *c, *par; | 426 | struct cpuset *c, *par; |
438 | int ret; | 427 | int ret; |
439 | 428 | ||
@@ -441,7 +430,7 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial) | |||
441 | 430 | ||
442 | /* Each of our child cpusets must be a subset of us */ | 431 | /* Each of our child cpusets must be a subset of us */ |
443 | ret = -EBUSY; | 432 | ret = -EBUSY; |
444 | cpuset_for_each_child(c, cgrp, cur) | 433 | cpuset_for_each_child(c, css, cur) |
445 | if (!is_cpuset_subset(c, trial)) | 434 | if (!is_cpuset_subset(c, trial)) |
446 | goto out; | 435 | goto out; |
447 | 436 | ||
@@ -462,7 +451,7 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial) | |||
462 | * overlap | 451 | * overlap |
463 | */ | 452 | */ |
464 | ret = -EINVAL; | 453 | ret = -EINVAL; |
465 | cpuset_for_each_child(c, cgrp, par) { | 454 | cpuset_for_each_child(c, css, par) { |
466 | if ((is_cpu_exclusive(trial) || is_cpu_exclusive(c)) && | 455 | if ((is_cpu_exclusive(trial) || is_cpu_exclusive(c)) && |
467 | c != cur && | 456 | c != cur && |
468 | cpumask_intersects(trial->cpus_allowed, c->cpus_allowed)) | 457 | cpumask_intersects(trial->cpus_allowed, c->cpus_allowed)) |
@@ -515,13 +504,16 @@ static void update_domain_attr_tree(struct sched_domain_attr *dattr, | |||
515 | struct cpuset *root_cs) | 504 | struct cpuset *root_cs) |
516 | { | 505 | { |
517 | struct cpuset *cp; | 506 | struct cpuset *cp; |
518 | struct cgroup *pos_cgrp; | 507 | struct cgroup_subsys_state *pos_css; |
519 | 508 | ||
520 | rcu_read_lock(); | 509 | rcu_read_lock(); |
521 | cpuset_for_each_descendant_pre(cp, pos_cgrp, root_cs) { | 510 | cpuset_for_each_descendant_pre(cp, pos_css, root_cs) { |
511 | if (cp == root_cs) | ||
512 | continue; | ||
513 | |||
522 | /* skip the whole subtree if @cp doesn't have any CPU */ | 514 | /* skip the whole subtree if @cp doesn't have any CPU */ |
523 | if (cpumask_empty(cp->cpus_allowed)) { | 515 | if (cpumask_empty(cp->cpus_allowed)) { |
524 | pos_cgrp = cgroup_rightmost_descendant(pos_cgrp); | 516 | pos_css = css_rightmost_descendant(pos_css); |
525 | continue; | 517 | continue; |
526 | } | 518 | } |
527 | 519 | ||
@@ -596,7 +588,7 @@ static int generate_sched_domains(cpumask_var_t **domains, | |||
596 | struct sched_domain_attr *dattr; /* attributes for custom domains */ | 588 | struct sched_domain_attr *dattr; /* attributes for custom domains */ |
597 | int ndoms = 0; /* number of sched domains in result */ | 589 | int ndoms = 0; /* number of sched domains in result */ |
598 | int nslot; /* next empty doms[] struct cpumask slot */ | 590 | int nslot; /* next empty doms[] struct cpumask slot */ |
599 | struct cgroup *pos_cgrp; | 591 | struct cgroup_subsys_state *pos_css; |
600 | 592 | ||
601 | doms = NULL; | 593 | doms = NULL; |
602 | dattr = NULL; | 594 | dattr = NULL; |
@@ -625,7 +617,9 @@ static int generate_sched_domains(cpumask_var_t **domains, | |||
625 | csn = 0; | 617 | csn = 0; |
626 | 618 | ||
627 | rcu_read_lock(); | 619 | rcu_read_lock(); |
628 | cpuset_for_each_descendant_pre(cp, pos_cgrp, &top_cpuset) { | 620 | cpuset_for_each_descendant_pre(cp, pos_css, &top_cpuset) { |
621 | if (cp == &top_cpuset) | ||
622 | continue; | ||
629 | /* | 623 | /* |
630 | * Continue traversing beyond @cp iff @cp has some CPUs and | 624 | * Continue traversing beyond @cp iff @cp has some CPUs and |
631 | * isn't load balancing. The former is obvious. The | 625 | * isn't load balancing. The former is obvious. The |
@@ -642,7 +636,7 @@ static int generate_sched_domains(cpumask_var_t **domains, | |||
642 | csa[csn++] = cp; | 636 | csa[csn++] = cp; |
643 | 637 | ||
644 | /* skip @cp's subtree */ | 638 | /* skip @cp's subtree */ |
645 | pos_cgrp = cgroup_rightmost_descendant(pos_cgrp); | 639 | pos_css = css_rightmost_descendant(pos_css); |
646 | } | 640 | } |
647 | rcu_read_unlock(); | 641 | rcu_read_unlock(); |
648 | 642 | ||
@@ -837,52 +831,45 @@ static struct cpuset *effective_nodemask_cpuset(struct cpuset *cs) | |||
837 | /** | 831 | /** |
838 | * cpuset_change_cpumask - make a task's cpus_allowed the same as its cpuset's | 832 | * cpuset_change_cpumask - make a task's cpus_allowed the same as its cpuset's |
839 | * @tsk: task to test | 833 | * @tsk: task to test |
840 | * @scan: struct cgroup_scanner containing the cgroup of the task | 834 | * @data: cpuset to @tsk belongs to |
841 | * | 835 | * |
842 | * Called by cgroup_scan_tasks() for each task in a cgroup whose | 836 | * Called by css_scan_tasks() for each task in a cgroup whose cpus_allowed |
843 | * cpus_allowed mask needs to be changed. | 837 | * mask needs to be changed. |
844 | * | 838 | * |
845 | * We don't need to re-check for the cgroup/cpuset membership, since we're | 839 | * We don't need to re-check for the cgroup/cpuset membership, since we're |
846 | * holding cpuset_mutex at this point. | 840 | * holding cpuset_mutex at this point. |
847 | */ | 841 | */ |
848 | static void cpuset_change_cpumask(struct task_struct *tsk, | 842 | static void cpuset_change_cpumask(struct task_struct *tsk, void *data) |
849 | struct cgroup_scanner *scan) | ||
850 | { | 843 | { |
851 | struct cpuset *cpus_cs; | 844 | struct cpuset *cs = data; |
845 | struct cpuset *cpus_cs = effective_cpumask_cpuset(cs); | ||
852 | 846 | ||
853 | cpus_cs = effective_cpumask_cpuset(cgroup_cs(scan->cg)); | ||
854 | set_cpus_allowed_ptr(tsk, cpus_cs->cpus_allowed); | 847 | set_cpus_allowed_ptr(tsk, cpus_cs->cpus_allowed); |
855 | } | 848 | } |
856 | 849 | ||
857 | /** | 850 | /** |
858 | * update_tasks_cpumask - Update the cpumasks of tasks in the cpuset. | 851 | * update_tasks_cpumask - Update the cpumasks of tasks in the cpuset. |
859 | * @cs: the cpuset in which each task's cpus_allowed mask needs to be changed | 852 | * @cs: the cpuset in which each task's cpus_allowed mask needs to be changed |
860 | * @heap: if NULL, defer allocating heap memory to cgroup_scan_tasks() | 853 | * @heap: if NULL, defer allocating heap memory to css_scan_tasks() |
861 | * | 854 | * |
862 | * Called with cpuset_mutex held | 855 | * Called with cpuset_mutex held |
863 | * | 856 | * |
864 | * The cgroup_scan_tasks() function will scan all the tasks in a cgroup, | 857 | * The css_scan_tasks() function will scan all the tasks in a cgroup, |
865 | * calling callback functions for each. | 858 | * calling callback functions for each. |
866 | * | 859 | * |
867 | * No return value. It's guaranteed that cgroup_scan_tasks() always returns 0 | 860 | * No return value. It's guaranteed that css_scan_tasks() always returns 0 |
868 | * if @heap != NULL. | 861 | * if @heap != NULL. |
869 | */ | 862 | */ |
870 | static void update_tasks_cpumask(struct cpuset *cs, struct ptr_heap *heap) | 863 | static void update_tasks_cpumask(struct cpuset *cs, struct ptr_heap *heap) |
871 | { | 864 | { |
872 | struct cgroup_scanner scan; | 865 | css_scan_tasks(&cs->css, NULL, cpuset_change_cpumask, cs, heap); |
873 | |||
874 | scan.cg = cs->css.cgroup; | ||
875 | scan.test_task = NULL; | ||
876 | scan.process_task = cpuset_change_cpumask; | ||
877 | scan.heap = heap; | ||
878 | cgroup_scan_tasks(&scan); | ||
879 | } | 866 | } |
880 | 867 | ||
881 | /* | 868 | /* |
882 | * update_tasks_cpumask_hier - Update the cpumasks of tasks in the hierarchy. | 869 | * update_tasks_cpumask_hier - Update the cpumasks of tasks in the hierarchy. |
883 | * @root_cs: the root cpuset of the hierarchy | 870 | * @root_cs: the root cpuset of the hierarchy |
884 | * @update_root: update root cpuset or not? | 871 | * @update_root: update root cpuset or not? |
885 | * @heap: the heap used by cgroup_scan_tasks() | 872 | * @heap: the heap used by css_scan_tasks() |
886 | * | 873 | * |
887 | * This will update cpumasks of tasks in @root_cs and all other empty cpusets | 874 | * This will update cpumasks of tasks in @root_cs and all other empty cpusets |
888 | * which take on cpumask of @root_cs. | 875 | * which take on cpumask of @root_cs. |
@@ -893,17 +880,19 @@ static void update_tasks_cpumask_hier(struct cpuset *root_cs, | |||
893 | bool update_root, struct ptr_heap *heap) | 880 | bool update_root, struct ptr_heap *heap) |
894 | { | 881 | { |
895 | struct cpuset *cp; | 882 | struct cpuset *cp; |
896 | struct cgroup *pos_cgrp; | 883 | struct cgroup_subsys_state *pos_css; |
897 | |||
898 | if (update_root) | ||
899 | update_tasks_cpumask(root_cs, heap); | ||
900 | 884 | ||
901 | rcu_read_lock(); | 885 | rcu_read_lock(); |
902 | cpuset_for_each_descendant_pre(cp, pos_cgrp, root_cs) { | 886 | cpuset_for_each_descendant_pre(cp, pos_css, root_cs) { |
903 | /* skip the whole subtree if @cp have some CPU */ | 887 | if (cp == root_cs) { |
904 | if (!cpumask_empty(cp->cpus_allowed)) { | 888 | if (!update_root) |
905 | pos_cgrp = cgroup_rightmost_descendant(pos_cgrp); | 889 | continue; |
906 | continue; | 890 | } else { |
891 | /* skip the whole subtree if @cp have some CPU */ | ||
892 | if (!cpumask_empty(cp->cpus_allowed)) { | ||
893 | pos_css = css_rightmost_descendant(pos_css); | ||
894 | continue; | ||
895 | } | ||
907 | } | 896 | } |
908 | if (!css_tryget(&cp->css)) | 897 | if (!css_tryget(&cp->css)) |
909 | continue; | 898 | continue; |
@@ -1059,20 +1048,24 @@ static void cpuset_change_task_nodemask(struct task_struct *tsk, | |||
1059 | task_unlock(tsk); | 1048 | task_unlock(tsk); |
1060 | } | 1049 | } |
1061 | 1050 | ||
1051 | struct cpuset_change_nodemask_arg { | ||
1052 | struct cpuset *cs; | ||
1053 | nodemask_t *newmems; | ||
1054 | }; | ||
1055 | |||
1062 | /* | 1056 | /* |
1063 | * Update task's mems_allowed and rebind its mempolicy and vmas' mempolicy | 1057 | * Update task's mems_allowed and rebind its mempolicy and vmas' mempolicy |
1064 | * of it to cpuset's new mems_allowed, and migrate pages to new nodes if | 1058 | * of it to cpuset's new mems_allowed, and migrate pages to new nodes if |
1065 | * memory_migrate flag is set. Called with cpuset_mutex held. | 1059 | * memory_migrate flag is set. Called with cpuset_mutex held. |
1066 | */ | 1060 | */ |
1067 | static void cpuset_change_nodemask(struct task_struct *p, | 1061 | static void cpuset_change_nodemask(struct task_struct *p, void *data) |
1068 | struct cgroup_scanner *scan) | ||
1069 | { | 1062 | { |
1070 | struct cpuset *cs = cgroup_cs(scan->cg); | 1063 | struct cpuset_change_nodemask_arg *arg = data; |
1064 | struct cpuset *cs = arg->cs; | ||
1071 | struct mm_struct *mm; | 1065 | struct mm_struct *mm; |
1072 | int migrate; | 1066 | int migrate; |
1073 | nodemask_t *newmems = scan->data; | ||
1074 | 1067 | ||
1075 | cpuset_change_task_nodemask(p, newmems); | 1068 | cpuset_change_task_nodemask(p, arg->newmems); |
1076 | 1069 | ||
1077 | mm = get_task_mm(p); | 1070 | mm = get_task_mm(p); |
1078 | if (!mm) | 1071 | if (!mm) |
@@ -1082,7 +1075,7 @@ static void cpuset_change_nodemask(struct task_struct *p, | |||
1082 | 1075 | ||
1083 | mpol_rebind_mm(mm, &cs->mems_allowed); | 1076 | mpol_rebind_mm(mm, &cs->mems_allowed); |
1084 | if (migrate) | 1077 | if (migrate) |
1085 | cpuset_migrate_mm(mm, &cs->old_mems_allowed, newmems); | 1078 | cpuset_migrate_mm(mm, &cs->old_mems_allowed, arg->newmems); |
1086 | mmput(mm); | 1079 | mmput(mm); |
1087 | } | 1080 | } |
1088 | 1081 | ||
@@ -1091,28 +1084,22 @@ static void *cpuset_being_rebound; | |||
1091 | /** | 1084 | /** |
1092 | * update_tasks_nodemask - Update the nodemasks of tasks in the cpuset. | 1085 | * update_tasks_nodemask - Update the nodemasks of tasks in the cpuset. |
1093 | * @cs: the cpuset in which each task's mems_allowed mask needs to be changed | 1086 | * @cs: the cpuset in which each task's mems_allowed mask needs to be changed |
1094 | * @heap: if NULL, defer allocating heap memory to cgroup_scan_tasks() | 1087 | * @heap: if NULL, defer allocating heap memory to css_scan_tasks() |
1095 | * | 1088 | * |
1096 | * Called with cpuset_mutex held | 1089 | * Called with cpuset_mutex held. No return value. It's guaranteed that |
1097 | * No return value. It's guaranteed that cgroup_scan_tasks() always returns 0 | 1090 | * css_scan_tasks() always returns 0 if @heap != NULL. |
1098 | * if @heap != NULL. | ||
1099 | */ | 1091 | */ |
1100 | static void update_tasks_nodemask(struct cpuset *cs, struct ptr_heap *heap) | 1092 | static void update_tasks_nodemask(struct cpuset *cs, struct ptr_heap *heap) |
1101 | { | 1093 | { |
1102 | static nodemask_t newmems; /* protected by cpuset_mutex */ | 1094 | static nodemask_t newmems; /* protected by cpuset_mutex */ |
1103 | struct cgroup_scanner scan; | ||
1104 | struct cpuset *mems_cs = effective_nodemask_cpuset(cs); | 1095 | struct cpuset *mems_cs = effective_nodemask_cpuset(cs); |
1096 | struct cpuset_change_nodemask_arg arg = { .cs = cs, | ||
1097 | .newmems = &newmems }; | ||
1105 | 1098 | ||
1106 | cpuset_being_rebound = cs; /* causes mpol_dup() rebind */ | 1099 | cpuset_being_rebound = cs; /* causes mpol_dup() rebind */ |
1107 | 1100 | ||
1108 | guarantee_online_mems(mems_cs, &newmems); | 1101 | guarantee_online_mems(mems_cs, &newmems); |
1109 | 1102 | ||
1110 | scan.cg = cs->css.cgroup; | ||
1111 | scan.test_task = NULL; | ||
1112 | scan.process_task = cpuset_change_nodemask; | ||
1113 | scan.heap = heap; | ||
1114 | scan.data = &newmems; | ||
1115 | |||
1116 | /* | 1103 | /* |
1117 | * The mpol_rebind_mm() call takes mmap_sem, which we couldn't | 1104 | * The mpol_rebind_mm() call takes mmap_sem, which we couldn't |
1118 | * take while holding tasklist_lock. Forks can happen - the | 1105 | * take while holding tasklist_lock. Forks can happen - the |
@@ -1123,7 +1110,7 @@ static void update_tasks_nodemask(struct cpuset *cs, struct ptr_heap *heap) | |||
1123 | * It's ok if we rebind the same mm twice; mpol_rebind_mm() | 1110 | * It's ok if we rebind the same mm twice; mpol_rebind_mm() |
1124 | * is idempotent. Also migrate pages in each mm to new nodes. | 1111 | * is idempotent. Also migrate pages in each mm to new nodes. |
1125 | */ | 1112 | */ |
1126 | cgroup_scan_tasks(&scan); | 1113 | css_scan_tasks(&cs->css, NULL, cpuset_change_nodemask, &arg, heap); |
1127 | 1114 | ||
1128 | /* | 1115 | /* |
1129 | * All the tasks' nodemasks have been updated, update | 1116 | * All the tasks' nodemasks have been updated, update |
@@ -1139,7 +1126,7 @@ static void update_tasks_nodemask(struct cpuset *cs, struct ptr_heap *heap) | |||
1139 | * update_tasks_nodemask_hier - Update the nodemasks of tasks in the hierarchy. | 1126 | * update_tasks_nodemask_hier - Update the nodemasks of tasks in the hierarchy. |
1140 | * @cs: the root cpuset of the hierarchy | 1127 | * @cs: the root cpuset of the hierarchy |
1141 | * @update_root: update the root cpuset or not? | 1128 | * @update_root: update the root cpuset or not? |
1142 | * @heap: the heap used by cgroup_scan_tasks() | 1129 | * @heap: the heap used by css_scan_tasks() |
1143 | * | 1130 | * |
1144 | * This will update nodemasks of tasks in @root_cs and all other empty cpusets | 1131 | * This will update nodemasks of tasks in @root_cs and all other empty cpusets |
1145 | * which take on nodemask of @root_cs. | 1132 | * which take on nodemask of @root_cs. |
@@ -1150,17 +1137,19 @@ static void update_tasks_nodemask_hier(struct cpuset *root_cs, | |||
1150 | bool update_root, struct ptr_heap *heap) | 1137 | bool update_root, struct ptr_heap *heap) |
1151 | { | 1138 | { |
1152 | struct cpuset *cp; | 1139 | struct cpuset *cp; |
1153 | struct cgroup *pos_cgrp; | 1140 | struct cgroup_subsys_state *pos_css; |
1154 | |||
1155 | if (update_root) | ||
1156 | update_tasks_nodemask(root_cs, heap); | ||
1157 | 1141 | ||
1158 | rcu_read_lock(); | 1142 | rcu_read_lock(); |
1159 | cpuset_for_each_descendant_pre(cp, pos_cgrp, root_cs) { | 1143 | cpuset_for_each_descendant_pre(cp, pos_css, root_cs) { |
1160 | /* skip the whole subtree if @cp have some CPU */ | 1144 | if (cp == root_cs) { |
1161 | if (!nodes_empty(cp->mems_allowed)) { | 1145 | if (!update_root) |
1162 | pos_cgrp = cgroup_rightmost_descendant(pos_cgrp); | 1146 | continue; |
1163 | continue; | 1147 | } else { |
1148 | /* skip the whole subtree if @cp have some CPU */ | ||
1149 | if (!nodes_empty(cp->mems_allowed)) { | ||
1150 | pos_css = css_rightmost_descendant(pos_css); | ||
1151 | continue; | ||
1152 | } | ||
1164 | } | 1153 | } |
1165 | if (!css_tryget(&cp->css)) | 1154 | if (!css_tryget(&cp->css)) |
1166 | continue; | 1155 | continue; |
@@ -1267,44 +1256,39 @@ static int update_relax_domain_level(struct cpuset *cs, s64 val) | |||
1267 | return 0; | 1256 | return 0; |
1268 | } | 1257 | } |
1269 | 1258 | ||
1270 | /* | 1259 | /** |
1271 | * cpuset_change_flag - make a task's spread flags the same as its cpuset's | 1260 | * cpuset_change_flag - make a task's spread flags the same as its cpuset's |
1272 | * @tsk: task to be updated | 1261 | * @tsk: task to be updated |
1273 | * @scan: struct cgroup_scanner containing the cgroup of the task | 1262 | * @data: cpuset to @tsk belongs to |
1274 | * | 1263 | * |
1275 | * Called by cgroup_scan_tasks() for each task in a cgroup. | 1264 | * Called by css_scan_tasks() for each task in a cgroup. |
1276 | * | 1265 | * |
1277 | * We don't need to re-check for the cgroup/cpuset membership, since we're | 1266 | * We don't need to re-check for the cgroup/cpuset membership, since we're |
1278 | * holding cpuset_mutex at this point. | 1267 | * holding cpuset_mutex at this point. |
1279 | */ | 1268 | */ |
1280 | static void cpuset_change_flag(struct task_struct *tsk, | 1269 | static void cpuset_change_flag(struct task_struct *tsk, void *data) |
1281 | struct cgroup_scanner *scan) | ||
1282 | { | 1270 | { |
1283 | cpuset_update_task_spread_flag(cgroup_cs(scan->cg), tsk); | 1271 | struct cpuset *cs = data; |
1272 | |||
1273 | cpuset_update_task_spread_flag(cs, tsk); | ||
1284 | } | 1274 | } |
1285 | 1275 | ||
1286 | /* | 1276 | /** |
1287 | * update_tasks_flags - update the spread flags of tasks in the cpuset. | 1277 | * update_tasks_flags - update the spread flags of tasks in the cpuset. |
1288 | * @cs: the cpuset in which each task's spread flags needs to be changed | 1278 | * @cs: the cpuset in which each task's spread flags needs to be changed |
1289 | * @heap: if NULL, defer allocating heap memory to cgroup_scan_tasks() | 1279 | * @heap: if NULL, defer allocating heap memory to css_scan_tasks() |
1290 | * | 1280 | * |
1291 | * Called with cpuset_mutex held | 1281 | * Called with cpuset_mutex held |
1292 | * | 1282 | * |
1293 | * The cgroup_scan_tasks() function will scan all the tasks in a cgroup, | 1283 | * The css_scan_tasks() function will scan all the tasks in a cgroup, |
1294 | * calling callback functions for each. | 1284 | * calling callback functions for each. |
1295 | * | 1285 | * |
1296 | * No return value. It's guaranteed that cgroup_scan_tasks() always returns 0 | 1286 | * No return value. It's guaranteed that css_scan_tasks() always returns 0 |
1297 | * if @heap != NULL. | 1287 | * if @heap != NULL. |
1298 | */ | 1288 | */ |
1299 | static void update_tasks_flags(struct cpuset *cs, struct ptr_heap *heap) | 1289 | static void update_tasks_flags(struct cpuset *cs, struct ptr_heap *heap) |
1300 | { | 1290 | { |
1301 | struct cgroup_scanner scan; | 1291 | css_scan_tasks(&cs->css, NULL, cpuset_change_flag, cs, heap); |
1302 | |||
1303 | scan.cg = cs->css.cgroup; | ||
1304 | scan.test_task = NULL; | ||
1305 | scan.process_task = cpuset_change_flag; | ||
1306 | scan.heap = heap; | ||
1307 | cgroup_scan_tasks(&scan); | ||
1308 | } | 1292 | } |
1309 | 1293 | ||
1310 | /* | 1294 | /* |
@@ -1462,9 +1446,10 @@ static int fmeter_getrate(struct fmeter *fmp) | |||
1462 | } | 1446 | } |
1463 | 1447 | ||
1464 | /* Called by cgroups to determine if a cpuset is usable; cpuset_mutex held */ | 1448 | /* Called by cgroups to determine if a cpuset is usable; cpuset_mutex held */ |
1465 | static int cpuset_can_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) | 1449 | static int cpuset_can_attach(struct cgroup_subsys_state *css, |
1450 | struct cgroup_taskset *tset) | ||
1466 | { | 1451 | { |
1467 | struct cpuset *cs = cgroup_cs(cgrp); | 1452 | struct cpuset *cs = css_cs(css); |
1468 | struct task_struct *task; | 1453 | struct task_struct *task; |
1469 | int ret; | 1454 | int ret; |
1470 | 1455 | ||
@@ -1475,11 +1460,11 @@ static int cpuset_can_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) | |||
1475 | * flag is set. | 1460 | * flag is set. |
1476 | */ | 1461 | */ |
1477 | ret = -ENOSPC; | 1462 | ret = -ENOSPC; |
1478 | if (!cgroup_sane_behavior(cgrp) && | 1463 | if (!cgroup_sane_behavior(css->cgroup) && |
1479 | (cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed))) | 1464 | (cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed))) |
1480 | goto out_unlock; | 1465 | goto out_unlock; |
1481 | 1466 | ||
1482 | cgroup_taskset_for_each(task, cgrp, tset) { | 1467 | cgroup_taskset_for_each(task, css, tset) { |
1483 | /* | 1468 | /* |
1484 | * Kthreads which disallow setaffinity shouldn't be moved | 1469 | * Kthreads which disallow setaffinity shouldn't be moved |
1485 | * to a new cpuset; we don't want to change their cpu | 1470 | * to a new cpuset; we don't want to change their cpu |
@@ -1508,11 +1493,11 @@ out_unlock: | |||
1508 | return ret; | 1493 | return ret; |
1509 | } | 1494 | } |
1510 | 1495 | ||
1511 | static void cpuset_cancel_attach(struct cgroup *cgrp, | 1496 | static void cpuset_cancel_attach(struct cgroup_subsys_state *css, |
1512 | struct cgroup_taskset *tset) | 1497 | struct cgroup_taskset *tset) |
1513 | { | 1498 | { |
1514 | mutex_lock(&cpuset_mutex); | 1499 | mutex_lock(&cpuset_mutex); |
1515 | cgroup_cs(cgrp)->attach_in_progress--; | 1500 | css_cs(css)->attach_in_progress--; |
1516 | mutex_unlock(&cpuset_mutex); | 1501 | mutex_unlock(&cpuset_mutex); |
1517 | } | 1502 | } |
1518 | 1503 | ||
@@ -1523,16 +1508,18 @@ static void cpuset_cancel_attach(struct cgroup *cgrp, | |||
1523 | */ | 1508 | */ |
1524 | static cpumask_var_t cpus_attach; | 1509 | static cpumask_var_t cpus_attach; |
1525 | 1510 | ||
1526 | static void cpuset_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) | 1511 | static void cpuset_attach(struct cgroup_subsys_state *css, |
1512 | struct cgroup_taskset *tset) | ||
1527 | { | 1513 | { |
1528 | /* static buf protected by cpuset_mutex */ | 1514 | /* static buf protected by cpuset_mutex */ |
1529 | static nodemask_t cpuset_attach_nodemask_to; | 1515 | static nodemask_t cpuset_attach_nodemask_to; |
1530 | struct mm_struct *mm; | 1516 | struct mm_struct *mm; |
1531 | struct task_struct *task; | 1517 | struct task_struct *task; |
1532 | struct task_struct *leader = cgroup_taskset_first(tset); | 1518 | struct task_struct *leader = cgroup_taskset_first(tset); |
1533 | struct cgroup *oldcgrp = cgroup_taskset_cur_cgroup(tset); | 1519 | struct cgroup_subsys_state *oldcss = cgroup_taskset_cur_css(tset, |
1534 | struct cpuset *cs = cgroup_cs(cgrp); | 1520 | cpuset_subsys_id); |
1535 | struct cpuset *oldcs = cgroup_cs(oldcgrp); | 1521 | struct cpuset *cs = css_cs(css); |
1522 | struct cpuset *oldcs = css_cs(oldcss); | ||
1536 | struct cpuset *cpus_cs = effective_cpumask_cpuset(cs); | 1523 | struct cpuset *cpus_cs = effective_cpumask_cpuset(cs); |
1537 | struct cpuset *mems_cs = effective_nodemask_cpuset(cs); | 1524 | struct cpuset *mems_cs = effective_nodemask_cpuset(cs); |
1538 | 1525 | ||
@@ -1546,7 +1533,7 @@ static void cpuset_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) | |||
1546 | 1533 | ||
1547 | guarantee_online_mems(mems_cs, &cpuset_attach_nodemask_to); | 1534 | guarantee_online_mems(mems_cs, &cpuset_attach_nodemask_to); |
1548 | 1535 | ||
1549 | cgroup_taskset_for_each(task, cgrp, tset) { | 1536 | cgroup_taskset_for_each(task, css, tset) { |
1550 | /* | 1537 | /* |
1551 | * can_attach beforehand should guarantee that this doesn't | 1538 | * can_attach beforehand should guarantee that this doesn't |
1552 | * fail. TODO: have a better way to handle failure here | 1539 | * fail. TODO: have a better way to handle failure here |
@@ -1608,9 +1595,10 @@ typedef enum { | |||
1608 | FILE_SPREAD_SLAB, | 1595 | FILE_SPREAD_SLAB, |
1609 | } cpuset_filetype_t; | 1596 | } cpuset_filetype_t; |
1610 | 1597 | ||
1611 | static int cpuset_write_u64(struct cgroup *cgrp, struct cftype *cft, u64 val) | 1598 | static int cpuset_write_u64(struct cgroup_subsys_state *css, struct cftype *cft, |
1599 | u64 val) | ||
1612 | { | 1600 | { |
1613 | struct cpuset *cs = cgroup_cs(cgrp); | 1601 | struct cpuset *cs = css_cs(css); |
1614 | cpuset_filetype_t type = cft->private; | 1602 | cpuset_filetype_t type = cft->private; |
1615 | int retval = 0; | 1603 | int retval = 0; |
1616 | 1604 | ||
@@ -1657,9 +1645,10 @@ out_unlock: | |||
1657 | return retval; | 1645 | return retval; |
1658 | } | 1646 | } |
1659 | 1647 | ||
1660 | static int cpuset_write_s64(struct cgroup *cgrp, struct cftype *cft, s64 val) | 1648 | static int cpuset_write_s64(struct cgroup_subsys_state *css, struct cftype *cft, |
1649 | s64 val) | ||
1661 | { | 1650 | { |
1662 | struct cpuset *cs = cgroup_cs(cgrp); | 1651 | struct cpuset *cs = css_cs(css); |
1663 | cpuset_filetype_t type = cft->private; | 1652 | cpuset_filetype_t type = cft->private; |
1664 | int retval = -ENODEV; | 1653 | int retval = -ENODEV; |
1665 | 1654 | ||
@@ -1683,10 +1672,10 @@ out_unlock: | |||
1683 | /* | 1672 | /* |
1684 | * Common handling for a write to a "cpus" or "mems" file. | 1673 | * Common handling for a write to a "cpus" or "mems" file. |
1685 | */ | 1674 | */ |
1686 | static int cpuset_write_resmask(struct cgroup *cgrp, struct cftype *cft, | 1675 | static int cpuset_write_resmask(struct cgroup_subsys_state *css, |
1687 | const char *buf) | 1676 | struct cftype *cft, const char *buf) |
1688 | { | 1677 | { |
1689 | struct cpuset *cs = cgroup_cs(cgrp); | 1678 | struct cpuset *cs = css_cs(css); |
1690 | struct cpuset *trialcs; | 1679 | struct cpuset *trialcs; |
1691 | int retval = -ENODEV; | 1680 | int retval = -ENODEV; |
1692 | 1681 | ||
@@ -1765,13 +1754,12 @@ static size_t cpuset_sprintf_memlist(char *page, struct cpuset *cs) | |||
1765 | return count; | 1754 | return count; |
1766 | } | 1755 | } |
1767 | 1756 | ||
1768 | static ssize_t cpuset_common_file_read(struct cgroup *cgrp, | 1757 | static ssize_t cpuset_common_file_read(struct cgroup_subsys_state *css, |
1769 | struct cftype *cft, | 1758 | struct cftype *cft, struct file *file, |
1770 | struct file *file, | 1759 | char __user *buf, size_t nbytes, |
1771 | char __user *buf, | 1760 | loff_t *ppos) |
1772 | size_t nbytes, loff_t *ppos) | ||
1773 | { | 1761 | { |
1774 | struct cpuset *cs = cgroup_cs(cgrp); | 1762 | struct cpuset *cs = css_cs(css); |
1775 | cpuset_filetype_t type = cft->private; | 1763 | cpuset_filetype_t type = cft->private; |
1776 | char *page; | 1764 | char *page; |
1777 | ssize_t retval = 0; | 1765 | ssize_t retval = 0; |
@@ -1801,9 +1789,9 @@ out: | |||
1801 | return retval; | 1789 | return retval; |
1802 | } | 1790 | } |
1803 | 1791 | ||
1804 | static u64 cpuset_read_u64(struct cgroup *cgrp, struct cftype *cft) | 1792 | static u64 cpuset_read_u64(struct cgroup_subsys_state *css, struct cftype *cft) |
1805 | { | 1793 | { |
1806 | struct cpuset *cs = cgroup_cs(cgrp); | 1794 | struct cpuset *cs = css_cs(css); |
1807 | cpuset_filetype_t type = cft->private; | 1795 | cpuset_filetype_t type = cft->private; |
1808 | switch (type) { | 1796 | switch (type) { |
1809 | case FILE_CPU_EXCLUSIVE: | 1797 | case FILE_CPU_EXCLUSIVE: |
@@ -1832,9 +1820,9 @@ static u64 cpuset_read_u64(struct cgroup *cgrp, struct cftype *cft) | |||
1832 | return 0; | 1820 | return 0; |
1833 | } | 1821 | } |
1834 | 1822 | ||
1835 | static s64 cpuset_read_s64(struct cgroup *cgrp, struct cftype *cft) | 1823 | static s64 cpuset_read_s64(struct cgroup_subsys_state *css, struct cftype *cft) |
1836 | { | 1824 | { |
1837 | struct cpuset *cs = cgroup_cs(cgrp); | 1825 | struct cpuset *cs = css_cs(css); |
1838 | cpuset_filetype_t type = cft->private; | 1826 | cpuset_filetype_t type = cft->private; |
1839 | switch (type) { | 1827 | switch (type) { |
1840 | case FILE_SCHED_RELAX_DOMAIN_LEVEL: | 1828 | case FILE_SCHED_RELAX_DOMAIN_LEVEL: |
@@ -1949,11 +1937,12 @@ static struct cftype files[] = { | |||
1949 | * cgrp: control group that the new cpuset will be part of | 1937 | * cgrp: control group that the new cpuset will be part of |
1950 | */ | 1938 | */ |
1951 | 1939 | ||
1952 | static struct cgroup_subsys_state *cpuset_css_alloc(struct cgroup *cgrp) | 1940 | static struct cgroup_subsys_state * |
1941 | cpuset_css_alloc(struct cgroup_subsys_state *parent_css) | ||
1953 | { | 1942 | { |
1954 | struct cpuset *cs; | 1943 | struct cpuset *cs; |
1955 | 1944 | ||
1956 | if (!cgrp->parent) | 1945 | if (!parent_css) |
1957 | return &top_cpuset.css; | 1946 | return &top_cpuset.css; |
1958 | 1947 | ||
1959 | cs = kzalloc(sizeof(*cs), GFP_KERNEL); | 1948 | cs = kzalloc(sizeof(*cs), GFP_KERNEL); |
@@ -1973,12 +1962,12 @@ static struct cgroup_subsys_state *cpuset_css_alloc(struct cgroup *cgrp) | |||
1973 | return &cs->css; | 1962 | return &cs->css; |
1974 | } | 1963 | } |
1975 | 1964 | ||
1976 | static int cpuset_css_online(struct cgroup *cgrp) | 1965 | static int cpuset_css_online(struct cgroup_subsys_state *css) |
1977 | { | 1966 | { |
1978 | struct cpuset *cs = cgroup_cs(cgrp); | 1967 | struct cpuset *cs = css_cs(css); |
1979 | struct cpuset *parent = parent_cs(cs); | 1968 | struct cpuset *parent = parent_cs(cs); |
1980 | struct cpuset *tmp_cs; | 1969 | struct cpuset *tmp_cs; |
1981 | struct cgroup *pos_cg; | 1970 | struct cgroup_subsys_state *pos_css; |
1982 | 1971 | ||
1983 | if (!parent) | 1972 | if (!parent) |
1984 | return 0; | 1973 | return 0; |
@@ -1993,7 +1982,7 @@ static int cpuset_css_online(struct cgroup *cgrp) | |||
1993 | 1982 | ||
1994 | number_of_cpusets++; | 1983 | number_of_cpusets++; |
1995 | 1984 | ||
1996 | if (!test_bit(CGRP_CPUSET_CLONE_CHILDREN, &cgrp->flags)) | 1985 | if (!test_bit(CGRP_CPUSET_CLONE_CHILDREN, &css->cgroup->flags)) |
1997 | goto out_unlock; | 1986 | goto out_unlock; |
1998 | 1987 | ||
1999 | /* | 1988 | /* |
@@ -2010,7 +1999,7 @@ static int cpuset_css_online(struct cgroup *cgrp) | |||
2010 | * (and likewise for mems) to the new cgroup. | 1999 | * (and likewise for mems) to the new cgroup. |
2011 | */ | 2000 | */ |
2012 | rcu_read_lock(); | 2001 | rcu_read_lock(); |
2013 | cpuset_for_each_child(tmp_cs, pos_cg, parent) { | 2002 | cpuset_for_each_child(tmp_cs, pos_css, parent) { |
2014 | if (is_mem_exclusive(tmp_cs) || is_cpu_exclusive(tmp_cs)) { | 2003 | if (is_mem_exclusive(tmp_cs) || is_cpu_exclusive(tmp_cs)) { |
2015 | rcu_read_unlock(); | 2004 | rcu_read_unlock(); |
2016 | goto out_unlock; | 2005 | goto out_unlock; |
@@ -2027,9 +2016,15 @@ out_unlock: | |||
2027 | return 0; | 2016 | return 0; |
2028 | } | 2017 | } |
2029 | 2018 | ||
2030 | static void cpuset_css_offline(struct cgroup *cgrp) | 2019 | /* |
2020 | * If the cpuset being removed has its flag 'sched_load_balance' | ||
2021 | * enabled, then simulate turning sched_load_balance off, which | ||
2022 | * will call rebuild_sched_domains_locked(). | ||
2023 | */ | ||
2024 | |||
2025 | static void cpuset_css_offline(struct cgroup_subsys_state *css) | ||
2031 | { | 2026 | { |
2032 | struct cpuset *cs = cgroup_cs(cgrp); | 2027 | struct cpuset *cs = css_cs(css); |
2033 | 2028 | ||
2034 | mutex_lock(&cpuset_mutex); | 2029 | mutex_lock(&cpuset_mutex); |
2035 | 2030 | ||
@@ -2042,15 +2037,9 @@ static void cpuset_css_offline(struct cgroup *cgrp) | |||
2042 | mutex_unlock(&cpuset_mutex); | 2037 | mutex_unlock(&cpuset_mutex); |
2043 | } | 2038 | } |
2044 | 2039 | ||
2045 | /* | 2040 | static void cpuset_css_free(struct cgroup_subsys_state *css) |
2046 | * If the cpuset being removed has its flag 'sched_load_balance' | ||
2047 | * enabled, then simulate turning sched_load_balance off, which | ||
2048 | * will call rebuild_sched_domains_locked(). | ||
2049 | */ | ||
2050 | |||
2051 | static void cpuset_css_free(struct cgroup *cgrp) | ||
2052 | { | 2041 | { |
2053 | struct cpuset *cs = cgroup_cs(cgrp); | 2042 | struct cpuset *cs = css_cs(css); |
2054 | 2043 | ||
2055 | free_cpumask_var(cs->cpus_allowed); | 2044 | free_cpumask_var(cs->cpus_allowed); |
2056 | kfree(cs); | 2045 | kfree(cs); |
@@ -2257,11 +2246,11 @@ static void cpuset_hotplug_workfn(struct work_struct *work) | |||
2257 | /* if cpus or mems changed, we need to propagate to descendants */ | 2246 | /* if cpus or mems changed, we need to propagate to descendants */ |
2258 | if (cpus_updated || mems_updated) { | 2247 | if (cpus_updated || mems_updated) { |
2259 | struct cpuset *cs; | 2248 | struct cpuset *cs; |
2260 | struct cgroup *pos_cgrp; | 2249 | struct cgroup_subsys_state *pos_css; |
2261 | 2250 | ||
2262 | rcu_read_lock(); | 2251 | rcu_read_lock(); |
2263 | cpuset_for_each_descendant_pre(cs, pos_cgrp, &top_cpuset) { | 2252 | cpuset_for_each_descendant_pre(cs, pos_css, &top_cpuset) { |
2264 | if (!css_tryget(&cs->css)) | 2253 | if (cs == &top_cpuset || !css_tryget(&cs->css)) |
2265 | continue; | 2254 | continue; |
2266 | rcu_read_unlock(); | 2255 | rcu_read_unlock(); |
2267 | 2256 | ||
@@ -2350,7 +2339,7 @@ void cpuset_cpus_allowed(struct task_struct *tsk, struct cpumask *pmask) | |||
2350 | 2339 | ||
2351 | void cpuset_cpus_allowed_fallback(struct task_struct *tsk) | 2340 | void cpuset_cpus_allowed_fallback(struct task_struct *tsk) |
2352 | { | 2341 | { |
2353 | const struct cpuset *cpus_cs; | 2342 | struct cpuset *cpus_cs; |
2354 | 2343 | ||
2355 | rcu_read_lock(); | 2344 | rcu_read_lock(); |
2356 | cpus_cs = effective_cpumask_cpuset(task_cs(tsk)); | 2345 | cpus_cs = effective_cpumask_cpuset(task_cs(tsk)); |
@@ -2423,7 +2412,7 @@ int cpuset_nodemask_valid_mems_allowed(nodemask_t *nodemask) | |||
2423 | * callback_mutex. If no ancestor is mem_exclusive or mem_hardwall | 2412 | * callback_mutex. If no ancestor is mem_exclusive or mem_hardwall |
2424 | * (an unusual configuration), then returns the root cpuset. | 2413 | * (an unusual configuration), then returns the root cpuset. |
2425 | */ | 2414 | */ |
2426 | static const struct cpuset *nearest_hardwall_ancestor(const struct cpuset *cs) | 2415 | static struct cpuset *nearest_hardwall_ancestor(struct cpuset *cs) |
2427 | { | 2416 | { |
2428 | while (!(is_mem_exclusive(cs) || is_mem_hardwall(cs)) && parent_cs(cs)) | 2417 | while (!(is_mem_exclusive(cs) || is_mem_hardwall(cs)) && parent_cs(cs)) |
2429 | cs = parent_cs(cs); | 2418 | cs = parent_cs(cs); |
@@ -2493,7 +2482,7 @@ static const struct cpuset *nearest_hardwall_ancestor(const struct cpuset *cs) | |||
2493 | */ | 2482 | */ |
2494 | int __cpuset_node_allowed_softwall(int node, gfp_t gfp_mask) | 2483 | int __cpuset_node_allowed_softwall(int node, gfp_t gfp_mask) |
2495 | { | 2484 | { |
2496 | const struct cpuset *cs; /* current cpuset ancestors */ | 2485 | struct cpuset *cs; /* current cpuset ancestors */ |
2497 | int allowed; /* is allocation in zone z allowed? */ | 2486 | int allowed; /* is allocation in zone z allowed? */ |
2498 | 2487 | ||
2499 | if (in_interrupt() || (gfp_mask & __GFP_THISNODE)) | 2488 | if (in_interrupt() || (gfp_mask & __GFP_THISNODE)) |
@@ -2731,7 +2720,7 @@ int proc_cpuset_show(struct seq_file *m, void *unused_v) | |||
2731 | goto out_free; | 2720 | goto out_free; |
2732 | 2721 | ||
2733 | rcu_read_lock(); | 2722 | rcu_read_lock(); |
2734 | css = task_subsys_state(tsk, cpuset_subsys_id); | 2723 | css = task_css(tsk, cpuset_subsys_id); |
2735 | retval = cgroup_path(css->cgroup, buf, PAGE_SIZE); | 2724 | retval = cgroup_path(css->cgroup, buf, PAGE_SIZE); |
2736 | rcu_read_unlock(); | 2725 | rcu_read_unlock(); |
2737 | if (retval < 0) | 2726 | if (retval < 0) |