@@ -1806,17 +1806,28 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
1806
1806
*
1807
1807
* Compute add/delete mask to/from effective_cpus
1808
1808
*
1809
- * addmask = effective_xcpus & ~newmask & parent->effective_xcpus
1810
- * delmask = newmask & ~cs->effective_xcpus
1811
- * & parent->effective_xcpus
1809
+ * For valid partition:
1810
+ * addmask = exclusive_cpus & ~newmask
1811
+ * & parent->effective_xcpus
1812
+ * delmask = newmask & ~exclusive_cpus
1813
+ * & parent->effective_xcpus
1814
+ *
1815
+ * For invalid partition:
1816
+ * delmask = newmask & parent->effective_xcpus
1812
1817
*/
1813
- cpumask_andnot (tmp -> addmask , xcpus , newmask );
1814
- adding = cpumask_and (tmp -> addmask , tmp -> addmask ,
1815
- parent -> effective_xcpus );
1818
+ if (is_prs_invalid (old_prs )) {
1819
+ adding = false;
1820
+ deleting = cpumask_and (tmp -> delmask ,
1821
+ newmask , parent -> effective_xcpus );
1822
+ } else {
1823
+ cpumask_andnot (tmp -> addmask , xcpus , newmask );
1824
+ adding = cpumask_and (tmp -> addmask , tmp -> addmask ,
1825
+ parent -> effective_xcpus );
1816
1826
1817
- cpumask_andnot (tmp -> delmask , newmask , xcpus );
1818
- deleting = cpumask_and (tmp -> delmask , tmp -> delmask ,
1819
- parent -> effective_xcpus );
1827
+ cpumask_andnot (tmp -> delmask , newmask , xcpus );
1828
+ deleting = cpumask_and (tmp -> delmask , tmp -> delmask ,
1829
+ parent -> effective_xcpus );
1830
+ }
1820
1831
/*
1821
1832
* Make partition invalid if parent's effective_cpus could
1822
1833
* become empty and there are tasks in the parent.
@@ -1910,9 +1921,11 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
1910
1921
1911
1922
/*
1912
1923
* Transitioning between invalid to valid or vice versa may require
1913
- * changing CS_CPU_EXCLUSIVE.
1924
+ * changing CS_CPU_EXCLUSIVE. In the case of partcmd_update,
1925
+ * validate_change() has already been successfully called and
1926
+ * CPU lists in cs haven't been updated yet. So defer it to later.
1914
1927
*/
1915
- if (old_prs != new_prs ) {
1928
+ if (( old_prs != new_prs ) && ( cmd != partcmd_update )) {
1916
1929
int err = update_partition_exclusive (cs , new_prs );
1917
1930
1918
1931
if (err )
@@ -1960,6 +1973,9 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
1960
1973
1961
1974
spin_unlock_irq (& callback_lock );
1962
1975
1976
+ if ((old_prs != new_prs ) && (cmd == partcmd_update ))
1977
+ update_partition_exclusive (cs , new_prs );
1978
+
1963
1979
if (adding || deleting ) {
1964
1980
update_tasks_cpumask (parent , tmp -> addmask );
1965
1981
update_sibling_cpumasks (parent , cs , tmp );
@@ -2356,8 +2372,9 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
2356
2372
if (alloc_cpumasks (NULL , & tmp ))
2357
2373
return - ENOMEM ;
2358
2374
2359
- if (is_partition_valid (cs )) {
2360
- if (cpumask_empty (trialcs -> effective_xcpus )) {
2375
+ if (old_prs ) {
2376
+ if (is_partition_valid (cs ) &&
2377
+ cpumask_empty (trialcs -> effective_xcpus )) {
2361
2378
invalidate = true;
2362
2379
cs -> prs_err = PERR_INVCPUS ;
2363
2380
} else if (prstate_housekeeping_conflict (old_prs , trialcs -> effective_xcpus )) {
@@ -2391,32 +2408,41 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
2391
2408
*/
2392
2409
invalidate = true;
2393
2410
rcu_read_lock ();
2394
- cpuset_for_each_child (cp , css , parent )
2411
+ cpuset_for_each_child (cp , css , parent ) {
2412
+ struct cpumask * xcpus = fetch_xcpus (trialcs );
2413
+
2395
2414
if (is_partition_valid (cp ) &&
2396
- cpumask_intersects (trialcs -> effective_xcpus , cp -> effective_xcpus )) {
2415
+ cpumask_intersects (xcpus , cp -> effective_xcpus )) {
2397
2416
rcu_read_unlock ();
2398
2417
update_parent_effective_cpumask (cp , partcmd_invalidate , NULL , & tmp );
2399
2418
rcu_read_lock ();
2400
2419
}
2420
+ }
2401
2421
rcu_read_unlock ();
2402
2422
retval = 0 ;
2403
2423
}
2404
2424
2405
2425
if (retval < 0 )
2406
2426
goto out_free ;
2407
2427
2408
- if (is_partition_valid (cs )) {
2428
+ if (is_partition_valid (cs ) ||
2429
+ (is_partition_invalid (cs ) && !invalidate )) {
2430
+ struct cpumask * xcpus = trialcs -> effective_xcpus ;
2431
+
2432
+ if (cpumask_empty (xcpus ) && is_partition_invalid (cs ))
2433
+ xcpus = trialcs -> cpus_allowed ;
2434
+
2409
2435
/*
2410
2436
* Call remote_cpus_update() to handle valid remote partition
2411
2437
*/
2412
2438
if (is_remote_partition (cs ))
2413
- remote_cpus_update (cs , trialcs -> effective_xcpus , & tmp );
2439
+ remote_cpus_update (cs , xcpus , & tmp );
2414
2440
else if (invalidate )
2415
2441
update_parent_effective_cpumask (cs , partcmd_invalidate ,
2416
2442
NULL , & tmp );
2417
2443
else
2418
2444
update_parent_effective_cpumask (cs , partcmd_update ,
2419
- trialcs -> effective_xcpus , & tmp );
2445
+ xcpus , & tmp );
2420
2446
} else if (!cpumask_empty (cs -> exclusive_cpus )) {
2421
2447
/*
2422
2448
* Use trialcs->effective_cpus as a temp cpumask
@@ -2493,7 +2519,7 @@ static int update_exclusive_cpumask(struct cpuset *cs, struct cpuset *trialcs,
2493
2519
if (retval )
2494
2520
return retval ;
2495
2521
2496
- if (is_partition_valid ( cs ) ) {
2522
+ if (old_prs ) {
2497
2523
if (cpumask_empty (trialcs -> effective_xcpus )) {
2498
2524
invalidate = true;
2499
2525
cs -> prs_err = PERR_INVCPUS ;
@@ -2927,19 +2953,10 @@ static int update_prstate(struct cpuset *cs, int new_prs)
2927
2953
return 0 ;
2928
2954
2929
2955
/*
2930
- * For a previously invalid partition root with valid partition root
2931
- * parent, treat it as if it is a "member". Otherwise, reject it as
2932
- * remote partition cannot currently self-recover from an invalid
2933
- * state.
2956
+ * Treat a previously invalid partition root as if it is a "member".
2934
2957
*/
2935
- if (new_prs && is_prs_invalid (old_prs )) {
2936
- if (is_partition_valid (parent )) {
2937
- old_prs = PRS_MEMBER ;
2938
- } else {
2939
- cs -> partition_root_state = - new_prs ;
2940
- return 0 ;
2941
- }
2942
- }
2958
+ if (new_prs && is_prs_invalid (old_prs ))
2959
+ old_prs = PRS_MEMBER ;
2943
2960
2944
2961
if (alloc_cpumasks (NULL , & tmpmask ))
2945
2962
return - ENOMEM ;
0 commit comments