@@ -311,17 +311,19 @@ static struct cpuset top_cpuset = {
311
311
if (is_cpuset_online(((des_cs) = css_cs((pos_css)))))
312
312
313
313
/*
314
- * There are two global locks guarding cpuset structures - cpuset_mutex and
314
+ * There are two global locks guarding cpuset structures - cpuset_rwsem and
315
315
* callback_lock. We also require taking task_lock() when dereferencing a
316
316
* task's cpuset pointer. See "The task_lock() exception", at the end of this
317
- * comment.
317
+ * comment. The cpuset code uses only cpuset_rwsem write lock. Other
318
+ * kernel subsystems can use cpuset_read_lock()/cpuset_read_unlock() to
319
+ * prevent change to cpuset structures.
318
320
*
319
321
* A task must hold both locks to modify cpusets. If a task holds
320
- * cpuset_mutex, then it blocks others wanting that mutex , ensuring that it
322
+ * cpuset_rwsem, it blocks others wanting that rwsem , ensuring that it
321
323
* is the only task able to also acquire callback_lock and be able to
322
324
* modify cpusets. It can perform various checks on the cpuset structure
323
325
* first, knowing nothing will change. It can also allocate memory while
324
- * just holding cpuset_mutex . While it is performing these checks, various
326
+ * just holding cpuset_rwsem . While it is performing these checks, various
325
327
* callback routines can briefly acquire callback_lock to query cpusets.
326
328
* Once it is ready to make the changes, it takes callback_lock, blocking
327
329
* everyone else.
@@ -393,7 +395,7 @@ static inline bool is_in_v2_mode(void)
393
395
* One way or another, we guarantee to return some non-empty subset
394
396
* of cpu_online_mask.
395
397
*
396
- * Call with callback_lock or cpuset_mutex held.
398
+ * Call with callback_lock or cpuset_rwsem held.
397
399
*/
398
400
static void guarantee_online_cpus (struct task_struct * tsk ,
399
401
struct cpumask * pmask )
@@ -435,7 +437,7 @@ static void guarantee_online_cpus(struct task_struct *tsk,
435
437
* One way or another, we guarantee to return some non-empty subset
436
438
* of node_states[N_MEMORY].
437
439
*
438
- * Call with callback_lock or cpuset_mutex held.
440
+ * Call with callback_lock or cpuset_rwsem held.
439
441
*/
440
442
static void guarantee_online_mems (struct cpuset * cs , nodemask_t * pmask )
441
443
{
@@ -447,7 +449,7 @@ static void guarantee_online_mems(struct cpuset *cs, nodemask_t *pmask)
447
449
/*
448
450
* update task's spread flag if cpuset's page/slab spread flag is set
449
451
*
450
- * Call with callback_lock or cpuset_mutex held.
452
+ * Call with callback_lock or cpuset_rwsem held.
451
453
*/
452
454
static void cpuset_update_task_spread_flag (struct cpuset * cs ,
453
455
struct task_struct * tsk )
@@ -468,7 +470,7 @@ static void cpuset_update_task_spread_flag(struct cpuset *cs,
468
470
*
469
471
* One cpuset is a subset of another if all its allowed CPUs and
470
472
* Memory Nodes are a subset of the other, and its exclusive flags
471
- * are only set if the other's are set. Call holding cpuset_mutex .
473
+ * are only set if the other's are set. Call holding cpuset_rwsem .
472
474
*/
473
475
474
476
static int is_cpuset_subset (const struct cpuset * p , const struct cpuset * q )
@@ -577,7 +579,7 @@ static inline void free_cpuset(struct cpuset *cs)
577
579
* If we replaced the flag and mask values of the current cpuset
578
580
* (cur) with those values in the trial cpuset (trial), would
579
581
* our various subset and exclusive rules still be valid? Presumes
580
- * cpuset_mutex held.
582
+ * cpuset_rwsem held.
581
583
*
582
584
* 'cur' is the address of an actual, in-use cpuset. Operations
583
585
* such as list traversal that depend on the actual address of the
@@ -700,7 +702,7 @@ static void update_domain_attr_tree(struct sched_domain_attr *dattr,
700
702
rcu_read_unlock ();
701
703
}
702
704
703
- /* Must be called with cpuset_mutex held. */
705
+ /* Must be called with cpuset_rwsem held. */
704
706
static inline int nr_cpusets (void )
705
707
{
706
708
/* jump label reference count + the top-level cpuset */
@@ -726,7 +728,7 @@ static inline int nr_cpusets(void)
726
728
* domains when operating in the severe memory shortage situations
727
729
* that could cause allocation failures below.
728
730
*
729
- * Must be called with cpuset_mutex held.
731
+ * Must be called with cpuset_rwsem held.
730
732
*
731
733
* The three key local variables below are:
732
734
* cp - cpuset pointer, used (together with pos_css) to perform a
@@ -1005,7 +1007,7 @@ partition_and_rebuild_sched_domains(int ndoms_new, cpumask_var_t doms_new[],
1005
1007
* 'cpus' is removed, then call this routine to rebuild the
1006
1008
* scheduler's dynamic sched domains.
1007
1009
*
1008
- * Call with cpuset_mutex held. Takes cpus_read_lock().
1010
+ * Call with cpuset_rwsem held. Takes cpus_read_lock().
1009
1011
*/
1010
1012
static void rebuild_sched_domains_locked (void )
1011
1013
{
@@ -1078,7 +1080,7 @@ void rebuild_sched_domains(void)
1078
1080
* @cs: the cpuset in which each task's cpus_allowed mask needs to be changed
1079
1081
*
1080
1082
* Iterate through each task of @cs updating its cpus_allowed to the
1081
- * effective cpuset's. As this function is called with cpuset_mutex held,
1083
+ * effective cpuset's. As this function is called with cpuset_rwsem held,
1082
1084
* cpuset membership stays stable.
1083
1085
*/
1084
1086
static void update_tasks_cpumask (struct cpuset * cs )
@@ -1347,7 +1349,7 @@ static int update_parent_subparts_cpumask(struct cpuset *cpuset, int cmd,
1347
1349
*
1348
1350
* On legacy hierarchy, effective_cpus will be the same with cpu_allowed.
1349
1351
*
1350
- * Called with cpuset_mutex held
1352
+ * Called with cpuset_rwsem held
1351
1353
*/
1352
1354
static void update_cpumasks_hier (struct cpuset * cs , struct tmpmasks * tmp )
1353
1355
{
@@ -1704,12 +1706,12 @@ static void *cpuset_being_rebound;
1704
1706
* @cs: the cpuset in which each task's mems_allowed mask needs to be changed
1705
1707
*
1706
1708
* Iterate through each task of @cs updating its mems_allowed to the
1707
- * effective cpuset's. As this function is called with cpuset_mutex held,
1709
+ * effective cpuset's. As this function is called with cpuset_rwsem held,
1708
1710
* cpuset membership stays stable.
1709
1711
*/
1710
1712
static void update_tasks_nodemask (struct cpuset * cs )
1711
1713
{
1712
- static nodemask_t newmems ; /* protected by cpuset_mutex */
1714
+ static nodemask_t newmems ; /* protected by cpuset_rwsem */
1713
1715
struct css_task_iter it ;
1714
1716
struct task_struct * task ;
1715
1717
@@ -1722,7 +1724,7 @@ static void update_tasks_nodemask(struct cpuset *cs)
1722
1724
* take while holding tasklist_lock. Forks can happen - the
1723
1725
* mpol_dup() cpuset_being_rebound check will catch such forks,
1724
1726
* and rebind their vma mempolicies too. Because we still hold
1725
- * the global cpuset_mutex , we know that no other rebind effort
1727
+ * the global cpuset_rwsem , we know that no other rebind effort
1726
1728
* will be contending for the global variable cpuset_being_rebound.
1727
1729
* It's ok if we rebind the same mm twice; mpol_rebind_mm()
1728
1730
* is idempotent. Also migrate pages in each mm to new nodes.
@@ -1768,7 +1770,7 @@ static void update_tasks_nodemask(struct cpuset *cs)
1768
1770
*
1769
1771
* On legacy hierarchy, effective_mems will be the same with mems_allowed.
1770
1772
*
1771
- * Called with cpuset_mutex held
1773
+ * Called with cpuset_rwsem held
1772
1774
*/
1773
1775
static void update_nodemasks_hier (struct cpuset * cs , nodemask_t * new_mems )
1774
1776
{
@@ -1821,7 +1823,7 @@ static void update_nodemasks_hier(struct cpuset *cs, nodemask_t *new_mems)
1821
1823
* mempolicies and if the cpuset is marked 'memory_migrate',
1822
1824
* migrate the tasks pages to the new memory.
1823
1825
*
1824
- * Call with cpuset_mutex held. May take callback_lock during call.
1826
+ * Call with cpuset_rwsem held. May take callback_lock during call.
1825
1827
* Will take tasklist_lock, scan tasklist for tasks in cpuset cs,
1826
1828
* lock each such tasks mm->mmap_lock, scan its vma's and rebind
1827
1829
* their mempolicies to the cpusets new mems_allowed.
@@ -1911,7 +1913,7 @@ static int update_relax_domain_level(struct cpuset *cs, s64 val)
1911
1913
* @cs: the cpuset in which each task's spread flags needs to be changed
1912
1914
*
1913
1915
* Iterate through each task of @cs updating its spread flags. As this
1914
- * function is called with cpuset_mutex held, cpuset membership stays
1916
+ * function is called with cpuset_rwsem held, cpuset membership stays
1915
1917
* stable.
1916
1918
*/
1917
1919
static void update_tasks_flags (struct cpuset * cs )
@@ -1931,7 +1933,7 @@ static void update_tasks_flags(struct cpuset *cs)
1931
1933
* cs: the cpuset to update
1932
1934
* turning_on: whether the flag is being set or cleared
1933
1935
*
1934
- * Call with cpuset_mutex held.
1936
+ * Call with cpuset_rwsem held.
1935
1937
*/
1936
1938
1937
1939
static int update_flag (cpuset_flagbits_t bit , struct cpuset * cs ,
@@ -1980,7 +1982,7 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
1980
1982
* cs: the cpuset to update
1981
1983
* new_prs: new partition root state
1982
1984
*
1983
- * Call with cpuset_mutex held.
1985
+ * Call with cpuset_rwsem held.
1984
1986
*/
1985
1987
static int update_prstate (struct cpuset * cs , int new_prs )
1986
1988
{
@@ -2167,7 +2169,7 @@ static int fmeter_getrate(struct fmeter *fmp)
2167
2169
2168
2170
static struct cpuset * cpuset_attach_old_cs ;
2169
2171
2170
- /* Called by cgroups to determine if a cpuset is usable; cpuset_mutex held */
2172
+ /* Called by cgroups to determine if a cpuset is usable; cpuset_rwsem held */
2171
2173
static int cpuset_can_attach (struct cgroup_taskset * tset )
2172
2174
{
2173
2175
struct cgroup_subsys_state * css ;
@@ -2219,15 +2221,15 @@ static void cpuset_cancel_attach(struct cgroup_taskset *tset)
2219
2221
}
2220
2222
2221
2223
/*
2222
- * Protected by cpuset_mutex . cpus_attach is used only by cpuset_attach()
2224
+ * Protected by cpuset_rwsem . cpus_attach is used only by cpuset_attach()
2223
2225
* but we can't allocate it dynamically there. Define it global and
2224
2226
* allocate from cpuset_init().
2225
2227
*/
2226
2228
static cpumask_var_t cpus_attach ;
2227
2229
2228
2230
static void cpuset_attach (struct cgroup_taskset * tset )
2229
2231
{
2230
- /* static buf protected by cpuset_mutex */
2232
+ /* static buf protected by cpuset_rwsem */
2231
2233
static nodemask_t cpuset_attach_nodemask_to ;
2232
2234
struct task_struct * task ;
2233
2235
struct task_struct * leader ;
@@ -2417,7 +2419,7 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of,
2417
2419
* operation like this one can lead to a deadlock through kernfs
2418
2420
* active_ref protection. Let's break the protection. Losing the
2419
2421
* protection is okay as we check whether @cs is online after
2420
- * grabbing cpuset_mutex anyway. This only happens on the legacy
2422
+ * grabbing cpuset_rwsem anyway. This only happens on the legacy
2421
2423
* hierarchies.
2422
2424
*/
2423
2425
css_get (& cs -> css );
@@ -3672,7 +3674,7 @@ void __cpuset_memory_pressure_bump(void)
3672
3674
* - Used for /proc/<pid>/cpuset.
3673
3675
* - No need to task_lock(tsk) on this tsk->cpuset reference, as it
3674
3676
* doesn't really matter if tsk->cpuset changes after we read it,
3675
- * and we take cpuset_mutex , keeping cpuset_attach() from changing it
3677
+ * and we take cpuset_rwsem , keeping cpuset_attach() from changing it
3676
3678
* anyway.
3677
3679
*/
3678
3680
int proc_cpuset_show (struct seq_file * m , struct pid_namespace * ns ,
0 commit comments