diff options
Diffstat (limited to 'kernel/cpuset.c')
-rw-r--r-- | kernel/cpuset.c | 260 |
1 files changed, 115 insertions, 145 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index d5a7e17474ee..7e75a41bd508 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -97,12 +97,6 @@ struct cpuset { | |||
97 | 97 | ||
98 | struct cpuset *parent; /* my parent */ | 98 | struct cpuset *parent; /* my parent */ |
99 | 99 | ||
100 | /* | ||
101 | * Copy of global cpuset_mems_generation as of the most | ||
102 | * recent time this cpuset changed its mems_allowed. | ||
103 | */ | ||
104 | int mems_generation; | ||
105 | |||
106 | struct fmeter fmeter; /* memory_pressure filter */ | 100 | struct fmeter fmeter; /* memory_pressure filter */ |
107 | 101 | ||
108 | /* partition number for rebuild_sched_domains() */ | 102 | /* partition number for rebuild_sched_domains() */ |
@@ -176,27 +170,6 @@ static inline int is_spread_slab(const struct cpuset *cs) | |||
176 | return test_bit(CS_SPREAD_SLAB, &cs->flags); | 170 | return test_bit(CS_SPREAD_SLAB, &cs->flags); |
177 | } | 171 | } |
178 | 172 | ||
179 | /* | ||
180 | * Increment this integer everytime any cpuset changes its | ||
181 | * mems_allowed value. Users of cpusets can track this generation | ||
182 | * number, and avoid having to lock and reload mems_allowed unless | ||
183 | * the cpuset they're using changes generation. | ||
184 | * | ||
185 | * A single, global generation is needed because cpuset_attach_task() could | ||
186 | * reattach a task to a different cpuset, which must not have its | ||
187 | * generation numbers aliased with those of that tasks previous cpuset. | ||
188 | * | ||
189 | * Generations are needed for mems_allowed because one task cannot | ||
190 | * modify another's memory placement. So we must enable every task, | ||
191 | * on every visit to __alloc_pages(), to efficiently check whether | ||
192 | * its current->cpuset->mems_allowed has changed, requiring an update | ||
193 | * of its current->mems_allowed. | ||
194 | * | ||
195 | * Since writes to cpuset_mems_generation are guarded by the cgroup lock | ||
196 | * there is no need to mark it atomic. | ||
197 | */ | ||
198 | static int cpuset_mems_generation; | ||
199 | |||
200 | static struct cpuset top_cpuset = { | 173 | static struct cpuset top_cpuset = { |
201 | .flags = ((1 << CS_CPU_EXCLUSIVE) | (1 << CS_MEM_EXCLUSIVE)), | 174 | .flags = ((1 << CS_CPU_EXCLUSIVE) | (1 << CS_MEM_EXCLUSIVE)), |
202 | }; | 175 | }; |
@@ -228,8 +201,9 @@ static struct cpuset top_cpuset = { | |||
228 | * If a task is only holding callback_mutex, then it has read-only | 201 | * If a task is only holding callback_mutex, then it has read-only |
229 | * access to cpusets. | 202 | * access to cpusets. |
230 | * | 203 | * |
231 | * The task_struct fields mems_allowed and mems_generation may only | 204 | * Now, the task_struct fields mems_allowed and mempolicy may be changed |
232 | * be accessed in the context of that task, so require no locks. | 205 | * by other task, we use alloc_lock in the task_struct fields to protect |
206 | * them. | ||
233 | * | 207 | * |
234 | * The cpuset_common_file_read() handlers only hold callback_mutex across | 208 | * The cpuset_common_file_read() handlers only hold callback_mutex across |
235 | * small pieces of code, such as when reading out possibly multi-word | 209 | * small pieces of code, such as when reading out possibly multi-word |
@@ -331,75 +305,22 @@ static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask) | |||
331 | BUG_ON(!nodes_intersects(*pmask, node_states[N_HIGH_MEMORY])); | 305 | BUG_ON(!nodes_intersects(*pmask, node_states[N_HIGH_MEMORY])); |
332 | } | 306 | } |
333 | 307 | ||
334 | /** | 308 | /* |
335 | * cpuset_update_task_memory_state - update task memory placement | 309 | * update task's spread flag if cpuset's page/slab spread flag is set |
336 | * | 310 | * |
337 | * If the current tasks cpusets mems_allowed changed behind our | 311 | * Called with callback_mutex/cgroup_mutex held |
338 | * backs, update current->mems_allowed, mems_generation and task NUMA | ||
339 | * mempolicy to the new value. | ||
340 | * | ||
341 | * Task mempolicy is updated by rebinding it relative to the | ||
342 | * current->cpuset if a task has its memory placement changed. | ||
343 | * Do not call this routine if in_interrupt(). | ||
344 | * | ||
345 | * Call without callback_mutex or task_lock() held. May be | ||
346 | * called with or without cgroup_mutex held. Thanks in part to | ||
347 | * 'the_top_cpuset_hack', the task's cpuset pointer will never | ||
348 | * be NULL. This routine also might acquire callback_mutex during | ||
349 | * call. | ||
350 | * | ||
351 | * Reading current->cpuset->mems_generation doesn't need task_lock | ||
352 | * to guard the current->cpuset derefence, because it is guarded | ||
353 | * from concurrent freeing of current->cpuset using RCU. | ||
354 | * | ||
355 | * The rcu_dereference() is technically probably not needed, | ||
356 | * as I don't actually mind if I see a new cpuset pointer but | ||
357 | * an old value of mems_generation. However this really only | ||
358 | * matters on alpha systems using cpusets heavily. If I dropped | ||
359 | * that rcu_dereference(), it would save them a memory barrier. | ||
360 | * For all other arch's, rcu_dereference is a no-op anyway, and for | ||
361 | * alpha systems not using cpusets, another planned optimization, | ||
362 | * avoiding the rcu critical section for tasks in the root cpuset | ||
363 | * which is statically allocated, so can't vanish, will make this | ||
364 | * irrelevant. Better to use RCU as intended, than to engage in | ||
365 | * some cute trick to save a memory barrier that is impossible to | ||
366 | * test, for alpha systems using cpusets heavily, which might not | ||
367 | * even exist. | ||
368 | * | ||
369 | * This routine is needed to update the per-task mems_allowed data, | ||
370 | * within the tasks context, when it is trying to allocate memory | ||
371 | * (in various mm/mempolicy.c routines) and notices that some other | ||
372 | * task has been modifying its cpuset. | ||
373 | */ | 312 | */ |
374 | 313 | static void cpuset_update_task_spread_flag(struct cpuset *cs, | |
375 | void cpuset_update_task_memory_state(void) | 314 | struct task_struct *tsk) |
376 | { | 315 | { |
377 | int my_cpusets_mem_gen; | 316 | if (is_spread_page(cs)) |
378 | struct task_struct *tsk = current; | 317 | tsk->flags |= PF_SPREAD_PAGE; |
379 | struct cpuset *cs; | 318 | else |
380 | 319 | tsk->flags &= ~PF_SPREAD_PAGE; | |
381 | rcu_read_lock(); | 320 | if (is_spread_slab(cs)) |
382 | my_cpusets_mem_gen = task_cs(tsk)->mems_generation; | 321 | tsk->flags |= PF_SPREAD_SLAB; |
383 | rcu_read_unlock(); | 322 | else |
384 | 323 | tsk->flags &= ~PF_SPREAD_SLAB; | |
385 | if (my_cpusets_mem_gen != tsk->cpuset_mems_generation) { | ||
386 | mutex_lock(&callback_mutex); | ||
387 | task_lock(tsk); | ||
388 | cs = task_cs(tsk); /* Maybe changed when task not locked */ | ||
389 | guarantee_online_mems(cs, &tsk->mems_allowed); | ||
390 | tsk->cpuset_mems_generation = cs->mems_generation; | ||
391 | if (is_spread_page(cs)) | ||
392 | tsk->flags |= PF_SPREAD_PAGE; | ||
393 | else | ||
394 | tsk->flags &= ~PF_SPREAD_PAGE; | ||
395 | if (is_spread_slab(cs)) | ||
396 | tsk->flags |= PF_SPREAD_SLAB; | ||
397 | else | ||
398 | tsk->flags &= ~PF_SPREAD_SLAB; | ||
399 | task_unlock(tsk); | ||
400 | mutex_unlock(&callback_mutex); | ||
401 | mpol_rebind_task(tsk, &tsk->mems_allowed); | ||
402 | } | ||
403 | } | 324 | } |
404 | 325 | ||
405 | /* | 326 | /* |
@@ -1007,14 +928,6 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs, | |||
1007 | * other task, the task_struct mems_allowed that we are hacking | 928 | * other task, the task_struct mems_allowed that we are hacking |
1008 | * is for our current task, which must allocate new pages for that | 929 | * is for our current task, which must allocate new pages for that |
1009 | * migrating memory region. | 930 | * migrating memory region. |
1010 | * | ||
1011 | * We call cpuset_update_task_memory_state() before hacking | ||
1012 | * our tasks mems_allowed, so that we are assured of being in | ||
1013 | * sync with our tasks cpuset, and in particular, callbacks to | ||
1014 | * cpuset_update_task_memory_state() from nested page allocations | ||
1015 | * won't see any mismatch of our cpuset and task mems_generation | ||
1016 | * values, so won't overwrite our hacked tasks mems_allowed | ||
1017 | * nodemask. | ||
1018 | */ | 931 | */ |
1019 | 932 | ||
1020 | static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from, | 933 | static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from, |
@@ -1022,22 +935,37 @@ static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from, | |||
1022 | { | 935 | { |
1023 | struct task_struct *tsk = current; | 936 | struct task_struct *tsk = current; |
1024 | 937 | ||
1025 | cpuset_update_task_memory_state(); | ||
1026 | |||
1027 | mutex_lock(&callback_mutex); | ||
1028 | tsk->mems_allowed = *to; | 938 | tsk->mems_allowed = *to; |
1029 | mutex_unlock(&callback_mutex); | ||
1030 | 939 | ||
1031 | do_migrate_pages(mm, from, to, MPOL_MF_MOVE_ALL); | 940 | do_migrate_pages(mm, from, to, MPOL_MF_MOVE_ALL); |
1032 | 941 | ||
1033 | mutex_lock(&callback_mutex); | ||
1034 | guarantee_online_mems(task_cs(tsk),&tsk->mems_allowed); | 942 | guarantee_online_mems(task_cs(tsk),&tsk->mems_allowed); |
1035 | mutex_unlock(&callback_mutex); | ||
1036 | } | 943 | } |
1037 | 944 | ||
1038 | /* | 945 | /* |
1039 | * Rebind task's vmas to cpuset's new mems_allowed, and migrate pages to new | 946 | * cpuset_change_task_nodemask - change task's mems_allowed and mempolicy |
1040 | * nodes if memory_migrate flag is set. Called with cgroup_mutex held. | 947 | * @tsk: the task to change |
948 | * @newmems: new nodes that the task will be set | ||
949 | * | ||
950 | * In order to avoid seeing no nodes if the old and new nodes are disjoint, | ||
951 | * we structure updates as setting all new allowed nodes, then clearing newly | ||
952 | * disallowed ones. | ||
953 | * | ||
954 | * Called with task's alloc_lock held | ||
955 | */ | ||
956 | static void cpuset_change_task_nodemask(struct task_struct *tsk, | ||
957 | nodemask_t *newmems) | ||
958 | { | ||
959 | nodes_or(tsk->mems_allowed, tsk->mems_allowed, *newmems); | ||
960 | mpol_rebind_task(tsk, &tsk->mems_allowed); | ||
961 | mpol_rebind_task(tsk, newmems); | ||
962 | tsk->mems_allowed = *newmems; | ||
963 | } | ||
964 | |||
965 | /* | ||
966 | * Update task's mems_allowed and rebind its mempolicy and vmas' mempolicy | ||
967 | * of it to cpuset's new mems_allowed, and migrate pages to new nodes if | ||
968 | * memory_migrate flag is set. Called with cgroup_mutex held. | ||
1041 | */ | 969 | */ |
1042 | static void cpuset_change_nodemask(struct task_struct *p, | 970 | static void cpuset_change_nodemask(struct task_struct *p, |
1043 | struct cgroup_scanner *scan) | 971 | struct cgroup_scanner *scan) |
@@ -1046,12 +974,19 @@ static void cpuset_change_nodemask(struct task_struct *p, | |||
1046 | struct cpuset *cs; | 974 | struct cpuset *cs; |
1047 | int migrate; | 975 | int migrate; |
1048 | const nodemask_t *oldmem = scan->data; | 976 | const nodemask_t *oldmem = scan->data; |
977 | nodemask_t newmems; | ||
978 | |||
979 | cs = cgroup_cs(scan->cg); | ||
980 | guarantee_online_mems(cs, &newmems); | ||
981 | |||
982 | task_lock(p); | ||
983 | cpuset_change_task_nodemask(p, &newmems); | ||
984 | task_unlock(p); | ||
1049 | 985 | ||
1050 | mm = get_task_mm(p); | 986 | mm = get_task_mm(p); |
1051 | if (!mm) | 987 | if (!mm) |
1052 | return; | 988 | return; |
1053 | 989 | ||
1054 | cs = cgroup_cs(scan->cg); | ||
1055 | migrate = is_memory_migrate(cs); | 990 | migrate = is_memory_migrate(cs); |
1056 | 991 | ||
1057 | mpol_rebind_mm(mm, &cs->mems_allowed); | 992 | mpol_rebind_mm(mm, &cs->mems_allowed); |
@@ -1104,10 +1039,10 @@ static void update_tasks_nodemask(struct cpuset *cs, const nodemask_t *oldmem, | |||
1104 | /* | 1039 | /* |
1105 | * Handle user request to change the 'mems' memory placement | 1040 | * Handle user request to change the 'mems' memory placement |
1106 | * of a cpuset. Needs to validate the request, update the | 1041 | * of a cpuset. Needs to validate the request, update the |
1107 | * cpusets mems_allowed and mems_generation, and for each | 1042 | * cpusets mems_allowed, and for each task in the cpuset, |
1108 | * task in the cpuset, rebind any vma mempolicies and if | 1043 | * update mems_allowed and rebind task's mempolicy and any vma |
1109 | * the cpuset is marked 'memory_migrate', migrate the tasks | 1044 | * mempolicies and if the cpuset is marked 'memory_migrate', |
1110 | * pages to the new memory. | 1045 | * migrate the tasks pages to the new memory. |
1111 | * | 1046 | * |
1112 | * Call with cgroup_mutex held. May take callback_mutex during call. | 1047 | * Call with cgroup_mutex held. May take callback_mutex during call. |
1113 | * Will take tasklist_lock, scan tasklist for tasks in cpuset cs, | 1048 | * Will take tasklist_lock, scan tasklist for tasks in cpuset cs, |
@@ -1160,7 +1095,6 @@ static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs, | |||
1160 | 1095 | ||
1161 | mutex_lock(&callback_mutex); | 1096 | mutex_lock(&callback_mutex); |
1162 | cs->mems_allowed = trialcs->mems_allowed; | 1097 | cs->mems_allowed = trialcs->mems_allowed; |
1163 | cs->mems_generation = cpuset_mems_generation++; | ||
1164 | mutex_unlock(&callback_mutex); | 1098 | mutex_unlock(&callback_mutex); |
1165 | 1099 | ||
1166 | update_tasks_nodemask(cs, &oldmem, &heap); | 1100 | update_tasks_nodemask(cs, &oldmem, &heap); |
@@ -1193,6 +1127,46 @@ static int update_relax_domain_level(struct cpuset *cs, s64 val) | |||
1193 | } | 1127 | } |
1194 | 1128 | ||
1195 | /* | 1129 | /* |
1130 | * cpuset_change_flag - make a task's spread flags the same as its cpuset's | ||
1131 | * @tsk: task to be updated | ||
1132 | * @scan: struct cgroup_scanner containing the cgroup of the task | ||
1133 | * | ||
1134 | * Called by cgroup_scan_tasks() for each task in a cgroup. | ||
1135 | * | ||
1136 | * We don't need to re-check for the cgroup/cpuset membership, since we're | ||
1137 | * holding cgroup_lock() at this point. | ||
1138 | */ | ||
1139 | static void cpuset_change_flag(struct task_struct *tsk, | ||
1140 | struct cgroup_scanner *scan) | ||
1141 | { | ||
1142 | cpuset_update_task_spread_flag(cgroup_cs(scan->cg), tsk); | ||
1143 | } | ||
1144 | |||
1145 | /* | ||
1146 | * update_tasks_flags - update the spread flags of tasks in the cpuset. | ||
1147 | * @cs: the cpuset in which each task's spread flags needs to be changed | ||
1148 | * @heap: if NULL, defer allocating heap memory to cgroup_scan_tasks() | ||
1149 | * | ||
1150 | * Called with cgroup_mutex held | ||
1151 | * | ||
1152 | * The cgroup_scan_tasks() function will scan all the tasks in a cgroup, | ||
1153 | * calling callback functions for each. | ||
1154 | * | ||
1155 | * No return value. It's guaranteed that cgroup_scan_tasks() always returns 0 | ||
1156 | * if @heap != NULL. | ||
1157 | */ | ||
1158 | static void update_tasks_flags(struct cpuset *cs, struct ptr_heap *heap) | ||
1159 | { | ||
1160 | struct cgroup_scanner scan; | ||
1161 | |||
1162 | scan.cg = cs->css.cgroup; | ||
1163 | scan.test_task = NULL; | ||
1164 | scan.process_task = cpuset_change_flag; | ||
1165 | scan.heap = heap; | ||
1166 | cgroup_scan_tasks(&scan); | ||
1167 | } | ||
1168 | |||
1169 | /* | ||
1196 | * update_flag - read a 0 or a 1 in a file and update associated flag | 1170 | * update_flag - read a 0 or a 1 in a file and update associated flag |
1197 | * bit: the bit to update (see cpuset_flagbits_t) | 1171 | * bit: the bit to update (see cpuset_flagbits_t) |
1198 | * cs: the cpuset to update | 1172 | * cs: the cpuset to update |
@@ -1205,8 +1179,10 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, | |||
1205 | int turning_on) | 1179 | int turning_on) |
1206 | { | 1180 | { |
1207 | struct cpuset *trialcs; | 1181 | struct cpuset *trialcs; |
1208 | int err; | ||
1209 | int balance_flag_changed; | 1182 | int balance_flag_changed; |
1183 | int spread_flag_changed; | ||
1184 | struct ptr_heap heap; | ||
1185 | int err; | ||
1210 | 1186 | ||
1211 | trialcs = alloc_trial_cpuset(cs); | 1187 | trialcs = alloc_trial_cpuset(cs); |
1212 | if (!trialcs) | 1188 | if (!trialcs) |
@@ -1221,9 +1197,16 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, | |||
1221 | if (err < 0) | 1197 | if (err < 0) |
1222 | goto out; | 1198 | goto out; |
1223 | 1199 | ||
1200 | err = heap_init(&heap, PAGE_SIZE, GFP_KERNEL, NULL); | ||
1201 | if (err < 0) | ||
1202 | goto out; | ||
1203 | |||
1224 | balance_flag_changed = (is_sched_load_balance(cs) != | 1204 | balance_flag_changed = (is_sched_load_balance(cs) != |
1225 | is_sched_load_balance(trialcs)); | 1205 | is_sched_load_balance(trialcs)); |
1226 | 1206 | ||
1207 | spread_flag_changed = ((is_spread_slab(cs) != is_spread_slab(trialcs)) | ||
1208 | || (is_spread_page(cs) != is_spread_page(trialcs))); | ||
1209 | |||
1227 | mutex_lock(&callback_mutex); | 1210 | mutex_lock(&callback_mutex); |
1228 | cs->flags = trialcs->flags; | 1211 | cs->flags = trialcs->flags; |
1229 | mutex_unlock(&callback_mutex); | 1212 | mutex_unlock(&callback_mutex); |
@@ -1231,6 +1214,9 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, | |||
1231 | if (!cpumask_empty(trialcs->cpus_allowed) && balance_flag_changed) | 1214 | if (!cpumask_empty(trialcs->cpus_allowed) && balance_flag_changed) |
1232 | async_rebuild_sched_domains(); | 1215 | async_rebuild_sched_domains(); |
1233 | 1216 | ||
1217 | if (spread_flag_changed) | ||
1218 | update_tasks_flags(cs, &heap); | ||
1219 | heap_free(&heap); | ||
1234 | out: | 1220 | out: |
1235 | free_trial_cpuset(trialcs); | 1221 | free_trial_cpuset(trialcs); |
1236 | return err; | 1222 | return err; |
@@ -1372,15 +1358,20 @@ static void cpuset_attach(struct cgroup_subsys *ss, | |||
1372 | 1358 | ||
1373 | if (cs == &top_cpuset) { | 1359 | if (cs == &top_cpuset) { |
1374 | cpumask_copy(cpus_attach, cpu_possible_mask); | 1360 | cpumask_copy(cpus_attach, cpu_possible_mask); |
1361 | to = node_possible_map; | ||
1375 | } else { | 1362 | } else { |
1376 | mutex_lock(&callback_mutex); | ||
1377 | guarantee_online_cpus(cs, cpus_attach); | 1363 | guarantee_online_cpus(cs, cpus_attach); |
1378 | mutex_unlock(&callback_mutex); | 1364 | guarantee_online_mems(cs, &to); |
1379 | } | 1365 | } |
1380 | err = set_cpus_allowed_ptr(tsk, cpus_attach); | 1366 | err = set_cpus_allowed_ptr(tsk, cpus_attach); |
1381 | if (err) | 1367 | if (err) |
1382 | return; | 1368 | return; |
1383 | 1369 | ||
1370 | task_lock(tsk); | ||
1371 | cpuset_change_task_nodemask(tsk, &to); | ||
1372 | task_unlock(tsk); | ||
1373 | cpuset_update_task_spread_flag(cs, tsk); | ||
1374 | |||
1384 | from = oldcs->mems_allowed; | 1375 | from = oldcs->mems_allowed; |
1385 | to = cs->mems_allowed; | 1376 | to = cs->mems_allowed; |
1386 | mm = get_task_mm(tsk); | 1377 | mm = get_task_mm(tsk); |
@@ -1442,11 +1433,9 @@ static int cpuset_write_u64(struct cgroup *cgrp, struct cftype *cft, u64 val) | |||
1442 | break; | 1433 | break; |
1443 | case FILE_SPREAD_PAGE: | 1434 | case FILE_SPREAD_PAGE: |
1444 | retval = update_flag(CS_SPREAD_PAGE, cs, val); | 1435 | retval = update_flag(CS_SPREAD_PAGE, cs, val); |
1445 | cs->mems_generation = cpuset_mems_generation++; | ||
1446 | break; | 1436 | break; |
1447 | case FILE_SPREAD_SLAB: | 1437 | case FILE_SPREAD_SLAB: |
1448 | retval = update_flag(CS_SPREAD_SLAB, cs, val); | 1438 | retval = update_flag(CS_SPREAD_SLAB, cs, val); |
1449 | cs->mems_generation = cpuset_mems_generation++; | ||
1450 | break; | 1439 | break; |
1451 | default: | 1440 | default: |
1452 | retval = -EINVAL; | 1441 | retval = -EINVAL; |
@@ -1786,8 +1775,6 @@ static struct cgroup_subsys_state *cpuset_create( | |||
1786 | struct cpuset *parent; | 1775 | struct cpuset *parent; |
1787 | 1776 | ||
1788 | if (!cont->parent) { | 1777 | if (!cont->parent) { |
1789 | /* This is early initialization for the top cgroup */ | ||
1790 | top_cpuset.mems_generation = cpuset_mems_generation++; | ||
1791 | return &top_cpuset.css; | 1778 | return &top_cpuset.css; |
1792 | } | 1779 | } |
1793 | parent = cgroup_cs(cont->parent); | 1780 | parent = cgroup_cs(cont->parent); |
@@ -1799,7 +1786,6 @@ static struct cgroup_subsys_state *cpuset_create( | |||
1799 | return ERR_PTR(-ENOMEM); | 1786 | return ERR_PTR(-ENOMEM); |
1800 | } | 1787 | } |
1801 | 1788 | ||
1802 | cpuset_update_task_memory_state(); | ||
1803 | cs->flags = 0; | 1789 | cs->flags = 0; |
1804 | if (is_spread_page(parent)) | 1790 | if (is_spread_page(parent)) |
1805 | set_bit(CS_SPREAD_PAGE, &cs->flags); | 1791 | set_bit(CS_SPREAD_PAGE, &cs->flags); |
@@ -1808,7 +1794,6 @@ static struct cgroup_subsys_state *cpuset_create( | |||
1808 | set_bit(CS_SCHED_LOAD_BALANCE, &cs->flags); | 1794 | set_bit(CS_SCHED_LOAD_BALANCE, &cs->flags); |
1809 | cpumask_clear(cs->cpus_allowed); | 1795 | cpumask_clear(cs->cpus_allowed); |
1810 | nodes_clear(cs->mems_allowed); | 1796 | nodes_clear(cs->mems_allowed); |
1811 | cs->mems_generation = cpuset_mems_generation++; | ||
1812 | fmeter_init(&cs->fmeter); | 1797 | fmeter_init(&cs->fmeter); |
1813 | cs->relax_domain_level = -1; | 1798 | cs->relax_domain_level = -1; |
1814 | 1799 | ||
@@ -1827,8 +1812,6 @@ static void cpuset_destroy(struct cgroup_subsys *ss, struct cgroup *cont) | |||
1827 | { | 1812 | { |
1828 | struct cpuset *cs = cgroup_cs(cont); | 1813 | struct cpuset *cs = cgroup_cs(cont); |
1829 | 1814 | ||
1830 | cpuset_update_task_memory_state(); | ||
1831 | |||
1832 | if (is_sched_load_balance(cs)) | 1815 | if (is_sched_load_balance(cs)) |
1833 | update_flag(CS_SCHED_LOAD_BALANCE, cs, 0); | 1816 | update_flag(CS_SCHED_LOAD_BALANCE, cs, 0); |
1834 | 1817 | ||
@@ -1849,21 +1832,6 @@ struct cgroup_subsys cpuset_subsys = { | |||
1849 | .early_init = 1, | 1832 | .early_init = 1, |
1850 | }; | 1833 | }; |
1851 | 1834 | ||
1852 | /* | ||
1853 | * cpuset_init_early - just enough so that the calls to | ||
1854 | * cpuset_update_task_memory_state() in early init code | ||
1855 | * are harmless. | ||
1856 | */ | ||
1857 | |||
1858 | int __init cpuset_init_early(void) | ||
1859 | { | ||
1860 | alloc_cpumask_var(&top_cpuset.cpus_allowed, GFP_NOWAIT); | ||
1861 | |||
1862 | top_cpuset.mems_generation = cpuset_mems_generation++; | ||
1863 | return 0; | ||
1864 | } | ||
1865 | |||
1866 | |||
1867 | /** | 1835 | /** |
1868 | * cpuset_init - initialize cpusets at system boot | 1836 | * cpuset_init - initialize cpusets at system boot |
1869 | * | 1837 | * |
@@ -1874,11 +1842,13 @@ int __init cpuset_init(void) | |||
1874 | { | 1842 | { |
1875 | int err = 0; | 1843 | int err = 0; |
1876 | 1844 | ||
1845 | if (!alloc_cpumask_var(&top_cpuset.cpus_allowed, GFP_KERNEL)) | ||
1846 | BUG(); | ||
1847 | |||
1877 | cpumask_setall(top_cpuset.cpus_allowed); | 1848 | cpumask_setall(top_cpuset.cpus_allowed); |
1878 | nodes_setall(top_cpuset.mems_allowed); | 1849 | nodes_setall(top_cpuset.mems_allowed); |
1879 | 1850 | ||
1880 | fmeter_init(&top_cpuset.fmeter); | 1851 | fmeter_init(&top_cpuset.fmeter); |
1881 | top_cpuset.mems_generation = cpuset_mems_generation++; | ||
1882 | set_bit(CS_SCHED_LOAD_BALANCE, &top_cpuset.flags); | 1852 | set_bit(CS_SCHED_LOAD_BALANCE, &top_cpuset.flags); |
1883 | top_cpuset.relax_domain_level = -1; | 1853 | top_cpuset.relax_domain_level = -1; |
1884 | 1854 | ||