@@ -1148,6 +1148,7 @@ static int update_parent_subparts_cpumask(struct cpuset *cpuset, int cmd,
1148
1148
struct cpuset * parent = parent_cs (cpuset );
1149
1149
int adding ; /* Moving cpus from effective_cpus to subparts_cpus */
1150
1150
int deleting ; /* Moving cpus from subparts_cpus to effective_cpus */
1151
+ int new_prs ;
1151
1152
bool part_error = false; /* Partition error? */
1152
1153
1153
1154
percpu_rwsem_assert_held (& cpuset_rwsem );
@@ -1183,6 +1184,7 @@ static int update_parent_subparts_cpumask(struct cpuset *cpuset, int cmd,
1183
1184
* A cpumask update cannot make parent's effective_cpus become empty.
1184
1185
*/
1185
1186
adding = deleting = false;
1187
+ new_prs = cpuset -> partition_root_state ;
1186
1188
if (cmd == partcmd_enable ) {
1187
1189
cpumask_copy (tmp -> addmask , cpuset -> cpus_allowed );
1188
1190
adding = true;
@@ -1247,11 +1249,11 @@ static int update_parent_subparts_cpumask(struct cpuset *cpuset, int cmd,
1247
1249
switch (cpuset -> partition_root_state ) {
1248
1250
case PRS_ENABLED :
1249
1251
if (part_error )
1250
- cpuset -> partition_root_state = PRS_ERROR ;
1252
+ new_prs = PRS_ERROR ;
1251
1253
break ;
1252
1254
case PRS_ERROR :
1253
1255
if (!part_error )
1254
- cpuset -> partition_root_state = PRS_ENABLED ;
1256
+ new_prs = PRS_ENABLED ;
1255
1257
break ;
1256
1258
}
1257
1259
/*
@@ -1260,10 +1262,10 @@ static int update_parent_subparts_cpumask(struct cpuset *cpuset, int cmd,
1260
1262
part_error = (prev_prs == PRS_ERROR );
1261
1263
}
1262
1264
1263
- if (!part_error && (cpuset -> partition_root_state == PRS_ERROR ))
1265
+ if (!part_error && (new_prs == PRS_ERROR ))
1264
1266
return 0 ; /* Nothing need to be done */
1265
1267
1266
- if (cpuset -> partition_root_state == PRS_ERROR ) {
1268
+ if (new_prs == PRS_ERROR ) {
1267
1269
/*
1268
1270
* Remove all its cpus from parent's subparts_cpus.
1269
1271
*/
@@ -1272,7 +1274,7 @@ static int update_parent_subparts_cpumask(struct cpuset *cpuset, int cmd,
1272
1274
parent -> subparts_cpus );
1273
1275
}
1274
1276
1275
- if (!adding && !deleting )
1277
+ if (!adding && !deleting && ( new_prs == cpuset -> partition_root_state ) )
1276
1278
return 0 ;
1277
1279
1278
1280
/*
@@ -1299,6 +1301,9 @@ static int update_parent_subparts_cpumask(struct cpuset *cpuset, int cmd,
1299
1301
}
1300
1302
1301
1303
parent -> nr_subparts_cpus = cpumask_weight (parent -> subparts_cpus );
1304
+
1305
+ if (cpuset -> partition_root_state != new_prs )
1306
+ cpuset -> partition_root_state = new_prs ;
1302
1307
spin_unlock_irq (& callback_lock );
1303
1308
1304
1309
return cmd == partcmd_update ;
@@ -1321,6 +1326,7 @@ static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp)
1321
1326
struct cpuset * cp ;
1322
1327
struct cgroup_subsys_state * pos_css ;
1323
1328
bool need_rebuild_sched_domains = false;
1329
+ int new_prs ;
1324
1330
1325
1331
rcu_read_lock ();
1326
1332
cpuset_for_each_descendant_pre (cp , pos_css , cs ) {
@@ -1360,7 +1366,8 @@ static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp)
1360
1366
* update_tasks_cpumask() again for tasks in the parent
1361
1367
* cpuset if the parent's subparts_cpus changes.
1362
1368
*/
1363
- if ((cp != cs ) && cp -> partition_root_state ) {
1369
+ new_prs = cp -> partition_root_state ;
1370
+ if ((cp != cs ) && new_prs ) {
1364
1371
switch (parent -> partition_root_state ) {
1365
1372
case PRS_DISABLED :
1366
1373
/*
@@ -1370,7 +1377,7 @@ static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp)
1370
1377
*/
1371
1378
WARN_ON_ONCE (cp -> partition_root_state
1372
1379
!= PRS_ERROR );
1373
- cp -> partition_root_state = PRS_DISABLED ;
1380
+ new_prs = PRS_DISABLED ;
1374
1381
1375
1382
/*
1376
1383
* clear_bit() is an atomic operation and
@@ -1391,11 +1398,7 @@ static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp)
1391
1398
/*
1392
1399
* When parent is invalid, it has to be too.
1393
1400
*/
1394
- cp -> partition_root_state = PRS_ERROR ;
1395
- if (cp -> nr_subparts_cpus ) {
1396
- cp -> nr_subparts_cpus = 0 ;
1397
- cpumask_clear (cp -> subparts_cpus );
1398
- }
1401
+ new_prs = PRS_ERROR ;
1399
1402
break ;
1400
1403
}
1401
1404
}
@@ -1407,8 +1410,7 @@ static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp)
1407
1410
spin_lock_irq (& callback_lock );
1408
1411
1409
1412
cpumask_copy (cp -> effective_cpus , tmp -> new_cpus );
1410
- if (cp -> nr_subparts_cpus &&
1411
- (cp -> partition_root_state != PRS_ENABLED )) {
1413
+ if (cp -> nr_subparts_cpus && (new_prs != PRS_ENABLED )) {
1412
1414
cp -> nr_subparts_cpus = 0 ;
1413
1415
cpumask_clear (cp -> subparts_cpus );
1414
1416
} else if (cp -> nr_subparts_cpus ) {
@@ -1435,6 +1437,10 @@ static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp)
1435
1437
= cpumask_weight (cp -> subparts_cpus );
1436
1438
}
1437
1439
}
1440
+
1441
+ if (new_prs != cp -> partition_root_state )
1442
+ cp -> partition_root_state = new_prs ;
1443
+
1438
1444
spin_unlock_irq (& callback_lock );
1439
1445
1440
1446
WARN_ON (!is_in_v2_mode () &&
@@ -1944,25 +1950,25 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
1944
1950
*/
1945
1951
static int update_prstate (struct cpuset * cs , int new_prs )
1946
1952
{
1947
- int err ;
1953
+ int err , old_prs = cs -> partition_root_state ;
1948
1954
struct cpuset * parent = parent_cs (cs );
1949
1955
struct tmpmasks tmpmask ;
1950
1956
1951
- if (new_prs == cs -> partition_root_state )
1957
+ if (old_prs == new_prs )
1952
1958
return 0 ;
1953
1959
1954
1960
/*
1955
1961
* Cannot force a partial or invalid partition root to a full
1956
1962
* partition root.
1957
1963
*/
1958
- if (new_prs && (cs -> partition_root_state < 0 ))
1964
+ if (new_prs && (old_prs == PRS_ERROR ))
1959
1965
return - EINVAL ;
1960
1966
1961
1967
if (alloc_cpumasks (NULL , & tmpmask ))
1962
1968
return - ENOMEM ;
1963
1969
1964
1970
err = - EINVAL ;
1965
- if (!cs -> partition_root_state ) {
1971
+ if (!old_prs ) {
1966
1972
/*
1967
1973
* Turning on partition root requires setting the
1968
1974
* CS_CPU_EXCLUSIVE bit implicitly as well and cpus_allowed
@@ -1981,14 +1987,12 @@ static int update_prstate(struct cpuset *cs, int new_prs)
1981
1987
update_flag (CS_CPU_EXCLUSIVE , cs , 0 );
1982
1988
goto out ;
1983
1989
}
1984
- cs -> partition_root_state = PRS_ENABLED ;
1985
1990
} else {
1986
1991
/*
1987
1992
* Turning off partition root will clear the
1988
1993
* CS_CPU_EXCLUSIVE bit.
1989
1994
*/
1990
- if (cs -> partition_root_state == PRS_ERROR ) {
1991
- cs -> partition_root_state = PRS_DISABLED ;
1995
+ if (old_prs == PRS_ERROR ) {
1992
1996
update_flag (CS_CPU_EXCLUSIVE , cs , 0 );
1993
1997
err = 0 ;
1994
1998
goto out ;
@@ -1999,8 +2003,6 @@ static int update_prstate(struct cpuset *cs, int new_prs)
1999
2003
if (err )
2000
2004
goto out ;
2001
2005
2002
- cs -> partition_root_state = PRS_DISABLED ;
2003
-
2004
2006
/* Turning off CS_CPU_EXCLUSIVE will not return error */
2005
2007
update_flag (CS_CPU_EXCLUSIVE , cs , 0 );
2006
2008
}
@@ -2017,6 +2019,12 @@ static int update_prstate(struct cpuset *cs, int new_prs)
2017
2019
2018
2020
rebuild_sched_domains_locked ();
2019
2021
out :
2022
+ if (!err ) {
2023
+ spin_lock_irq (& callback_lock );
2024
+ cs -> partition_root_state = new_prs ;
2025
+ spin_unlock_irq (& callback_lock );
2026
+ }
2027
+
2020
2028
free_cpumasks (NULL , & tmpmask );
2021
2029
return err ;
2022
2030
}
@@ -3080,8 +3088,10 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp)
3080
3088
if (is_partition_root (cs ) && (cpumask_empty (& new_cpus ) ||
3081
3089
(parent -> partition_root_state == PRS_ERROR ))) {
3082
3090
if (cs -> nr_subparts_cpus ) {
3091
+ spin_lock_irq (& callback_lock );
3083
3092
cs -> nr_subparts_cpus = 0 ;
3084
3093
cpumask_clear (cs -> subparts_cpus );
3094
+ spin_unlock_irq (& callback_lock );
3085
3095
compute_effective_cpumask (& new_cpus , cs , parent );
3086
3096
}
3087
3097
@@ -3095,7 +3105,9 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp)
3095
3105
cpumask_empty (& new_cpus )) {
3096
3106
update_parent_subparts_cpumask (cs , partcmd_disable ,
3097
3107
NULL , tmp );
3108
+ spin_lock_irq (& callback_lock );
3098
3109
cs -> partition_root_state = PRS_ERROR ;
3110
+ spin_unlock_irq (& callback_lock );
3099
3111
}
3100
3112
cpuset_force_rebuild ();
3101
3113
}
0 commit comments