diff options
Diffstat (limited to 'kernel/cpuset.c')
-rw-r--r-- | kernel/cpuset.c | 262 |
1 files changed, 97 insertions, 165 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index f6fc7475f1a1..3d54c418bd06 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -119,7 +119,7 @@ static inline struct cpuset *css_cs(struct cgroup_subsys_state *css) | |||
119 | /* Retrieve the cpuset for a task */ | 119 | /* Retrieve the cpuset for a task */ |
120 | static inline struct cpuset *task_cs(struct task_struct *task) | 120 | static inline struct cpuset *task_cs(struct task_struct *task) |
121 | { | 121 | { |
122 | return css_cs(task_css(task, cpuset_subsys_id)); | 122 | return css_cs(task_css(task, cpuset_cgrp_id)); |
123 | } | 123 | } |
124 | 124 | ||
125 | static inline struct cpuset *parent_cs(struct cpuset *cs) | 125 | static inline struct cpuset *parent_cs(struct cpuset *cs) |
@@ -467,7 +467,7 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial) | |||
467 | * be changed to have empty cpus_allowed or mems_allowed. | 467 | * be changed to have empty cpus_allowed or mems_allowed. |
468 | */ | 468 | */ |
469 | ret = -ENOSPC; | 469 | ret = -ENOSPC; |
470 | if ((cgroup_task_count(cur->css.cgroup) || cur->attach_in_progress)) { | 470 | if ((cgroup_has_tasks(cur->css.cgroup) || cur->attach_in_progress)) { |
471 | if (!cpumask_empty(cur->cpus_allowed) && | 471 | if (!cpumask_empty(cur->cpus_allowed) && |
472 | cpumask_empty(trial->cpus_allowed)) | 472 | cpumask_empty(trial->cpus_allowed)) |
473 | goto out; | 473 | goto out; |
@@ -829,55 +829,36 @@ static struct cpuset *effective_nodemask_cpuset(struct cpuset *cs) | |||
829 | } | 829 | } |
830 | 830 | ||
831 | /** | 831 | /** |
832 | * cpuset_change_cpumask - make a task's cpus_allowed the same as its cpuset's | ||
833 | * @tsk: task to test | ||
834 | * @data: cpuset to @tsk belongs to | ||
835 | * | ||
836 | * Called by css_scan_tasks() for each task in a cgroup whose cpus_allowed | ||
837 | * mask needs to be changed. | ||
838 | * | ||
839 | * We don't need to re-check for the cgroup/cpuset membership, since we're | ||
840 | * holding cpuset_mutex at this point. | ||
841 | */ | ||
842 | static void cpuset_change_cpumask(struct task_struct *tsk, void *data) | ||
843 | { | ||
844 | struct cpuset *cs = data; | ||
845 | struct cpuset *cpus_cs = effective_cpumask_cpuset(cs); | ||
846 | |||
847 | set_cpus_allowed_ptr(tsk, cpus_cs->cpus_allowed); | ||
848 | } | ||
849 | |||
850 | /** | ||
851 | * update_tasks_cpumask - Update the cpumasks of tasks in the cpuset. | 832 | * update_tasks_cpumask - Update the cpumasks of tasks in the cpuset. |
852 | * @cs: the cpuset in which each task's cpus_allowed mask needs to be changed | 833 | * @cs: the cpuset in which each task's cpus_allowed mask needs to be changed |
853 | * @heap: if NULL, defer allocating heap memory to css_scan_tasks() | ||
854 | * | ||
855 | * Called with cpuset_mutex held | ||
856 | * | 834 | * |
857 | * The css_scan_tasks() function will scan all the tasks in a cgroup, | 835 | * Iterate through each task of @cs updating its cpus_allowed to the |
858 | * calling callback functions for each. | 836 | * effective cpuset's. As this function is called with cpuset_mutex held, |
859 | * | 837 | * cpuset membership stays stable. |
860 | * No return value. It's guaranteed that css_scan_tasks() always returns 0 | ||
861 | * if @heap != NULL. | ||
862 | */ | 838 | */ |
863 | static void update_tasks_cpumask(struct cpuset *cs, struct ptr_heap *heap) | 839 | static void update_tasks_cpumask(struct cpuset *cs) |
864 | { | 840 | { |
865 | css_scan_tasks(&cs->css, NULL, cpuset_change_cpumask, cs, heap); | 841 | struct cpuset *cpus_cs = effective_cpumask_cpuset(cs); |
842 | struct css_task_iter it; | ||
843 | struct task_struct *task; | ||
844 | |||
845 | css_task_iter_start(&cs->css, &it); | ||
846 | while ((task = css_task_iter_next(&it))) | ||
847 | set_cpus_allowed_ptr(task, cpus_cs->cpus_allowed); | ||
848 | css_task_iter_end(&it); | ||
866 | } | 849 | } |
867 | 850 | ||
868 | /* | 851 | /* |
869 | * update_tasks_cpumask_hier - Update the cpumasks of tasks in the hierarchy. | 852 | * update_tasks_cpumask_hier - Update the cpumasks of tasks in the hierarchy. |
870 | * @root_cs: the root cpuset of the hierarchy | 853 | * @root_cs: the root cpuset of the hierarchy |
871 | * @update_root: update root cpuset or not? | 854 | * @update_root: update root cpuset or not? |
872 | * @heap: the heap used by css_scan_tasks() | ||
873 | * | 855 | * |
874 | * This will update cpumasks of tasks in @root_cs and all other empty cpusets | 856 | * This will update cpumasks of tasks in @root_cs and all other empty cpusets |
875 | * which take on cpumask of @root_cs. | 857 | * which take on cpumask of @root_cs. |
876 | * | 858 | * |
877 | * Called with cpuset_mutex held | 859 | * Called with cpuset_mutex held |
878 | */ | 860 | */ |
879 | static void update_tasks_cpumask_hier(struct cpuset *root_cs, | 861 | static void update_tasks_cpumask_hier(struct cpuset *root_cs, bool update_root) |
880 | bool update_root, struct ptr_heap *heap) | ||
881 | { | 862 | { |
882 | struct cpuset *cp; | 863 | struct cpuset *cp; |
883 | struct cgroup_subsys_state *pos_css; | 864 | struct cgroup_subsys_state *pos_css; |
@@ -898,7 +879,7 @@ static void update_tasks_cpumask_hier(struct cpuset *root_cs, | |||
898 | continue; | 879 | continue; |
899 | rcu_read_unlock(); | 880 | rcu_read_unlock(); |
900 | 881 | ||
901 | update_tasks_cpumask(cp, heap); | 882 | update_tasks_cpumask(cp); |
902 | 883 | ||
903 | rcu_read_lock(); | 884 | rcu_read_lock(); |
904 | css_put(&cp->css); | 885 | css_put(&cp->css); |
@@ -914,7 +895,6 @@ static void update_tasks_cpumask_hier(struct cpuset *root_cs, | |||
914 | static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs, | 895 | static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs, |
915 | const char *buf) | 896 | const char *buf) |
916 | { | 897 | { |
917 | struct ptr_heap heap; | ||
918 | int retval; | 898 | int retval; |
919 | int is_load_balanced; | 899 | int is_load_balanced; |
920 | 900 | ||
@@ -947,19 +927,13 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs, | |||
947 | if (retval < 0) | 927 | if (retval < 0) |
948 | return retval; | 928 | return retval; |
949 | 929 | ||
950 | retval = heap_init(&heap, PAGE_SIZE, GFP_KERNEL, NULL); | ||
951 | if (retval) | ||
952 | return retval; | ||
953 | |||
954 | is_load_balanced = is_sched_load_balance(trialcs); | 930 | is_load_balanced = is_sched_load_balance(trialcs); |
955 | 931 | ||
956 | mutex_lock(&callback_mutex); | 932 | mutex_lock(&callback_mutex); |
957 | cpumask_copy(cs->cpus_allowed, trialcs->cpus_allowed); | 933 | cpumask_copy(cs->cpus_allowed, trialcs->cpus_allowed); |
958 | mutex_unlock(&callback_mutex); | 934 | mutex_unlock(&callback_mutex); |
959 | 935 | ||
960 | update_tasks_cpumask_hier(cs, true, &heap); | 936 | update_tasks_cpumask_hier(cs, true); |
961 | |||
962 | heap_free(&heap); | ||
963 | 937 | ||
964 | if (is_load_balanced) | 938 | if (is_load_balanced) |
965 | rebuild_sched_domains_locked(); | 939 | rebuild_sched_domains_locked(); |
@@ -1048,53 +1022,22 @@ static void cpuset_change_task_nodemask(struct task_struct *tsk, | |||
1048 | task_unlock(tsk); | 1022 | task_unlock(tsk); |
1049 | } | 1023 | } |
1050 | 1024 | ||
1051 | struct cpuset_change_nodemask_arg { | ||
1052 | struct cpuset *cs; | ||
1053 | nodemask_t *newmems; | ||
1054 | }; | ||
1055 | |||
1056 | /* | ||
1057 | * Update task's mems_allowed and rebind its mempolicy and vmas' mempolicy | ||
1058 | * of it to cpuset's new mems_allowed, and migrate pages to new nodes if | ||
1059 | * memory_migrate flag is set. Called with cpuset_mutex held. | ||
1060 | */ | ||
1061 | static void cpuset_change_nodemask(struct task_struct *p, void *data) | ||
1062 | { | ||
1063 | struct cpuset_change_nodemask_arg *arg = data; | ||
1064 | struct cpuset *cs = arg->cs; | ||
1065 | struct mm_struct *mm; | ||
1066 | int migrate; | ||
1067 | |||
1068 | cpuset_change_task_nodemask(p, arg->newmems); | ||
1069 | |||
1070 | mm = get_task_mm(p); | ||
1071 | if (!mm) | ||
1072 | return; | ||
1073 | |||
1074 | migrate = is_memory_migrate(cs); | ||
1075 | |||
1076 | mpol_rebind_mm(mm, &cs->mems_allowed); | ||
1077 | if (migrate) | ||
1078 | cpuset_migrate_mm(mm, &cs->old_mems_allowed, arg->newmems); | ||
1079 | mmput(mm); | ||
1080 | } | ||
1081 | |||
1082 | static void *cpuset_being_rebound; | 1025 | static void *cpuset_being_rebound; |
1083 | 1026 | ||
1084 | /** | 1027 | /** |
1085 | * update_tasks_nodemask - Update the nodemasks of tasks in the cpuset. | 1028 | * update_tasks_nodemask - Update the nodemasks of tasks in the cpuset. |
1086 | * @cs: the cpuset in which each task's mems_allowed mask needs to be changed | 1029 | * @cs: the cpuset in which each task's mems_allowed mask needs to be changed |
1087 | * @heap: if NULL, defer allocating heap memory to css_scan_tasks() | ||
1088 | * | 1030 | * |
1089 | * Called with cpuset_mutex held. No return value. It's guaranteed that | 1031 | * Iterate through each task of @cs updating its mems_allowed to the |
1090 | * css_scan_tasks() always returns 0 if @heap != NULL. | 1032 | * effective cpuset's. As this function is called with cpuset_mutex held, |
1033 | * cpuset membership stays stable. | ||
1091 | */ | 1034 | */ |
1092 | static void update_tasks_nodemask(struct cpuset *cs, struct ptr_heap *heap) | 1035 | static void update_tasks_nodemask(struct cpuset *cs) |
1093 | { | 1036 | { |
1094 | static nodemask_t newmems; /* protected by cpuset_mutex */ | 1037 | static nodemask_t newmems; /* protected by cpuset_mutex */ |
1095 | struct cpuset *mems_cs = effective_nodemask_cpuset(cs); | 1038 | struct cpuset *mems_cs = effective_nodemask_cpuset(cs); |
1096 | struct cpuset_change_nodemask_arg arg = { .cs = cs, | 1039 | struct css_task_iter it; |
1097 | .newmems = &newmems }; | 1040 | struct task_struct *task; |
1098 | 1041 | ||
1099 | cpuset_being_rebound = cs; /* causes mpol_dup() rebind */ | 1042 | cpuset_being_rebound = cs; /* causes mpol_dup() rebind */ |
1100 | 1043 | ||
@@ -1110,7 +1053,25 @@ static void update_tasks_nodemask(struct cpuset *cs, struct ptr_heap *heap) | |||
1110 | * It's ok if we rebind the same mm twice; mpol_rebind_mm() | 1053 | * It's ok if we rebind the same mm twice; mpol_rebind_mm() |
1111 | * is idempotent. Also migrate pages in each mm to new nodes. | 1054 | * is idempotent. Also migrate pages in each mm to new nodes. |
1112 | */ | 1055 | */ |
1113 | css_scan_tasks(&cs->css, NULL, cpuset_change_nodemask, &arg, heap); | 1056 | css_task_iter_start(&cs->css, &it); |
1057 | while ((task = css_task_iter_next(&it))) { | ||
1058 | struct mm_struct *mm; | ||
1059 | bool migrate; | ||
1060 | |||
1061 | cpuset_change_task_nodemask(task, &newmems); | ||
1062 | |||
1063 | mm = get_task_mm(task); | ||
1064 | if (!mm) | ||
1065 | continue; | ||
1066 | |||
1067 | migrate = is_memory_migrate(cs); | ||
1068 | |||
1069 | mpol_rebind_mm(mm, &cs->mems_allowed); | ||
1070 | if (migrate) | ||
1071 | cpuset_migrate_mm(mm, &cs->old_mems_allowed, &newmems); | ||
1072 | mmput(mm); | ||
1073 | } | ||
1074 | css_task_iter_end(&it); | ||
1114 | 1075 | ||
1115 | /* | 1076 | /* |
1116 | * All the tasks' nodemasks have been updated, update | 1077 | * All the tasks' nodemasks have been updated, update |
@@ -1126,15 +1087,13 @@ static void update_tasks_nodemask(struct cpuset *cs, struct ptr_heap *heap) | |||
1126 | * update_tasks_nodemask_hier - Update the nodemasks of tasks in the hierarchy. | 1087 | * update_tasks_nodemask_hier - Update the nodemasks of tasks in the hierarchy. |
1127 | * @cs: the root cpuset of the hierarchy | 1088 | * @cs: the root cpuset of the hierarchy |
1128 | * @update_root: update the root cpuset or not? | 1089 | * @update_root: update the root cpuset or not? |
1129 | * @heap: the heap used by css_scan_tasks() | ||
1130 | * | 1090 | * |
1131 | * This will update nodemasks of tasks in @root_cs and all other empty cpusets | 1091 | * This will update nodemasks of tasks in @root_cs and all other empty cpusets |
1132 | * which take on nodemask of @root_cs. | 1092 | * which take on nodemask of @root_cs. |
1133 | * | 1093 | * |
1134 | * Called with cpuset_mutex held | 1094 | * Called with cpuset_mutex held |
1135 | */ | 1095 | */ |
1136 | static void update_tasks_nodemask_hier(struct cpuset *root_cs, | 1096 | static void update_tasks_nodemask_hier(struct cpuset *root_cs, bool update_root) |
1137 | bool update_root, struct ptr_heap *heap) | ||
1138 | { | 1097 | { |
1139 | struct cpuset *cp; | 1098 | struct cpuset *cp; |
1140 | struct cgroup_subsys_state *pos_css; | 1099 | struct cgroup_subsys_state *pos_css; |
@@ -1155,7 +1114,7 @@ static void update_tasks_nodemask_hier(struct cpuset *root_cs, | |||
1155 | continue; | 1114 | continue; |
1156 | rcu_read_unlock(); | 1115 | rcu_read_unlock(); |
1157 | 1116 | ||
1158 | update_tasks_nodemask(cp, heap); | 1117 | update_tasks_nodemask(cp); |
1159 | 1118 | ||
1160 | rcu_read_lock(); | 1119 | rcu_read_lock(); |
1161 | css_put(&cp->css); | 1120 | css_put(&cp->css); |
@@ -1180,7 +1139,6 @@ static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs, | |||
1180 | const char *buf) | 1139 | const char *buf) |
1181 | { | 1140 | { |
1182 | int retval; | 1141 | int retval; |
1183 | struct ptr_heap heap; | ||
1184 | 1142 | ||
1185 | /* | 1143 | /* |
1186 | * top_cpuset.mems_allowed tracks node_stats[N_MEMORY]; | 1144 | * top_cpuset.mems_allowed tracks node_stats[N_MEMORY]; |
@@ -1219,17 +1177,11 @@ static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs, | |||
1219 | if (retval < 0) | 1177 | if (retval < 0) |
1220 | goto done; | 1178 | goto done; |
1221 | 1179 | ||
1222 | retval = heap_init(&heap, PAGE_SIZE, GFP_KERNEL, NULL); | ||
1223 | if (retval < 0) | ||
1224 | goto done; | ||
1225 | |||
1226 | mutex_lock(&callback_mutex); | 1180 | mutex_lock(&callback_mutex); |
1227 | cs->mems_allowed = trialcs->mems_allowed; | 1181 | cs->mems_allowed = trialcs->mems_allowed; |
1228 | mutex_unlock(&callback_mutex); | 1182 | mutex_unlock(&callback_mutex); |
1229 | 1183 | ||
1230 | update_tasks_nodemask_hier(cs, true, &heap); | 1184 | update_tasks_nodemask_hier(cs, true); |
1231 | |||
1232 | heap_free(&heap); | ||
1233 | done: | 1185 | done: |
1234 | return retval; | 1186 | return retval; |
1235 | } | 1187 | } |
@@ -1257,38 +1209,22 @@ static int update_relax_domain_level(struct cpuset *cs, s64 val) | |||
1257 | } | 1209 | } |
1258 | 1210 | ||
1259 | /** | 1211 | /** |
1260 | * cpuset_change_flag - make a task's spread flags the same as its cpuset's | ||
1261 | * @tsk: task to be updated | ||
1262 | * @data: cpuset to @tsk belongs to | ||
1263 | * | ||
1264 | * Called by css_scan_tasks() for each task in a cgroup. | ||
1265 | * | ||
1266 | * We don't need to re-check for the cgroup/cpuset membership, since we're | ||
1267 | * holding cpuset_mutex at this point. | ||
1268 | */ | ||
1269 | static void cpuset_change_flag(struct task_struct *tsk, void *data) | ||
1270 | { | ||
1271 | struct cpuset *cs = data; | ||
1272 | |||
1273 | cpuset_update_task_spread_flag(cs, tsk); | ||
1274 | } | ||
1275 | |||
1276 | /** | ||
1277 | * update_tasks_flags - update the spread flags of tasks in the cpuset. | 1212 | * update_tasks_flags - update the spread flags of tasks in the cpuset. |
1278 | * @cs: the cpuset in which each task's spread flags needs to be changed | 1213 | * @cs: the cpuset in which each task's spread flags needs to be changed |
1279 | * @heap: if NULL, defer allocating heap memory to css_scan_tasks() | ||
1280 | * | ||
1281 | * Called with cpuset_mutex held | ||
1282 | * | 1214 | * |
1283 | * The css_scan_tasks() function will scan all the tasks in a cgroup, | 1215 | * Iterate through each task of @cs updating its spread flags. As this |
1284 | * calling callback functions for each. | 1216 | * function is called with cpuset_mutex held, cpuset membership stays |
1285 | * | 1217 | * stable. |
1286 | * No return value. It's guaranteed that css_scan_tasks() always returns 0 | ||
1287 | * if @heap != NULL. | ||
1288 | */ | 1218 | */ |
1289 | static void update_tasks_flags(struct cpuset *cs, struct ptr_heap *heap) | 1219 | static void update_tasks_flags(struct cpuset *cs) |
1290 | { | 1220 | { |
1291 | css_scan_tasks(&cs->css, NULL, cpuset_change_flag, cs, heap); | 1221 | struct css_task_iter it; |
1222 | struct task_struct *task; | ||
1223 | |||
1224 | css_task_iter_start(&cs->css, &it); | ||
1225 | while ((task = css_task_iter_next(&it))) | ||
1226 | cpuset_update_task_spread_flag(cs, task); | ||
1227 | css_task_iter_end(&it); | ||
1292 | } | 1228 | } |
1293 | 1229 | ||
1294 | /* | 1230 | /* |
@@ -1306,7 +1242,6 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, | |||
1306 | struct cpuset *trialcs; | 1242 | struct cpuset *trialcs; |
1307 | int balance_flag_changed; | 1243 | int balance_flag_changed; |
1308 | int spread_flag_changed; | 1244 | int spread_flag_changed; |
1309 | struct ptr_heap heap; | ||
1310 | int err; | 1245 | int err; |
1311 | 1246 | ||
1312 | trialcs = alloc_trial_cpuset(cs); | 1247 | trialcs = alloc_trial_cpuset(cs); |
@@ -1322,10 +1257,6 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, | |||
1322 | if (err < 0) | 1257 | if (err < 0) |
1323 | goto out; | 1258 | goto out; |
1324 | 1259 | ||
1325 | err = heap_init(&heap, PAGE_SIZE, GFP_KERNEL, NULL); | ||
1326 | if (err < 0) | ||
1327 | goto out; | ||
1328 | |||
1329 | balance_flag_changed = (is_sched_load_balance(cs) != | 1260 | balance_flag_changed = (is_sched_load_balance(cs) != |
1330 | is_sched_load_balance(trialcs)); | 1261 | is_sched_load_balance(trialcs)); |
1331 | 1262 | ||
@@ -1340,8 +1271,7 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, | |||
1340 | rebuild_sched_domains_locked(); | 1271 | rebuild_sched_domains_locked(); |
1341 | 1272 | ||
1342 | if (spread_flag_changed) | 1273 | if (spread_flag_changed) |
1343 | update_tasks_flags(cs, &heap); | 1274 | update_tasks_flags(cs); |
1344 | heap_free(&heap); | ||
1345 | out: | 1275 | out: |
1346 | free_trial_cpuset(trialcs); | 1276 | free_trial_cpuset(trialcs); |
1347 | return err; | 1277 | return err; |
@@ -1445,6 +1375,8 @@ static int fmeter_getrate(struct fmeter *fmp) | |||
1445 | return val; | 1375 | return val; |
1446 | } | 1376 | } |
1447 | 1377 | ||
1378 | static struct cpuset *cpuset_attach_old_cs; | ||
1379 | |||
1448 | /* Called by cgroups to determine if a cpuset is usable; cpuset_mutex held */ | 1380 | /* Called by cgroups to determine if a cpuset is usable; cpuset_mutex held */ |
1449 | static int cpuset_can_attach(struct cgroup_subsys_state *css, | 1381 | static int cpuset_can_attach(struct cgroup_subsys_state *css, |
1450 | struct cgroup_taskset *tset) | 1382 | struct cgroup_taskset *tset) |
@@ -1453,6 +1385,9 @@ static int cpuset_can_attach(struct cgroup_subsys_state *css, | |||
1453 | struct task_struct *task; | 1385 | struct task_struct *task; |
1454 | int ret; | 1386 | int ret; |
1455 | 1387 | ||
1388 | /* used later by cpuset_attach() */ | ||
1389 | cpuset_attach_old_cs = task_cs(cgroup_taskset_first(tset)); | ||
1390 | |||
1456 | mutex_lock(&cpuset_mutex); | 1391 | mutex_lock(&cpuset_mutex); |
1457 | 1392 | ||
1458 | /* | 1393 | /* |
@@ -1464,7 +1399,7 @@ static int cpuset_can_attach(struct cgroup_subsys_state *css, | |||
1464 | (cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed))) | 1399 | (cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed))) |
1465 | goto out_unlock; | 1400 | goto out_unlock; |
1466 | 1401 | ||
1467 | cgroup_taskset_for_each(task, css, tset) { | 1402 | cgroup_taskset_for_each(task, tset) { |
1468 | /* | 1403 | /* |
1469 | * Kthreads which disallow setaffinity shouldn't be moved | 1404 | * Kthreads which disallow setaffinity shouldn't be moved |
1470 | * to a new cpuset; we don't want to change their cpu | 1405 | * to a new cpuset; we don't want to change their cpu |
@@ -1516,10 +1451,8 @@ static void cpuset_attach(struct cgroup_subsys_state *css, | |||
1516 | struct mm_struct *mm; | 1451 | struct mm_struct *mm; |
1517 | struct task_struct *task; | 1452 | struct task_struct *task; |
1518 | struct task_struct *leader = cgroup_taskset_first(tset); | 1453 | struct task_struct *leader = cgroup_taskset_first(tset); |
1519 | struct cgroup_subsys_state *oldcss = cgroup_taskset_cur_css(tset, | ||
1520 | cpuset_subsys_id); | ||
1521 | struct cpuset *cs = css_cs(css); | 1454 | struct cpuset *cs = css_cs(css); |
1522 | struct cpuset *oldcs = css_cs(oldcss); | 1455 | struct cpuset *oldcs = cpuset_attach_old_cs; |
1523 | struct cpuset *cpus_cs = effective_cpumask_cpuset(cs); | 1456 | struct cpuset *cpus_cs = effective_cpumask_cpuset(cs); |
1524 | struct cpuset *mems_cs = effective_nodemask_cpuset(cs); | 1457 | struct cpuset *mems_cs = effective_nodemask_cpuset(cs); |
1525 | 1458 | ||
@@ -1533,7 +1466,7 @@ static void cpuset_attach(struct cgroup_subsys_state *css, | |||
1533 | 1466 | ||
1534 | guarantee_online_mems(mems_cs, &cpuset_attach_nodemask_to); | 1467 | guarantee_online_mems(mems_cs, &cpuset_attach_nodemask_to); |
1535 | 1468 | ||
1536 | cgroup_taskset_for_each(task, css, tset) { | 1469 | cgroup_taskset_for_each(task, tset) { |
1537 | /* | 1470 | /* |
1538 | * can_attach beforehand should guarantee that this doesn't | 1471 | * can_attach beforehand should guarantee that this doesn't |
1539 | * fail. TODO: have a better way to handle failure here | 1472 | * fail. TODO: have a better way to handle failure here |
@@ -1673,7 +1606,7 @@ out_unlock: | |||
1673 | * Common handling for a write to a "cpus" or "mems" file. | 1606 | * Common handling for a write to a "cpus" or "mems" file. |
1674 | */ | 1607 | */ |
1675 | static int cpuset_write_resmask(struct cgroup_subsys_state *css, | 1608 | static int cpuset_write_resmask(struct cgroup_subsys_state *css, |
1676 | struct cftype *cft, const char *buf) | 1609 | struct cftype *cft, char *buf) |
1677 | { | 1610 | { |
1678 | struct cpuset *cs = css_cs(css); | 1611 | struct cpuset *cs = css_cs(css); |
1679 | struct cpuset *trialcs; | 1612 | struct cpuset *trialcs; |
@@ -2020,8 +1953,7 @@ static void cpuset_css_free(struct cgroup_subsys_state *css) | |||
2020 | kfree(cs); | 1953 | kfree(cs); |
2021 | } | 1954 | } |
2022 | 1955 | ||
2023 | struct cgroup_subsys cpuset_subsys = { | 1956 | struct cgroup_subsys cpuset_cgrp_subsys = { |
2024 | .name = "cpuset", | ||
2025 | .css_alloc = cpuset_css_alloc, | 1957 | .css_alloc = cpuset_css_alloc, |
2026 | .css_online = cpuset_css_online, | 1958 | .css_online = cpuset_css_online, |
2027 | .css_offline = cpuset_css_offline, | 1959 | .css_offline = cpuset_css_offline, |
@@ -2029,7 +1961,6 @@ struct cgroup_subsys cpuset_subsys = { | |||
2029 | .can_attach = cpuset_can_attach, | 1961 | .can_attach = cpuset_can_attach, |
2030 | .cancel_attach = cpuset_cancel_attach, | 1962 | .cancel_attach = cpuset_cancel_attach, |
2031 | .attach = cpuset_attach, | 1963 | .attach = cpuset_attach, |
2032 | .subsys_id = cpuset_subsys_id, | ||
2033 | .base_cftypes = files, | 1964 | .base_cftypes = files, |
2034 | .early_init = 1, | 1965 | .early_init = 1, |
2035 | }; | 1966 | }; |
@@ -2086,10 +2017,9 @@ static void remove_tasks_in_empty_cpuset(struct cpuset *cs) | |||
2086 | parent = parent_cs(parent); | 2017 | parent = parent_cs(parent); |
2087 | 2018 | ||
2088 | if (cgroup_transfer_tasks(parent->css.cgroup, cs->css.cgroup)) { | 2019 | if (cgroup_transfer_tasks(parent->css.cgroup, cs->css.cgroup)) { |
2089 | rcu_read_lock(); | 2020 | printk(KERN_ERR "cpuset: failed to transfer tasks out of empty cpuset "); |
2090 | printk(KERN_ERR "cpuset: failed to transfer tasks out of empty cpuset %s\n", | 2021 | pr_cont_cgroup_name(cs->css.cgroup); |
2091 | cgroup_name(cs->css.cgroup)); | 2022 | pr_cont("\n"); |
2092 | rcu_read_unlock(); | ||
2093 | } | 2023 | } |
2094 | } | 2024 | } |
2095 | 2025 | ||
@@ -2137,7 +2067,7 @@ retry: | |||
2137 | */ | 2067 | */ |
2138 | if ((sane && cpumask_empty(cs->cpus_allowed)) || | 2068 | if ((sane && cpumask_empty(cs->cpus_allowed)) || |
2139 | (!cpumask_empty(&off_cpus) && !cpumask_empty(cs->cpus_allowed))) | 2069 | (!cpumask_empty(&off_cpus) && !cpumask_empty(cs->cpus_allowed))) |
2140 | update_tasks_cpumask(cs, NULL); | 2070 | update_tasks_cpumask(cs); |
2141 | 2071 | ||
2142 | mutex_lock(&callback_mutex); | 2072 | mutex_lock(&callback_mutex); |
2143 | nodes_andnot(cs->mems_allowed, cs->mems_allowed, off_mems); | 2073 | nodes_andnot(cs->mems_allowed, cs->mems_allowed, off_mems); |
@@ -2151,7 +2081,7 @@ retry: | |||
2151 | */ | 2081 | */ |
2152 | if ((sane && nodes_empty(cs->mems_allowed)) || | 2082 | if ((sane && nodes_empty(cs->mems_allowed)) || |
2153 | (!nodes_empty(off_mems) && !nodes_empty(cs->mems_allowed))) | 2083 | (!nodes_empty(off_mems) && !nodes_empty(cs->mems_allowed))) |
2154 | update_tasks_nodemask(cs, NULL); | 2084 | update_tasks_nodemask(cs); |
2155 | 2085 | ||
2156 | is_empty = cpumask_empty(cs->cpus_allowed) || | 2086 | is_empty = cpumask_empty(cs->cpus_allowed) || |
2157 | nodes_empty(cs->mems_allowed); | 2087 | nodes_empty(cs->mems_allowed); |
@@ -2213,7 +2143,7 @@ static void cpuset_hotplug_workfn(struct work_struct *work) | |||
2213 | mutex_lock(&callback_mutex); | 2143 | mutex_lock(&callback_mutex); |
2214 | top_cpuset.mems_allowed = new_mems; | 2144 | top_cpuset.mems_allowed = new_mems; |
2215 | mutex_unlock(&callback_mutex); | 2145 | mutex_unlock(&callback_mutex); |
2216 | update_tasks_nodemask(&top_cpuset, NULL); | 2146 | update_tasks_nodemask(&top_cpuset); |
2217 | } | 2147 | } |
2218 | 2148 | ||
2219 | mutex_unlock(&cpuset_mutex); | 2149 | mutex_unlock(&cpuset_mutex); |
@@ -2305,10 +2235,10 @@ void cpuset_cpus_allowed(struct task_struct *tsk, struct cpumask *pmask) | |||
2305 | struct cpuset *cpus_cs; | 2235 | struct cpuset *cpus_cs; |
2306 | 2236 | ||
2307 | mutex_lock(&callback_mutex); | 2237 | mutex_lock(&callback_mutex); |
2308 | task_lock(tsk); | 2238 | rcu_read_lock(); |
2309 | cpus_cs = effective_cpumask_cpuset(task_cs(tsk)); | 2239 | cpus_cs = effective_cpumask_cpuset(task_cs(tsk)); |
2310 | guarantee_online_cpus(cpus_cs, pmask); | 2240 | guarantee_online_cpus(cpus_cs, pmask); |
2311 | task_unlock(tsk); | 2241 | rcu_read_unlock(); |
2312 | mutex_unlock(&callback_mutex); | 2242 | mutex_unlock(&callback_mutex); |
2313 | } | 2243 | } |
2314 | 2244 | ||
@@ -2361,10 +2291,10 @@ nodemask_t cpuset_mems_allowed(struct task_struct *tsk) | |||
2361 | nodemask_t mask; | 2291 | nodemask_t mask; |
2362 | 2292 | ||
2363 | mutex_lock(&callback_mutex); | 2293 | mutex_lock(&callback_mutex); |
2364 | task_lock(tsk); | 2294 | rcu_read_lock(); |
2365 | mems_cs = effective_nodemask_cpuset(task_cs(tsk)); | 2295 | mems_cs = effective_nodemask_cpuset(task_cs(tsk)); |
2366 | guarantee_online_mems(mems_cs, &mask); | 2296 | guarantee_online_mems(mems_cs, &mask); |
2367 | task_unlock(tsk); | 2297 | rcu_read_unlock(); |
2368 | mutex_unlock(&callback_mutex); | 2298 | mutex_unlock(&callback_mutex); |
2369 | 2299 | ||
2370 | return mask; | 2300 | return mask; |
@@ -2480,10 +2410,10 @@ int __cpuset_node_allowed_softwall(int node, gfp_t gfp_mask) | |||
2480 | /* Not hardwall and node outside mems_allowed: scan up cpusets */ | 2410 | /* Not hardwall and node outside mems_allowed: scan up cpusets */ |
2481 | mutex_lock(&callback_mutex); | 2411 | mutex_lock(&callback_mutex); |
2482 | 2412 | ||
2483 | task_lock(current); | 2413 | rcu_read_lock(); |
2484 | cs = nearest_hardwall_ancestor(task_cs(current)); | 2414 | cs = nearest_hardwall_ancestor(task_cs(current)); |
2485 | allowed = node_isset(node, cs->mems_allowed); | 2415 | allowed = node_isset(node, cs->mems_allowed); |
2486 | task_unlock(current); | 2416 | rcu_read_unlock(); |
2487 | 2417 | ||
2488 | mutex_unlock(&callback_mutex); | 2418 | mutex_unlock(&callback_mutex); |
2489 | return allowed; | 2419 | return allowed; |
@@ -2609,27 +2539,27 @@ int cpuset_mems_allowed_intersects(const struct task_struct *tsk1, | |||
2609 | * @task: pointer to task_struct of some task. | 2539 | * @task: pointer to task_struct of some task. |
2610 | * | 2540 | * |
2611 | * Description: Prints @task's name, cpuset name, and cached copy of its | 2541 | * Description: Prints @task's name, cpuset name, and cached copy of its |
2612 | * mems_allowed to the kernel log. Must hold task_lock(task) to allow | 2542 | * mems_allowed to the kernel log. |
2613 | * dereferencing task_cs(task). | ||
2614 | */ | 2543 | */ |
2615 | void cpuset_print_task_mems_allowed(struct task_struct *tsk) | 2544 | void cpuset_print_task_mems_allowed(struct task_struct *tsk) |
2616 | { | 2545 | { |
2617 | /* Statically allocated to prevent using excess stack. */ | 2546 | /* Statically allocated to prevent using excess stack. */ |
2618 | static char cpuset_nodelist[CPUSET_NODELIST_LEN]; | 2547 | static char cpuset_nodelist[CPUSET_NODELIST_LEN]; |
2619 | static DEFINE_SPINLOCK(cpuset_buffer_lock); | 2548 | static DEFINE_SPINLOCK(cpuset_buffer_lock); |
2549 | struct cgroup *cgrp; | ||
2620 | 2550 | ||
2621 | struct cgroup *cgrp = task_cs(tsk)->css.cgroup; | ||
2622 | |||
2623 | rcu_read_lock(); | ||
2624 | spin_lock(&cpuset_buffer_lock); | 2551 | spin_lock(&cpuset_buffer_lock); |
2552 | rcu_read_lock(); | ||
2625 | 2553 | ||
2554 | cgrp = task_cs(tsk)->css.cgroup; | ||
2626 | nodelist_scnprintf(cpuset_nodelist, CPUSET_NODELIST_LEN, | 2555 | nodelist_scnprintf(cpuset_nodelist, CPUSET_NODELIST_LEN, |
2627 | tsk->mems_allowed); | 2556 | tsk->mems_allowed); |
2628 | printk(KERN_INFO "%s cpuset=%s mems_allowed=%s\n", | 2557 | printk(KERN_INFO "%s cpuset=", tsk->comm); |
2629 | tsk->comm, cgroup_name(cgrp), cpuset_nodelist); | 2558 | pr_cont_cgroup_name(cgrp); |
2559 | pr_cont(" mems_allowed=%s\n", cpuset_nodelist); | ||
2630 | 2560 | ||
2631 | spin_unlock(&cpuset_buffer_lock); | ||
2632 | rcu_read_unlock(); | 2561 | rcu_read_unlock(); |
2562 | spin_unlock(&cpuset_buffer_lock); | ||
2633 | } | 2563 | } |
2634 | 2564 | ||
2635 | /* | 2565 | /* |
@@ -2660,9 +2590,9 @@ int cpuset_memory_pressure_enabled __read_mostly; | |||
2660 | 2590 | ||
2661 | void __cpuset_memory_pressure_bump(void) | 2591 | void __cpuset_memory_pressure_bump(void) |
2662 | { | 2592 | { |
2663 | task_lock(current); | 2593 | rcu_read_lock(); |
2664 | fmeter_markevent(&task_cs(current)->fmeter); | 2594 | fmeter_markevent(&task_cs(current)->fmeter); |
2665 | task_unlock(current); | 2595 | rcu_read_unlock(); |
2666 | } | 2596 | } |
2667 | 2597 | ||
2668 | #ifdef CONFIG_PROC_PID_CPUSET | 2598 | #ifdef CONFIG_PROC_PID_CPUSET |
@@ -2679,12 +2609,12 @@ int proc_cpuset_show(struct seq_file *m, void *unused_v) | |||
2679 | { | 2609 | { |
2680 | struct pid *pid; | 2610 | struct pid *pid; |
2681 | struct task_struct *tsk; | 2611 | struct task_struct *tsk; |
2682 | char *buf; | 2612 | char *buf, *p; |
2683 | struct cgroup_subsys_state *css; | 2613 | struct cgroup_subsys_state *css; |
2684 | int retval; | 2614 | int retval; |
2685 | 2615 | ||
2686 | retval = -ENOMEM; | 2616 | retval = -ENOMEM; |
2687 | buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | 2617 | buf = kmalloc(PATH_MAX, GFP_KERNEL); |
2688 | if (!buf) | 2618 | if (!buf) |
2689 | goto out; | 2619 | goto out; |
2690 | 2620 | ||
@@ -2694,14 +2624,16 @@ int proc_cpuset_show(struct seq_file *m, void *unused_v) | |||
2694 | if (!tsk) | 2624 | if (!tsk) |
2695 | goto out_free; | 2625 | goto out_free; |
2696 | 2626 | ||
2627 | retval = -ENAMETOOLONG; | ||
2697 | rcu_read_lock(); | 2628 | rcu_read_lock(); |
2698 | css = task_css(tsk, cpuset_subsys_id); | 2629 | css = task_css(tsk, cpuset_cgrp_id); |
2699 | retval = cgroup_path(css->cgroup, buf, PAGE_SIZE); | 2630 | p = cgroup_path(css->cgroup, buf, PATH_MAX); |
2700 | rcu_read_unlock(); | 2631 | rcu_read_unlock(); |
2701 | if (retval < 0) | 2632 | if (!p) |
2702 | goto out_put_task; | 2633 | goto out_put_task; |
2703 | seq_puts(m, buf); | 2634 | seq_puts(m, p); |
2704 | seq_putc(m, '\n'); | 2635 | seq_putc(m, '\n'); |
2636 | retval = 0; | ||
2705 | out_put_task: | 2637 | out_put_task: |
2706 | put_task_struct(tsk); | 2638 | put_task_struct(tsk); |
2707 | out_free: | 2639 | out_free: |