Skip to content

Commit 1f38221

Browse files
Pingfan Liuhtejun
authored andcommitted
cgroup/cpuset: Introduce cpuset_cpus_allowed_locked()
cpuset_cpus_allowed() uses a reader lock that is sleepable under RT, which means it cannot be called inside raw_spin_lock_t context. Introduce a new cpuset_cpus_allowed_locked() helper that performs the same function as cpuset_cpus_allowed() except that the caller must have acquired the cpuset_mutex so that no further locking will be needed. Suggested-by: Waiman Long <[email protected]> Signed-off-by: Pingfan Liu <[email protected]> Cc: Waiman Long <[email protected]> Cc: Tejun Heo <[email protected]> Cc: Johannes Weiner <[email protected]> Cc: Michal Koutný <[email protected]> Cc: [email protected] To: [email protected] Reviewed-by: Chen Ridong <[email protected]> Reviewed-by: Waiman Long <[email protected]> Signed-off-by: Tejun Heo <[email protected]>
1 parent a0131c3 commit 1f38221

File tree

2 files changed

+44
-16
lines changed

2 files changed

+44
-16
lines changed

include/linux/cpuset.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ extern void inc_dl_tasks_cs(struct task_struct *task);
7474
extern void dec_dl_tasks_cs(struct task_struct *task);
7575
extern void cpuset_lock(void);
7676
extern void cpuset_unlock(void);
77+
extern void cpuset_cpus_allowed_locked(struct task_struct *p, struct cpumask *mask);
7778
extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask);
7879
extern bool cpuset_cpus_allowed_fallback(struct task_struct *p);
7980
extern bool cpuset_cpu_is_isolated(int cpu);
@@ -195,10 +196,16 @@ static inline void dec_dl_tasks_cs(struct task_struct *task) { }
195196
static inline void cpuset_lock(void) { }
196197
static inline void cpuset_unlock(void) { }
197198

199+
static inline void cpuset_cpus_allowed_locked(struct task_struct *p,
200+
struct cpumask *mask)
201+
{
202+
cpumask_copy(mask, task_cpu_possible_mask(p));
203+
}
204+
198205
static inline void cpuset_cpus_allowed(struct task_struct *p,
199206
struct cpumask *mask)
200207
{
201-
cpumask_copy(mask, task_cpu_possible_mask(p));
208+
cpuset_cpus_allowed_locked(p, mask);
202209
}
203210

204211
static inline bool cpuset_cpus_allowed_fallback(struct task_struct *p)

kernel/cgroup/cpuset.c

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4160,24 +4160,13 @@ void __init cpuset_init_smp(void)
41604160
BUG_ON(!cpuset_migrate_mm_wq);
41614161
}
41624162

4163-
/**
4164-
* cpuset_cpus_allowed - return cpus_allowed mask from a tasks cpuset.
4165-
* @tsk: pointer to task_struct from which to obtain cpuset->cpus_allowed.
4166-
* @pmask: pointer to struct cpumask variable to receive cpus_allowed set.
4167-
*
4168-
* Description: Returns the cpumask_var_t cpus_allowed of the cpuset
4169-
* attached to the specified @tsk. Guaranteed to return some non-empty
4170-
* subset of cpu_active_mask, even if this means going outside the
4171-
* tasks cpuset, except when the task is in the top cpuset.
4172-
**/
4173-
4174-
void cpuset_cpus_allowed(struct task_struct *tsk, struct cpumask *pmask)
4163+
/*
4164+
* Return cpus_allowed mask from a task's cpuset.
4165+
*/
4166+
static void __cpuset_cpus_allowed_locked(struct task_struct *tsk, struct cpumask *pmask)
41754167
{
4176-
unsigned long flags;
41774168
struct cpuset *cs;
41784169

4179-
spin_lock_irqsave(&callback_lock, flags);
4180-
41814170
cs = task_cs(tsk);
41824171
if (cs != &top_cpuset)
41834172
guarantee_active_cpus(tsk, pmask);
@@ -4197,7 +4186,39 @@ void cpuset_cpus_allowed(struct task_struct *tsk, struct cpumask *pmask)
41974186
if (!cpumask_intersects(pmask, cpu_active_mask))
41984187
cpumask_copy(pmask, possible_mask);
41994188
}
4189+
}
42004190

4191+
/**
4192+
* cpuset_cpus_allowed_locked - return cpus_allowed mask from a task's cpuset.
4193+
* @tsk: pointer to task_struct from which to obtain cpuset->cpus_allowed.
4194+
* @pmask: pointer to struct cpumask variable to receive cpus_allowed set.
4195+
*
4196+
* Similir to cpuset_cpus_allowed() except that the caller must have acquired
4197+
* cpuset_mutex.
4198+
*/
4199+
void cpuset_cpus_allowed_locked(struct task_struct *tsk, struct cpumask *pmask)
4200+
{
4201+
lockdep_assert_held(&cpuset_mutex);
4202+
__cpuset_cpus_allowed_locked(tsk, pmask);
4203+
}
4204+
4205+
/**
4206+
* cpuset_cpus_allowed - return cpus_allowed mask from a task's cpuset.
4207+
* @tsk: pointer to task_struct from which to obtain cpuset->cpus_allowed.
4208+
* @pmask: pointer to struct cpumask variable to receive cpus_allowed set.
4209+
*
4210+
* Description: Returns the cpumask_var_t cpus_allowed of the cpuset
4211+
* attached to the specified @tsk. Guaranteed to return some non-empty
4212+
* subset of cpu_active_mask, even if this means going outside the
4213+
* tasks cpuset, except when the task is in the top cpuset.
4214+
**/
4215+
4216+
void cpuset_cpus_allowed(struct task_struct *tsk, struct cpumask *pmask)
4217+
{
4218+
unsigned long flags;
4219+
4220+
spin_lock_irqsave(&callback_lock, flags);
4221+
__cpuset_cpus_allowed_locked(tsk, pmask);
42014222
spin_unlock_irqrestore(&callback_lock, flags);
42024223
}
42034224

0 commit comments

Comments
 (0)