@@ -406,7 +406,6 @@ void cpuset_update_task_memory_state(void)
406
406
cs = task_cs (tsk ); /* Maybe changed when task not locked */
407
407
guarantee_online_mems (cs , & tsk -> mems_allowed );
408
408
tsk -> cpuset_mems_generation = cs -> mems_generation ;
409
- cpuset_update_task_spread_flag (cs , tsk );
410
409
task_unlock (tsk );
411
410
mutex_unlock (& callback_mutex );
412
411
mpol_rebind_task (tsk , & tsk -> mems_allowed );
@@ -1203,6 +1202,46 @@ static int update_relax_domain_level(struct cpuset *cs, s64 val)
1203
1202
return 0 ;
1204
1203
}
1205
1204
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
+
1206
1245
/*
1207
1246
* update_flag - read a 0 or a 1 in a file and update associated flag
1208
1247
* bit: the bit to update (see cpuset_flagbits_t)
@@ -1216,8 +1255,10 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
1216
1255
int turning_on )
1217
1256
{
1218
1257
struct cpuset * trialcs ;
1219
- int err ;
1220
1258
int balance_flag_changed ;
1259
+ int spread_flag_changed ;
1260
+ struct ptr_heap heap ;
1261
+ int err ;
1221
1262
1222
1263
trialcs = alloc_trial_cpuset (cs );
1223
1264
if (!trialcs )
@@ -1232,16 +1273,26 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
1232
1273
if (err < 0 )
1233
1274
goto out ;
1234
1275
1276
+ err = heap_init (& heap , PAGE_SIZE , GFP_KERNEL , NULL );
1277
+ if (err < 0 )
1278
+ goto out ;
1279
+
1235
1280
balance_flag_changed = (is_sched_load_balance (cs ) !=
1236
1281
is_sched_load_balance (trialcs ));
1237
1282
1283
+ spread_flag_changed = ((is_spread_slab (cs ) != is_spread_slab (trialcs ))
1284
+ || (is_spread_page (cs ) != is_spread_page (trialcs )));
1285
+
1238
1286
mutex_lock (& callback_mutex );
1239
1287
cs -> flags = trialcs -> flags ;
1240
1288
mutex_unlock (& callback_mutex );
1241
1289
1242
1290
if (!cpumask_empty (trialcs -> cpus_allowed ) && balance_flag_changed )
1243
1291
async_rebuild_sched_domains ();
1244
1292
1293
+ if (spread_flag_changed )
1294
+ update_tasks_flags (cs , & heap );
1295
+ heap_free (& heap );
1245
1296
out :
1246
1297
free_trial_cpuset (trialcs );
1247
1298
return err ;
@@ -1392,6 +1443,8 @@ static void cpuset_attach(struct cgroup_subsys *ss,
1392
1443
if (err )
1393
1444
return ;
1394
1445
1446
+ cpuset_update_task_spread_flag (cs , tsk );
1447
+
1395
1448
from = oldcs -> mems_allowed ;
1396
1449
to = cs -> mems_allowed ;
1397
1450
mm = get_task_mm (tsk );
@@ -1453,11 +1506,9 @@ static int cpuset_write_u64(struct cgroup *cgrp, struct cftype *cft, u64 val)
1453
1506
break ;
1454
1507
case FILE_SPREAD_PAGE :
1455
1508
retval = update_flag (CS_SPREAD_PAGE , cs , val );
1456
- cs -> mems_generation = cpuset_mems_generation ++ ;
1457
1509
break ;
1458
1510
case FILE_SPREAD_SLAB :
1459
1511
retval = update_flag (CS_SPREAD_SLAB , cs , val );
1460
- cs -> mems_generation = cpuset_mems_generation ++ ;
1461
1512
break ;
1462
1513
default :
1463
1514
retval = - EINVAL ;
0 commit comments