Skip to content

Commit 950592f

Browse files
Miao Xietorvalds
authored andcommitted
cpusets: update tasks' page/slab spread flags in time
Fix the bug that the kernel didn't spread page cache/slab object evenly over all the allowed nodes when spread flags were set by updating tasks' page/slab spread flags in time. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Christoph Lameter <cl@linux-foundation.org> Cc: Paul Menage <menage@google.com> Cc: Nick Piggin <nickpiggin@yahoo.com.au> Cc: Yasunori Goto <y-goto@jp.fujitsu.com> Cc: Pekka Enberg <penberg@cs.helsinki.fi> Cc: David Rientjes <rientjes@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent f3b39d4 commit 950592f

File tree

1 file changed

+55
-4
lines changed

1 file changed

+55
-4
lines changed

kernel/cpuset.c

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,6 @@ void cpuset_update_task_memory_state(void)
406406
cs = task_cs(tsk); /* Maybe changed when task not locked */
407407
guarantee_online_mems(cs, &tsk->mems_allowed);
408408
tsk->cpuset_mems_generation = cs->mems_generation;
409-
cpuset_update_task_spread_flag(cs, tsk);
410409
task_unlock(tsk);
411410
mutex_unlock(&callback_mutex);
412411
mpol_rebind_task(tsk, &tsk->mems_allowed);
@@ -1203,6 +1202,46 @@ static int update_relax_domain_level(struct cpuset *cs, s64 val)
12031202
return 0;
12041203
}
12051204

1205+
/*
1206+
* cpuset_change_flag - make a task's spread flags the same as its cpuset's
1207+
* @tsk: task to be updated
1208+
* @scan: struct cgroup_scanner containing the cgroup of the task
1209+
*
1210+
* Called by cgroup_scan_tasks() for each task in a cgroup.
1211+
*
1212+
* We don't need to re-check for the cgroup/cpuset membership, since we're
1213+
* holding cgroup_lock() at this point.
1214+
*/
1215+
static void cpuset_change_flag(struct task_struct *tsk,
1216+
struct cgroup_scanner *scan)
1217+
{
1218+
cpuset_update_task_spread_flag(cgroup_cs(scan->cg), tsk);
1219+
}
1220+
1221+
/*
1222+
* update_tasks_flags - update the spread flags of tasks in the cpuset.
1223+
* @cs: the cpuset in which each task's spread flags needs to be changed
1224+
* @heap: if NULL, defer allocating heap memory to cgroup_scan_tasks()
1225+
*
1226+
* Called with cgroup_mutex held
1227+
*
1228+
* The cgroup_scan_tasks() function will scan all the tasks in a cgroup,
1229+
* calling callback functions for each.
1230+
*
1231+
* No return value. It's guaranteed that cgroup_scan_tasks() always returns 0
1232+
* if @heap != NULL.
1233+
*/
1234+
static void update_tasks_flags(struct cpuset *cs, struct ptr_heap *heap)
1235+
{
1236+
struct cgroup_scanner scan;
1237+
1238+
scan.cg = cs->css.cgroup;
1239+
scan.test_task = NULL;
1240+
scan.process_task = cpuset_change_flag;
1241+
scan.heap = heap;
1242+
cgroup_scan_tasks(&scan);
1243+
}
1244+
12061245
/*
12071246
* update_flag - read a 0 or a 1 in a file and update associated flag
12081247
* bit: the bit to update (see cpuset_flagbits_t)
@@ -1216,8 +1255,10 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
12161255
int turning_on)
12171256
{
12181257
struct cpuset *trialcs;
1219-
int err;
12201258
int balance_flag_changed;
1259+
int spread_flag_changed;
1260+
struct ptr_heap heap;
1261+
int err;
12211262

12221263
trialcs = alloc_trial_cpuset(cs);
12231264
if (!trialcs)
@@ -1232,16 +1273,26 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
12321273
if (err < 0)
12331274
goto out;
12341275

1276+
err = heap_init(&heap, PAGE_SIZE, GFP_KERNEL, NULL);
1277+
if (err < 0)
1278+
goto out;
1279+
12351280
balance_flag_changed = (is_sched_load_balance(cs) !=
12361281
is_sched_load_balance(trialcs));
12371282

1283+
spread_flag_changed = ((is_spread_slab(cs) != is_spread_slab(trialcs))
1284+
|| (is_spread_page(cs) != is_spread_page(trialcs)));
1285+
12381286
mutex_lock(&callback_mutex);
12391287
cs->flags = trialcs->flags;
12401288
mutex_unlock(&callback_mutex);
12411289

12421290
if (!cpumask_empty(trialcs->cpus_allowed) && balance_flag_changed)
12431291
async_rebuild_sched_domains();
12441292

1293+
if (spread_flag_changed)
1294+
update_tasks_flags(cs, &heap);
1295+
heap_free(&heap);
12451296
out:
12461297
free_trial_cpuset(trialcs);
12471298
return err;
@@ -1392,6 +1443,8 @@ static void cpuset_attach(struct cgroup_subsys *ss,
13921443
if (err)
13931444
return;
13941445

1446+
cpuset_update_task_spread_flag(cs, tsk);
1447+
13951448
from = oldcs->mems_allowed;
13961449
to = cs->mems_allowed;
13971450
mm = get_task_mm(tsk);
@@ -1453,11 +1506,9 @@ static int cpuset_write_u64(struct cgroup *cgrp, struct cftype *cft, u64 val)
14531506
break;
14541507
case FILE_SPREAD_PAGE:
14551508
retval = update_flag(CS_SPREAD_PAGE, cs, val);
1456-
cs->mems_generation = cpuset_mems_generation++;
14571509
break;
14581510
case FILE_SPREAD_SLAB:
14591511
retval = update_flag(CS_SPREAD_SLAB, cs, val);
1460-
cs->mems_generation = cpuset_mems_generation++;
14611512
break;
14621513
default:
14631514
retval = -EINVAL;

0 commit comments

Comments
 (0)