@@ -65,7 +65,13 @@ static const char * const perr_strings[] = {
65
65
};
66
66
67
67
/*
68
- * Exclusive CPUs distributed out to sub-partitions of top_cpuset
68
+ * For local partitions, update to subpartitions_cpus & isolated_cpus is done
69
+ * in update_parent_effective_cpumask(). For remote partitions, it is done in
70
+ * the remote_partition_*() and remote_cpus_update() helpers.
71
+ */
72
+ /*
73
+ * Exclusive CPUs distributed out to local or remote sub-partitions of
74
+ * top_cpuset
69
75
*/
70
76
static cpumask_var_t subpartitions_cpus ;
71
77
@@ -1089,9 +1095,14 @@ void cpuset_reset_sched_domains(void)
1089
1095
*
1090
1096
* Iterate through each task of @cs updating its cpus_allowed to the
1091
1097
* effective cpuset's. As this function is called with cpuset_mutex held,
1092
- * cpuset membership stays stable. For top_cpuset, task_cpu_possible_mask()
1093
- * is used instead of effective_cpus to make sure all offline CPUs are also
1094
- * included as hotplug code won't update cpumasks for tasks in top_cpuset.
1098
+ * cpuset membership stays stable.
1099
+ *
1100
+ * For top_cpuset, task_cpu_possible_mask() is used instead of effective_cpus
1101
+ * to make sure all offline CPUs are also included as hotplug code won't
1102
+ * update cpumasks for tasks in top_cpuset.
1103
+ *
1104
+ * As task_cpu_possible_mask() can be task dependent in arm64, we have to
1105
+ * do cpu masking per task instead of doing it once for all.
1095
1106
*/
1096
1107
void cpuset_update_tasks_cpumask (struct cpuset * cs , struct cpumask * new_cpus )
1097
1108
{
@@ -1151,7 +1162,7 @@ static void update_sibling_cpumasks(struct cpuset *parent, struct cpuset *cs,
1151
1162
*
1152
1163
* Return: 0 if successful, an error code otherwise
1153
1164
*/
1154
- static int update_partition_exclusive (struct cpuset * cs , int new_prs )
1165
+ static int update_partition_exclusive_flag (struct cpuset * cs , int new_prs )
1155
1166
{
1156
1167
bool exclusive = (new_prs > PRS_MEMBER );
1157
1168
@@ -1234,12 +1245,12 @@ static void reset_partition_data(struct cpuset *cs)
1234
1245
}
1235
1246
1236
1247
/*
1237
- * partition_xcpus_newstate - Exclusive CPUs state change
1248
+ * isolated_cpus_update - Update the isolated_cpus mask
1238
1249
* @old_prs: old partition_root_state
1239
1250
* @new_prs: new partition_root_state
1240
1251
* @xcpus: exclusive CPUs with state change
1241
1252
*/
1242
- static void partition_xcpus_newstate (int old_prs , int new_prs , struct cpumask * xcpus )
1253
+ static void isolated_cpus_update (int old_prs , int new_prs , struct cpumask * xcpus )
1243
1254
{
1244
1255
WARN_ON_ONCE (old_prs == new_prs );
1245
1256
if (new_prs == PRS_ISOLATED )
@@ -1273,8 +1284,8 @@ static bool partition_xcpus_add(int new_prs, struct cpuset *parent,
1273
1284
1274
1285
isolcpus_updated = (new_prs != parent -> partition_root_state );
1275
1286
if (isolcpus_updated )
1276
- partition_xcpus_newstate (parent -> partition_root_state , new_prs ,
1277
- xcpus );
1287
+ isolated_cpus_update (parent -> partition_root_state , new_prs ,
1288
+ xcpus );
1278
1289
1279
1290
cpumask_andnot (parent -> effective_cpus , parent -> effective_cpus , xcpus );
1280
1291
return isolcpus_updated ;
@@ -1304,8 +1315,8 @@ static bool partition_xcpus_del(int old_prs, struct cpuset *parent,
1304
1315
1305
1316
isolcpus_updated = (old_prs != parent -> partition_root_state );
1306
1317
if (isolcpus_updated )
1307
- partition_xcpus_newstate (old_prs , parent -> partition_root_state ,
1308
- xcpus );
1318
+ isolated_cpus_update (old_prs , parent -> partition_root_state ,
1319
+ xcpus );
1309
1320
1310
1321
cpumask_and (xcpus , xcpus , cpu_active_mask );
1311
1322
cpumask_or (parent -> effective_cpus , parent -> effective_cpus , xcpus );
@@ -1634,8 +1645,8 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
1634
1645
int old_prs , new_prs ;
1635
1646
int part_error = PERR_NONE ; /* Partition error? */
1636
1647
int subparts_delta = 0 ;
1637
- struct cpumask * xcpus ; /* cs effective_xcpus */
1638
1648
int isolcpus_updated = 0 ;
1649
+ struct cpumask * xcpus = user_xcpus (cs );
1639
1650
bool nocpu ;
1640
1651
1641
1652
lockdep_assert_held (& cpuset_mutex );
@@ -1647,7 +1658,6 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
1647
1658
*/
1648
1659
adding = deleting = false;
1649
1660
old_prs = new_prs = cs -> partition_root_state ;
1650
- xcpus = user_xcpus (cs );
1651
1661
1652
1662
if (cmd == partcmd_invalidate ) {
1653
1663
if (is_prs_invalid (old_prs ))
@@ -1861,7 +1871,7 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
1861
1871
* CPU lists in cs haven't been updated yet. So defer it to later.
1862
1872
*/
1863
1873
if ((old_prs != new_prs ) && (cmd != partcmd_update )) {
1864
- int err = update_partition_exclusive (cs , new_prs );
1874
+ int err = update_partition_exclusive_flag (cs , new_prs );
1865
1875
1866
1876
if (err )
1867
1877
return err ;
@@ -1899,7 +1909,7 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
1899
1909
update_unbound_workqueue_cpumask (isolcpus_updated );
1900
1910
1901
1911
if ((old_prs != new_prs ) && (cmd == partcmd_update ))
1902
- update_partition_exclusive (cs , new_prs );
1912
+ update_partition_exclusive_flag (cs , new_prs );
1903
1913
1904
1914
if (adding || deleting ) {
1905
1915
cpuset_update_tasks_cpumask (parent , tmp -> addmask );
@@ -2829,7 +2839,7 @@ static int update_prstate(struct cpuset *cs, int new_prs)
2829
2839
int err = PERR_NONE , old_prs = cs -> partition_root_state ;
2830
2840
struct cpuset * parent = parent_cs (cs );
2831
2841
struct tmpmasks tmpmask ;
2832
- bool new_xcpus_state = false;
2842
+ bool isolcpus_updated = false;
2833
2843
2834
2844
if (old_prs == new_prs )
2835
2845
return 0 ;
@@ -2843,7 +2853,7 @@ static int update_prstate(struct cpuset *cs, int new_prs)
2843
2853
if (alloc_cpumasks (NULL , & tmpmask ))
2844
2854
return - ENOMEM ;
2845
2855
2846
- err = update_partition_exclusive (cs , new_prs );
2856
+ err = update_partition_exclusive_flag (cs , new_prs );
2847
2857
if (err )
2848
2858
goto out ;
2849
2859
@@ -2884,8 +2894,9 @@ static int update_prstate(struct cpuset *cs, int new_prs)
2884
2894
} else if (old_prs && new_prs ) {
2885
2895
/*
2886
2896
* A change in load balance state only, no change in cpumasks.
2897
+ * Need to update isolated_cpus.
2887
2898
*/
2888
- new_xcpus_state = true;
2899
+ isolcpus_updated = true;
2889
2900
} else {
2890
2901
/*
2891
2902
* Switching back to member is always allowed even if it
@@ -2909,22 +2920,26 @@ static int update_prstate(struct cpuset *cs, int new_prs)
2909
2920
*/
2910
2921
if (err ) {
2911
2922
new_prs = - new_prs ;
2912
- update_partition_exclusive (cs , new_prs );
2923
+ update_partition_exclusive_flag (cs , new_prs );
2913
2924
}
2914
2925
2915
2926
spin_lock_irq (& callback_lock );
2916
2927
cs -> partition_root_state = new_prs ;
2917
2928
WRITE_ONCE (cs -> prs_err , err );
2918
2929
if (!is_partition_valid (cs ))
2919
2930
reset_partition_data (cs );
2920
- else if (new_xcpus_state )
2921
- partition_xcpus_newstate (old_prs , new_prs , cs -> effective_xcpus );
2931
+ else if (isolcpus_updated )
2932
+ isolated_cpus_update (old_prs , new_prs , cs -> effective_xcpus );
2922
2933
spin_unlock_irq (& callback_lock );
2923
- update_unbound_workqueue_cpumask (new_xcpus_state );
2934
+ update_unbound_workqueue_cpumask (isolcpus_updated );
2924
2935
2925
- /* Force update if switching back to member */
2936
+ /* Force update if switching back to member & update effective_xcpus */
2926
2937
update_cpumasks_hier (cs , & tmpmask , !new_prs );
2927
2938
2939
+ /* A newly created partition must have effective_xcpus set */
2940
+ WARN_ON_ONCE (!old_prs && (new_prs > 0 )
2941
+ && cpumask_empty (cs -> effective_xcpus ));
2942
+
2928
2943
/* Update sched domains and load balance flag */
2929
2944
update_partition_sd_lb (cs , old_prs );
2930
2945
0 commit comments