@@ -81,6 +81,13 @@ static cpumask_var_t subpartitions_cpus;
8181 */
8282static cpumask_var_t isolated_cpus ;
8383
84+ /*
85+ * isolated_cpus updating flag (protected by cpuset_mutex)
86+ * Set if isolated_cpus is going to be updated in the current
87+ * cpuset_mutex crtical section.
88+ */
89+ static bool isolated_cpus_updating ;
90+
8491/*
8592 * Housekeeping (HK_TYPE_DOMAIN) CPUs at boot
8693 */
@@ -1327,22 +1334,21 @@ static void isolated_cpus_update(int old_prs, int new_prs, struct cpumask *xcpus
13271334 cpumask_or (isolated_cpus , isolated_cpus , xcpus );
13281335 else
13291336 cpumask_andnot (isolated_cpus , isolated_cpus , xcpus );
1337+
1338+ isolated_cpus_updating = true;
13301339}
13311340
13321341/*
13331342 * partition_xcpus_add - Add new exclusive CPUs to partition
13341343 * @new_prs: new partition_root_state
13351344 * @parent: parent cpuset
13361345 * @xcpus: exclusive CPUs to be added
1337- * Return: true if isolated_cpus modified, false otherwise
13381346 *
13391347 * Remote partition if parent == NULL
13401348 */
1341- static bool partition_xcpus_add (int new_prs , struct cpuset * parent ,
1349+ static void partition_xcpus_add (int new_prs , struct cpuset * parent ,
13421350 struct cpumask * xcpus )
13431351{
1344- bool isolcpus_updated ;
1345-
13461352 WARN_ON_ONCE (new_prs < 0 );
13471353 lockdep_assert_held (& callback_lock );
13481354 if (!parent )
@@ -1352,29 +1358,24 @@ static bool partition_xcpus_add(int new_prs, struct cpuset *parent,
13521358 if (parent == & top_cpuset )
13531359 cpumask_or (subpartitions_cpus , subpartitions_cpus , xcpus );
13541360
1355- isolcpus_updated = (new_prs != parent -> partition_root_state );
1356- if (isolcpus_updated )
1361+ if (new_prs != parent -> partition_root_state )
13571362 isolated_cpus_update (parent -> partition_root_state , new_prs ,
13581363 xcpus );
13591364
13601365 cpumask_andnot (parent -> effective_cpus , parent -> effective_cpus , xcpus );
1361- return isolcpus_updated ;
13621366}
13631367
13641368/*
13651369 * partition_xcpus_del - Remove exclusive CPUs from partition
13661370 * @old_prs: old partition_root_state
13671371 * @parent: parent cpuset
13681372 * @xcpus: exclusive CPUs to be removed
1369- * Return: true if isolated_cpus modified, false otherwise
13701373 *
13711374 * Remote partition if parent == NULL
13721375 */
1373- static bool partition_xcpus_del (int old_prs , struct cpuset * parent ,
1376+ static void partition_xcpus_del (int old_prs , struct cpuset * parent ,
13741377 struct cpumask * xcpus )
13751378{
1376- bool isolcpus_updated ;
1377-
13781379 WARN_ON_ONCE (old_prs < 0 );
13791380 lockdep_assert_held (& callback_lock );
13801381 if (!parent )
@@ -1383,14 +1384,12 @@ static bool partition_xcpus_del(int old_prs, struct cpuset *parent,
13831384 if (parent == & top_cpuset )
13841385 cpumask_andnot (subpartitions_cpus , subpartitions_cpus , xcpus );
13851386
1386- isolcpus_updated = (old_prs != parent -> partition_root_state );
1387- if (isolcpus_updated )
1387+ if (old_prs != parent -> partition_root_state )
13881388 isolated_cpus_update (old_prs , parent -> partition_root_state ,
13891389 xcpus );
13901390
13911391 cpumask_and (xcpus , xcpus , cpu_active_mask );
13921392 cpumask_or (parent -> effective_cpus , parent -> effective_cpus , xcpus );
1393- return isolcpus_updated ;
13941393}
13951394
13961395/*
@@ -1452,17 +1451,24 @@ static bool prstate_housekeeping_conflict(int prstate, struct cpumask *new_cpus)
14521451 return false;
14531452}
14541453
1455- static void update_isolation_cpumasks (bool isolcpus_updated )
1454+ /*
1455+ * update_isolation_cpumasks - Update external isolation related CPU masks
1456+ *
1457+ * The following external CPU masks will be updated if necessary:
1458+ * - workqueue unbound cpumask
1459+ */
1460+ static void update_isolation_cpumasks (void )
14561461{
14571462 int ret ;
14581463
1459- lockdep_assert_cpus_held ();
1460-
1461- if (!isolcpus_updated )
1464+ if (!isolated_cpus_updating )
14621465 return ;
14631466
1467+ lockdep_assert_cpus_held ();
1468+
14641469 ret = workqueue_unbound_exclude_cpumask (isolated_cpus );
14651470 WARN_ON_ONCE (ret < 0 );
1471+ isolated_cpus_updating = false;
14661472}
14671473
14681474/**
@@ -1587,8 +1593,6 @@ static inline bool is_local_partition(struct cpuset *cs)
15871593static int remote_partition_enable (struct cpuset * cs , int new_prs ,
15881594 struct tmpmasks * tmp )
15891595{
1590- bool isolcpus_updated ;
1591-
15921596 /*
15931597 * The user must have sysadmin privilege.
15941598 */
@@ -1616,11 +1620,11 @@ static int remote_partition_enable(struct cpuset *cs, int new_prs,
16161620 return PERR_HKEEPING ;
16171621
16181622 spin_lock_irq (& callback_lock );
1619- isolcpus_updated = partition_xcpus_add (new_prs , NULL , tmp -> new_cpus );
1623+ partition_xcpus_add (new_prs , NULL , tmp -> new_cpus );
16201624 list_add (& cs -> remote_sibling , & remote_children );
16211625 cpumask_copy (cs -> effective_xcpus , tmp -> new_cpus );
16221626 spin_unlock_irq (& callback_lock );
1623- update_isolation_cpumasks (isolcpus_updated );
1627+ update_isolation_cpumasks ();
16241628 cpuset_force_rebuild ();
16251629 cs -> prs_err = 0 ;
16261630
@@ -1643,15 +1647,12 @@ static int remote_partition_enable(struct cpuset *cs, int new_prs,
16431647 */
16441648static void remote_partition_disable (struct cpuset * cs , struct tmpmasks * tmp )
16451649{
1646- bool isolcpus_updated ;
1647-
16481650 WARN_ON_ONCE (!is_remote_partition (cs ));
16491651 WARN_ON_ONCE (!cpumask_subset (cs -> effective_xcpus , subpartitions_cpus ));
16501652
16511653 spin_lock_irq (& callback_lock );
16521654 list_del_init (& cs -> remote_sibling );
1653- isolcpus_updated = partition_xcpus_del (cs -> partition_root_state ,
1654- NULL , cs -> effective_xcpus );
1655+ partition_xcpus_del (cs -> partition_root_state , NULL , cs -> effective_xcpus );
16551656 if (cs -> prs_err )
16561657 cs -> partition_root_state = - cs -> partition_root_state ;
16571658 else
@@ -1661,7 +1662,7 @@ static void remote_partition_disable(struct cpuset *cs, struct tmpmasks *tmp)
16611662 compute_excpus (cs , cs -> effective_xcpus );
16621663 reset_partition_data (cs );
16631664 spin_unlock_irq (& callback_lock );
1664- update_isolation_cpumasks (isolcpus_updated );
1665+ update_isolation_cpumasks ();
16651666 cpuset_force_rebuild ();
16661667
16671668 /*
@@ -1686,7 +1687,6 @@ static void remote_cpus_update(struct cpuset *cs, struct cpumask *xcpus,
16861687{
16871688 bool adding , deleting ;
16881689 int prs = cs -> partition_root_state ;
1689- int isolcpus_updated = 0 ;
16901690
16911691 if (WARN_ON_ONCE (!is_remote_partition (cs )))
16921692 return ;
@@ -1722,9 +1722,9 @@ static void remote_cpus_update(struct cpuset *cs, struct cpumask *xcpus,
17221722
17231723 spin_lock_irq (& callback_lock );
17241724 if (adding )
1725- isolcpus_updated += partition_xcpus_add (prs , NULL , tmp -> addmask );
1725+ partition_xcpus_add (prs , NULL , tmp -> addmask );
17261726 if (deleting )
1727- isolcpus_updated += partition_xcpus_del (prs , NULL , tmp -> delmask );
1727+ partition_xcpus_del (prs , NULL , tmp -> delmask );
17281728 /*
17291729 * Need to update effective_xcpus and exclusive_cpus now as
17301730 * update_sibling_cpumasks() below may iterate back to the same cs.
@@ -1733,7 +1733,7 @@ static void remote_cpus_update(struct cpuset *cs, struct cpumask *xcpus,
17331733 if (xcpus )
17341734 cpumask_copy (cs -> exclusive_cpus , xcpus );
17351735 spin_unlock_irq (& callback_lock );
1736- update_isolation_cpumasks (isolcpus_updated );
1736+ update_isolation_cpumasks ();
17371737 if (adding || deleting )
17381738 cpuset_force_rebuild ();
17391739
@@ -1794,7 +1794,6 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
17941794 int deleting ; /* Deleting cpus from parent's effective_cpus */
17951795 int old_prs , new_prs ;
17961796 int part_error = PERR_NONE ; /* Partition error? */
1797- int isolcpus_updated = 0 ;
17981797 struct cpumask * xcpus = user_xcpus (cs );
17991798 int parent_prs = parent -> partition_root_state ;
18001799 bool nocpu ;
@@ -2073,14 +2072,12 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
20732072 * and vice versa.
20742073 */
20752074 if (adding )
2076- isolcpus_updated += partition_xcpus_del (old_prs , parent ,
2077- tmp -> addmask );
2075+ partition_xcpus_del (old_prs , parent , tmp -> addmask );
20782076 if (deleting )
2079- isolcpus_updated += partition_xcpus_add (new_prs , parent ,
2080- tmp -> delmask );
2077+ partition_xcpus_add (new_prs , parent , tmp -> delmask );
20812078
20822079 spin_unlock_irq (& callback_lock );
2083- update_isolation_cpumasks (isolcpus_updated );
2080+ update_isolation_cpumasks ();
20842081
20852082 if ((old_prs != new_prs ) && (cmd == partcmd_update ))
20862083 update_partition_exclusive_flag (cs , new_prs );
@@ -3103,7 +3100,7 @@ static int update_prstate(struct cpuset *cs, int new_prs)
31033100 else if (isolcpus_updated )
31043101 isolated_cpus_update (old_prs , new_prs , cs -> effective_xcpus );
31053102 spin_unlock_irq (& callback_lock );
3106- update_isolation_cpumasks (isolcpus_updated );
3103+ update_isolation_cpumasks ();
31073104
31083105 /* Force update if switching back to member & update effective_xcpus */
31093106 update_cpumasks_hier (cs , & tmpmask , !new_prs );
0 commit comments