diff options
author | Tejun Heo <tj@kernel.org> | 2014-02-13 06:58:40 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2014-02-13 06:58:40 -0500 |
commit | d66393e54e0a9dc743e440eb36c58bd1158a560e (patch) | |
tree | 62aa7143ecca51903919ede1cee8f8802c79f042 /kernel/cpuset.c | |
parent | 96d365e0b86ee7ec6366c99669687e54c9f145e3 (diff) |
cpuset: use css_task_iter_start/next/end() instead of css_scan_tasks()
Now that css_task_iter_start/next_end() supports blocking while
iterating, there's no reason to use css_scan_tasks() which is more
cumbersome to use and scheduled to be removed.
Convert all css_scan_tasks() usages in cpuset to
css_task_iter_start/next/end(). This simplifies the code by removing
heap allocation and callbacks.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
Diffstat (limited to 'kernel/cpuset.c')
-rw-r--r-- | kernel/cpuset.c | 186 |
1 files changed, 58 insertions, 128 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index ae190b0a196a..65ae0bdf4af8 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -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 | * | ||
857 | * The css_scan_tasks() function will scan all the tasks in a cgroup, | ||
858 | * calling callback functions for each. | ||
859 | * | 834 | * |
860 | * No return value. It's guaranteed that css_scan_tasks() always returns 0 | 835 | * Iterate through each task of @cs updating its cpus_allowed to the |
861 | * if @heap != NULL. | 836 | * effective cpuset's. As this function is called with cpuset_mutex held, |
837 | * cpuset membership stays stable. | ||
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(); |
@@ -1052,53 +1026,22 @@ static void cpuset_change_task_nodemask(struct task_struct *tsk, | |||
1052 | task_unlock(tsk); | 1026 | task_unlock(tsk); |
1053 | } | 1027 | } |
1054 | 1028 | ||
1055 | struct cpuset_change_nodemask_arg { | ||
1056 | struct cpuset *cs; | ||
1057 | nodemask_t *newmems; | ||
1058 | }; | ||
1059 | |||
1060 | /* | ||
1061 | * Update task's mems_allowed and rebind its mempolicy and vmas' mempolicy | ||
1062 | * of it to cpuset's new mems_allowed, and migrate pages to new nodes if | ||
1063 | * memory_migrate flag is set. Called with cpuset_mutex held. | ||
1064 | */ | ||
1065 | static void cpuset_change_nodemask(struct task_struct *p, void *data) | ||
1066 | { | ||
1067 | struct cpuset_change_nodemask_arg *arg = data; | ||
1068 | struct cpuset *cs = arg->cs; | ||
1069 | struct mm_struct *mm; | ||
1070 | int migrate; | ||
1071 | |||
1072 | cpuset_change_task_nodemask(p, arg->newmems); | ||
1073 | |||
1074 | mm = get_task_mm(p); | ||
1075 | if (!mm) | ||
1076 | return; | ||
1077 | |||
1078 | migrate = is_memory_migrate(cs); | ||
1079 | |||
1080 | mpol_rebind_mm(mm, &cs->mems_allowed); | ||
1081 | if (migrate) | ||
1082 | cpuset_migrate_mm(mm, &cs->old_mems_allowed, arg->newmems); | ||
1083 | mmput(mm); | ||
1084 | } | ||
1085 | |||
1086 | static void *cpuset_being_rebound; | 1029 | static void *cpuset_being_rebound; |
1087 | 1030 | ||
1088 | /** | 1031 | /** |
1089 | * update_tasks_nodemask - Update the nodemasks of tasks in the cpuset. | 1032 | * update_tasks_nodemask - Update the nodemasks of tasks in the cpuset. |
1090 | * @cs: the cpuset in which each task's mems_allowed mask needs to be changed | 1033 | * @cs: the cpuset in which each task's mems_allowed mask needs to be changed |
1091 | * @heap: if NULL, defer allocating heap memory to css_scan_tasks() | ||
1092 | * | 1034 | * |
1093 | * Called with cpuset_mutex held. No return value. It's guaranteed that | 1035 | * Iterate through each task of @cs updating its mems_allowed to the |
1094 | * css_scan_tasks() always returns 0 if @heap != NULL. | 1036 | * effective cpuset's. As this function is called with cpuset_mutex held, |
1037 | * cpuset membership stays stable. | ||
1095 | */ | 1038 | */ |
1096 | static void update_tasks_nodemask(struct cpuset *cs, struct ptr_heap *heap) | 1039 | static void update_tasks_nodemask(struct cpuset *cs) |
1097 | { | 1040 | { |
1098 | static nodemask_t newmems; /* protected by cpuset_mutex */ | 1041 | static nodemask_t newmems; /* protected by cpuset_mutex */ |
1099 | struct cpuset *mems_cs = effective_nodemask_cpuset(cs); | 1042 | struct cpuset *mems_cs = effective_nodemask_cpuset(cs); |
1100 | struct cpuset_change_nodemask_arg arg = { .cs = cs, | 1043 | struct css_task_iter it; |
1101 | .newmems = &newmems }; | 1044 | struct task_struct *task; |
1102 | 1045 | ||
1103 | cpuset_being_rebound = cs; /* causes mpol_dup() rebind */ | 1046 | cpuset_being_rebound = cs; /* causes mpol_dup() rebind */ |
1104 | 1047 | ||
@@ -1114,7 +1057,25 @@ static void update_tasks_nodemask(struct cpuset *cs, struct ptr_heap *heap) | |||
1114 | * It's ok if we rebind the same mm twice; mpol_rebind_mm() | 1057 | * It's ok if we rebind the same mm twice; mpol_rebind_mm() |
1115 | * is idempotent. Also migrate pages in each mm to new nodes. | 1058 | * is idempotent. Also migrate pages in each mm to new nodes. |
1116 | */ | 1059 | */ |
1117 | css_scan_tasks(&cs->css, NULL, cpuset_change_nodemask, &arg, heap); | 1060 | css_task_iter_start(&cs->css, &it); |
1061 | while ((task = css_task_iter_next(&it))) { | ||
1062 | struct mm_struct *mm; | ||
1063 | bool migrate; | ||
1064 | |||
1065 | cpuset_change_task_nodemask(task, &newmems); | ||
1066 | |||
1067 | mm = get_task_mm(task); | ||
1068 | if (!mm) | ||
1069 | continue; | ||
1070 | |||
1071 | migrate = is_memory_migrate(cs); | ||
1072 | |||
1073 | mpol_rebind_mm(mm, &cs->mems_allowed); | ||
1074 | if (migrate) | ||
1075 | cpuset_migrate_mm(mm, &cs->old_mems_allowed, &newmems); | ||
1076 | mmput(mm); | ||
1077 | } | ||
1078 | css_task_iter_end(&it); | ||
1118 | 1079 | ||
1119 | /* | 1080 | /* |
1120 | * All the tasks' nodemasks have been updated, update | 1081 | * All the tasks' nodemasks have been updated, update |
@@ -1130,15 +1091,13 @@ static void update_tasks_nodemask(struct cpuset *cs, struct ptr_heap *heap) | |||
1130 | * update_tasks_nodemask_hier - Update the nodemasks of tasks in the hierarchy. | 1091 | * update_tasks_nodemask_hier - Update the nodemasks of tasks in the hierarchy. |
1131 | * @cs: the root cpuset of the hierarchy | 1092 | * @cs: the root cpuset of the hierarchy |
1132 | * @update_root: update the root cpuset or not? | 1093 | * @update_root: update the root cpuset or not? |
1133 | * @heap: the heap used by css_scan_tasks() | ||
1134 | * | 1094 | * |
1135 | * This will update nodemasks of tasks in @root_cs and all other empty cpusets | 1095 | * This will update nodemasks of tasks in @root_cs and all other empty cpusets |
1136 | * which take on nodemask of @root_cs. | 1096 | * which take on nodemask of @root_cs. |
1137 | * | 1097 | * |
1138 | * Called with cpuset_mutex held | 1098 | * Called with cpuset_mutex held |
1139 | */ | 1099 | */ |
1140 | static void update_tasks_nodemask_hier(struct cpuset *root_cs, | 1100 | static void update_tasks_nodemask_hier(struct cpuset *root_cs, bool update_root) |
1141 | bool update_root, struct ptr_heap *heap) | ||
1142 | { | 1101 | { |
1143 | struct cpuset *cp; | 1102 | struct cpuset *cp; |
1144 | struct cgroup_subsys_state *pos_css; | 1103 | struct cgroup_subsys_state *pos_css; |
@@ -1159,7 +1118,7 @@ static void update_tasks_nodemask_hier(struct cpuset *root_cs, | |||
1159 | continue; | 1118 | continue; |
1160 | rcu_read_unlock(); | 1119 | rcu_read_unlock(); |
1161 | 1120 | ||
1162 | update_tasks_nodemask(cp, heap); | 1121 | update_tasks_nodemask(cp); |
1163 | 1122 | ||
1164 | rcu_read_lock(); | 1123 | rcu_read_lock(); |
1165 | css_put(&cp->css); | 1124 | css_put(&cp->css); |
@@ -1184,7 +1143,6 @@ static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs, | |||
1184 | const char *buf) | 1143 | const char *buf) |
1185 | { | 1144 | { |
1186 | int retval; | 1145 | int retval; |
1187 | struct ptr_heap heap; | ||
1188 | 1146 | ||
1189 | /* | 1147 | /* |
1190 | * top_cpuset.mems_allowed tracks node_stats[N_MEMORY]; | 1148 | * top_cpuset.mems_allowed tracks node_stats[N_MEMORY]; |
@@ -1223,17 +1181,11 @@ static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs, | |||
1223 | if (retval < 0) | 1181 | if (retval < 0) |
1224 | goto done; | 1182 | goto done; |
1225 | 1183 | ||
1226 | retval = heap_init(&heap, PAGE_SIZE, GFP_KERNEL, NULL); | ||
1227 | if (retval < 0) | ||
1228 | goto done; | ||
1229 | |||
1230 | mutex_lock(&callback_mutex); | 1184 | mutex_lock(&callback_mutex); |
1231 | cs->mems_allowed = trialcs->mems_allowed; | 1185 | cs->mems_allowed = trialcs->mems_allowed; |
1232 | mutex_unlock(&callback_mutex); | 1186 | mutex_unlock(&callback_mutex); |
1233 | 1187 | ||
1234 | update_tasks_nodemask_hier(cs, true, &heap); | 1188 | update_tasks_nodemask_hier(cs, true); |
1235 | |||
1236 | heap_free(&heap); | ||
1237 | done: | 1189 | done: |
1238 | return retval; | 1190 | return retval; |
1239 | } | 1191 | } |
@@ -1261,38 +1213,22 @@ static int update_relax_domain_level(struct cpuset *cs, s64 val) | |||
1261 | } | 1213 | } |
1262 | 1214 | ||
1263 | /** | 1215 | /** |
1264 | * cpuset_change_flag - make a task's spread flags the same as its cpuset's | ||
1265 | * @tsk: task to be updated | ||
1266 | * @data: cpuset to @tsk belongs to | ||
1267 | * | ||
1268 | * Called by css_scan_tasks() for each task in a cgroup. | ||
1269 | * | ||
1270 | * We don't need to re-check for the cgroup/cpuset membership, since we're | ||
1271 | * holding cpuset_mutex at this point. | ||
1272 | */ | ||
1273 | static void cpuset_change_flag(struct task_struct *tsk, void *data) | ||
1274 | { | ||
1275 | struct cpuset *cs = data; | ||
1276 | |||
1277 | cpuset_update_task_spread_flag(cs, tsk); | ||
1278 | } | ||
1279 | |||
1280 | /** | ||
1281 | * update_tasks_flags - update the spread flags of tasks in the cpuset. | 1216 | * update_tasks_flags - update the spread flags of tasks in the cpuset. |
1282 | * @cs: the cpuset in which each task's spread flags needs to be changed | 1217 | * @cs: the cpuset in which each task's spread flags needs to be changed |
1283 | * @heap: if NULL, defer allocating heap memory to css_scan_tasks() | ||
1284 | * | ||
1285 | * Called with cpuset_mutex held | ||
1286 | * | 1218 | * |
1287 | * The css_scan_tasks() function will scan all the tasks in a cgroup, | 1219 | * Iterate through each task of @cs updating its spread flags. As this |
1288 | * calling callback functions for each. | 1220 | * function is called with cpuset_mutex held, cpuset membership stays |
1289 | * | 1221 | * stable. |
1290 | * No return value. It's guaranteed that css_scan_tasks() always returns 0 | ||
1291 | * if @heap != NULL. | ||
1292 | */ | 1222 | */ |
1293 | static void update_tasks_flags(struct cpuset *cs, struct ptr_heap *heap) | 1223 | static void update_tasks_flags(struct cpuset *cs) |
1294 | { | 1224 | { |
1295 | css_scan_tasks(&cs->css, NULL, cpuset_change_flag, cs, heap); | 1225 | struct css_task_iter it; |
1226 | struct task_struct *task; | ||
1227 | |||
1228 | css_task_iter_start(&cs->css, &it); | ||
1229 | while ((task = css_task_iter_next(&it))) | ||
1230 | cpuset_update_task_spread_flag(cs, task); | ||
1231 | css_task_iter_end(&it); | ||
1296 | } | 1232 | } |
1297 | 1233 | ||
1298 | /* | 1234 | /* |
@@ -1310,7 +1246,6 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, | |||
1310 | struct cpuset *trialcs; | 1246 | struct cpuset *trialcs; |
1311 | int balance_flag_changed; | 1247 | int balance_flag_changed; |
1312 | int spread_flag_changed; | 1248 | int spread_flag_changed; |
1313 | struct ptr_heap heap; | ||
1314 | int err; | 1249 | int err; |
1315 | 1250 | ||
1316 | trialcs = alloc_trial_cpuset(cs); | 1251 | trialcs = alloc_trial_cpuset(cs); |
@@ -1326,10 +1261,6 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, | |||
1326 | if (err < 0) | 1261 | if (err < 0) |
1327 | goto out; | 1262 | goto out; |
1328 | 1263 | ||
1329 | err = heap_init(&heap, PAGE_SIZE, GFP_KERNEL, NULL); | ||
1330 | if (err < 0) | ||
1331 | goto out; | ||
1332 | |||
1333 | balance_flag_changed = (is_sched_load_balance(cs) != | 1264 | balance_flag_changed = (is_sched_load_balance(cs) != |
1334 | is_sched_load_balance(trialcs)); | 1265 | is_sched_load_balance(trialcs)); |
1335 | 1266 | ||
@@ -1344,8 +1275,7 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, | |||
1344 | rebuild_sched_domains_locked(); | 1275 | rebuild_sched_domains_locked(); |
1345 | 1276 | ||
1346 | if (spread_flag_changed) | 1277 | if (spread_flag_changed) |
1347 | update_tasks_flags(cs, &heap); | 1278 | update_tasks_flags(cs); |
1348 | heap_free(&heap); | ||
1349 | out: | 1279 | out: |
1350 | free_trial_cpuset(trialcs); | 1280 | free_trial_cpuset(trialcs); |
1351 | return err; | 1281 | return err; |
@@ -2138,7 +2068,7 @@ retry: | |||
2138 | */ | 2068 | */ |
2139 | if ((sane && cpumask_empty(cs->cpus_allowed)) || | 2069 | if ((sane && cpumask_empty(cs->cpus_allowed)) || |
2140 | (!cpumask_empty(&off_cpus) && !cpumask_empty(cs->cpus_allowed))) | 2070 | (!cpumask_empty(&off_cpus) && !cpumask_empty(cs->cpus_allowed))) |
2141 | update_tasks_cpumask(cs, NULL); | 2071 | update_tasks_cpumask(cs); |
2142 | 2072 | ||
2143 | mutex_lock(&callback_mutex); | 2073 | mutex_lock(&callback_mutex); |
2144 | nodes_andnot(cs->mems_allowed, cs->mems_allowed, off_mems); | 2074 | nodes_andnot(cs->mems_allowed, cs->mems_allowed, off_mems); |
@@ -2152,7 +2082,7 @@ retry: | |||
2152 | */ | 2082 | */ |
2153 | if ((sane && nodes_empty(cs->mems_allowed)) || | 2083 | if ((sane && nodes_empty(cs->mems_allowed)) || |
2154 | (!nodes_empty(off_mems) && !nodes_empty(cs->mems_allowed))) | 2084 | (!nodes_empty(off_mems) && !nodes_empty(cs->mems_allowed))) |
2155 | update_tasks_nodemask(cs, NULL); | 2085 | update_tasks_nodemask(cs); |
2156 | 2086 | ||
2157 | is_empty = cpumask_empty(cs->cpus_allowed) || | 2087 | is_empty = cpumask_empty(cs->cpus_allowed) || |
2158 | nodes_empty(cs->mems_allowed); | 2088 | nodes_empty(cs->mems_allowed); |
@@ -2214,7 +2144,7 @@ static void cpuset_hotplug_workfn(struct work_struct *work) | |||
2214 | mutex_lock(&callback_mutex); | 2144 | mutex_lock(&callback_mutex); |
2215 | top_cpuset.mems_allowed = new_mems; | 2145 | top_cpuset.mems_allowed = new_mems; |
2216 | mutex_unlock(&callback_mutex); | 2146 | mutex_unlock(&callback_mutex); |
2217 | update_tasks_nodemask(&top_cpuset, NULL); | 2147 | update_tasks_nodemask(&top_cpuset); |
2218 | } | 2148 | } |
2219 | 2149 | ||
2220 | mutex_unlock(&cpuset_mutex); | 2150 | mutex_unlock(&cpuset_mutex); |