cgroups.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv6 1/2] cgroup/cpuset: Introduce cpuset_cpus_allowed_locked()
       [not found] <20251117092732.16419-1-piliu@redhat.com>
@ 2025-11-17  9:27 ` Pingfan Liu
  2025-11-17 20:37   ` Waiman Long
  0 siblings, 1 reply; 4+ messages in thread
From: Pingfan Liu @ 2025-11-17  9:27 UTC (permalink / raw)
  To: cgroups
  Cc: Pingfan Liu, Waiman Long, Chen Ridong, Peter Zijlstra, Juri Lelli,
	Pierre Gondois, Ingo Molnar, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
	Tejun Heo, Johannes Weiner, mkoutny, linux-kernel

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 <longman@redhat.com>
Signed-off-by: Pingfan Liu <piliu@redhat.com>
Cc: Waiman Long <longman@redhat.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: "Michal Koutný" <mkoutny@suse.com>
Cc: linux-kernel@vger.kernel.org
To: cgroups@vger.kernel.org
---
 include/linux/cpuset.h |  1 +
 kernel/cgroup/cpuset.c | 51 +++++++++++++++++++++++++++++-------------
 2 files changed, 37 insertions(+), 15 deletions(-)

diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index 2ddb256187b51..e057a3123791e 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -75,6 +75,7 @@ extern void dec_dl_tasks_cs(struct task_struct *task);
 extern void cpuset_lock(void);
 extern void cpuset_unlock(void);
 extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask);
+extern void cpuset_cpus_allowed_locked(struct task_struct *p, struct cpumask *mask);
 extern bool cpuset_cpus_allowed_fallback(struct task_struct *p);
 extern bool cpuset_cpu_is_isolated(int cpu);
 extern nodemask_t cpuset_mems_allowed(struct task_struct *p);
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index 52468d2c178a3..7a179a1a2e30a 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -4116,24 +4116,13 @@ void __init cpuset_init_smp(void)
 	BUG_ON(!cpuset_migrate_mm_wq);
 }
 
-/**
- * cpuset_cpus_allowed - return cpus_allowed mask from a tasks cpuset.
- * @tsk: pointer to task_struct from which to obtain cpuset->cpus_allowed.
- * @pmask: pointer to struct cpumask variable to receive cpus_allowed set.
- *
- * Description: Returns the cpumask_var_t cpus_allowed of the cpuset
- * attached to the specified @tsk.  Guaranteed to return some non-empty
- * subset of cpu_active_mask, even if this means going outside the
- * tasks cpuset, except when the task is in the top cpuset.
- **/
-
-void cpuset_cpus_allowed(struct task_struct *tsk, struct cpumask *pmask)
+/*
+ * Return cpus_allowed mask from a task's cpuset.
+ */
+static void __cpuset_cpus_allowed_locked(struct task_struct *tsk, struct cpumask *pmask)
 {
-	unsigned long flags;
 	struct cpuset *cs;
 
-	spin_lock_irqsave(&callback_lock, flags);
-
 	cs = task_cs(tsk);
 	if (cs != &top_cpuset)
 		guarantee_active_cpus(tsk, pmask);
@@ -4153,7 +4142,39 @@ void cpuset_cpus_allowed(struct task_struct *tsk, struct cpumask *pmask)
 		if (!cpumask_intersects(pmask, cpu_active_mask))
 			cpumask_copy(pmask, possible_mask);
 	}
+}
 
+/**
+ * cpuset_cpus_allowed_locked - return cpus_allowed mask from a task's cpuset.
+ * @tsk: pointer to task_struct from which to obtain cpuset->cpus_allowed.
+ * @pmask: pointer to struct cpumask variable to receive cpus_allowed set.
+ *
+ * Similir to cpuset_cpus_allowed() except that the caller must have acquired
+ * cpuset_mutex.
+ */
+void cpuset_cpus_allowed_locked(struct task_struct *tsk, struct cpumask *pmask)
+{
+	lockdep_assert_held(&cpuset_mutex);
+	__cpuset_cpus_allowed_locked(tsk, pmask);
+}
+
+/**
+ * cpuset_cpus_allowed - return cpus_allowed mask from a task's cpuset.
+ * @tsk: pointer to task_struct from which to obtain cpuset->cpus_allowed.
+ * @pmask: pointer to struct cpumask variable to receive cpus_allowed set.
+ *
+ * Description: Returns the cpumask_var_t cpus_allowed of the cpuset
+ * attached to the specified @tsk.  Guaranteed to return some non-empty
+ * subset of cpu_active_mask, even if this means going outside the
+ * tasks cpuset, except when the task is in the top cpuset.
+ **/
+
+void cpuset_cpus_allowed(struct task_struct *tsk, struct cpumask *pmask)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&callback_lock, flags);
+	__cpuset_cpus_allowed_locked(tsk, pmask);
 	spin_unlock_irqrestore(&callback_lock, flags);
 }
 
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCHv6 1/2] cgroup/cpuset: Introduce cpuset_cpus_allowed_locked()
  2025-11-17  9:27 ` [PATCHv6 1/2] cgroup/cpuset: Introduce cpuset_cpus_allowed_locked() Pingfan Liu
@ 2025-11-17 20:37   ` Waiman Long
  2025-11-18  6:30     ` Pingfan Liu
  0 siblings, 1 reply; 4+ messages in thread
From: Waiman Long @ 2025-11-17 20:37 UTC (permalink / raw)
  To: Pingfan Liu, cgroups
  Cc: Chen Ridong, Peter Zijlstra, Juri Lelli, Pierre Gondois,
	Ingo Molnar, Vincent Guittot, Dietmar Eggemann, Steven Rostedt,
	Ben Segall, Mel Gorman, Valentin Schneider, Tejun Heo,
	Johannes Weiner, mkoutny, linux-kernel

On 11/17/25 4:27 AM, Pingfan Liu wrote:
> 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 <longman@redhat.com>
> Signed-off-by: Pingfan Liu <piliu@redhat.com>
> Cc: Waiman Long <longman@redhat.com>
> Cc: Tejun Heo <tj@kernel.org>
> Cc: Johannes Weiner <hannes@cmpxchg.org>
> Cc: "Michal Koutný" <mkoutny@suse.com>
> Cc: linux-kernel@vger.kernel.org
> To: cgroups@vger.kernel.org
> ---
>   include/linux/cpuset.h |  1 +
>   kernel/cgroup/cpuset.c | 51 +++++++++++++++++++++++++++++-------------
>   2 files changed, 37 insertions(+), 15 deletions(-)
>
> diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
> index 2ddb256187b51..e057a3123791e 100644
> --- a/include/linux/cpuset.h
> +++ b/include/linux/cpuset.h
> @@ -75,6 +75,7 @@ extern void dec_dl_tasks_cs(struct task_struct *task);
>   extern void cpuset_lock(void);
>   extern void cpuset_unlock(void);
>   extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask);
> +extern void cpuset_cpus_allowed_locked(struct task_struct *p, struct cpumask *mask);
>   extern bool cpuset_cpus_allowed_fallback(struct task_struct *p);
>   extern bool cpuset_cpu_is_isolated(int cpu);
>   extern nodemask_t cpuset_mems_allowed(struct task_struct *p);

Ah, the following code should be added to to !CONFIG_CPUSETS section 
after cpuset_cpus_allowed().

#define cpuset_cpus_allowed_locked(p, m)  cpuset_cpus_allowed(p, m)

Or you can add another inline function that just calls 
cpuset_cpus_allowed().

Cheers,
Longman


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCHv6 1/2] cgroup/cpuset: Introduce cpuset_cpus_allowed_locked()
  2025-11-17 20:37   ` Waiman Long
@ 2025-11-18  6:30     ` Pingfan Liu
  2025-11-18 14:33       ` Waiman Long
  0 siblings, 1 reply; 4+ messages in thread
From: Pingfan Liu @ 2025-11-18  6:30 UTC (permalink / raw)
  To: Waiman Long
  Cc: cgroups, Chen Ridong, Peter Zijlstra, Juri Lelli, Pierre Gondois,
	Ingo Molnar, Vincent Guittot, Dietmar Eggemann, Steven Rostedt,
	Ben Segall, Mel Gorman, Valentin Schneider, Tejun Heo,
	Johannes Weiner, mkoutny, linux-kernel

On Tue, Nov 18, 2025 at 4:37 AM Waiman Long <llong@redhat.com> wrote:
>
> On 11/17/25 4:27 AM, Pingfan Liu wrote:
> > 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 <longman@redhat.com>
> > Signed-off-by: Pingfan Liu <piliu@redhat.com>
> > Cc: Waiman Long <longman@redhat.com>
> > Cc: Tejun Heo <tj@kernel.org>
> > Cc: Johannes Weiner <hannes@cmpxchg.org>
> > Cc: "Michal Koutný" <mkoutny@suse.com>
> > Cc: linux-kernel@vger.kernel.org
> > To: cgroups@vger.kernel.org
> > ---
> >   include/linux/cpuset.h |  1 +
> >   kernel/cgroup/cpuset.c | 51 +++++++++++++++++++++++++++++-------------
> >   2 files changed, 37 insertions(+), 15 deletions(-)
> >
> > diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
> > index 2ddb256187b51..e057a3123791e 100644
> > --- a/include/linux/cpuset.h
> > +++ b/include/linux/cpuset.h
> > @@ -75,6 +75,7 @@ extern void dec_dl_tasks_cs(struct task_struct *task);
> >   extern void cpuset_lock(void);
> >   extern void cpuset_unlock(void);
> >   extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask);
> > +extern void cpuset_cpus_allowed_locked(struct task_struct *p, struct cpumask *mask);
> >   extern bool cpuset_cpus_allowed_fallback(struct task_struct *p);
> >   extern bool cpuset_cpu_is_isolated(int cpu);
> >   extern nodemask_t cpuset_mems_allowed(struct task_struct *p);
>
> Ah, the following code should be added to to !CONFIG_CPUSETS section
> after cpuset_cpus_allowed().
>
> #define cpuset_cpus_allowed_locked(p, m)  cpuset_cpus_allowed(p, m)
>
> Or you can add another inline function that just calls
> cpuset_cpus_allowed().
>

It may be better to make cpuset_cpus_allowed() call
cpuset_cpus_allowed_locked(), following the call chain used under
CONFIG_CPUSETS case.

Thanks,

Pingfan


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCHv6 1/2] cgroup/cpuset: Introduce cpuset_cpus_allowed_locked()
  2025-11-18  6:30     ` Pingfan Liu
@ 2025-11-18 14:33       ` Waiman Long
  0 siblings, 0 replies; 4+ messages in thread
From: Waiman Long @ 2025-11-18 14:33 UTC (permalink / raw)
  To: Pingfan Liu, Waiman Long
  Cc: cgroups, Chen Ridong, Peter Zijlstra, Juri Lelli, Pierre Gondois,
	Ingo Molnar, Vincent Guittot, Dietmar Eggemann, Steven Rostedt,
	Ben Segall, Mel Gorman, Valentin Schneider, Tejun Heo,
	Johannes Weiner, mkoutny, linux-kernel

On 11/18/25 1:30 AM, Pingfan Liu wrote:
> On Tue, Nov 18, 2025 at 4:37 AM Waiman Long <llong@redhat.com> wrote:
>> On 11/17/25 4:27 AM, Pingfan Liu wrote:
>>> 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 <longman@redhat.com>
>>> Signed-off-by: Pingfan Liu <piliu@redhat.com>
>>> Cc: Waiman Long <longman@redhat.com>
>>> Cc: Tejun Heo <tj@kernel.org>
>>> Cc: Johannes Weiner <hannes@cmpxchg.org>
>>> Cc: "Michal Koutný" <mkoutny@suse.com>
>>> Cc: linux-kernel@vger.kernel.org
>>> To: cgroups@vger.kernel.org
>>> ---
>>>    include/linux/cpuset.h |  1 +
>>>    kernel/cgroup/cpuset.c | 51 +++++++++++++++++++++++++++++-------------
>>>    2 files changed, 37 insertions(+), 15 deletions(-)
>>>
>>> diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
>>> index 2ddb256187b51..e057a3123791e 100644
>>> --- a/include/linux/cpuset.h
>>> +++ b/include/linux/cpuset.h
>>> @@ -75,6 +75,7 @@ extern void dec_dl_tasks_cs(struct task_struct *task);
>>>    extern void cpuset_lock(void);
>>>    extern void cpuset_unlock(void);
>>>    extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask);
>>> +extern void cpuset_cpus_allowed_locked(struct task_struct *p, struct cpumask *mask);
>>>    extern bool cpuset_cpus_allowed_fallback(struct task_struct *p);
>>>    extern bool cpuset_cpu_is_isolated(int cpu);
>>>    extern nodemask_t cpuset_mems_allowed(struct task_struct *p);
>> Ah, the following code should be added to to !CONFIG_CPUSETS section
>> after cpuset_cpus_allowed().
>>
>> #define cpuset_cpus_allowed_locked(p, m)  cpuset_cpus_allowed(p, m)
>>
>> Or you can add another inline function that just calls
>> cpuset_cpus_allowed().
>>
> It may be better to make cpuset_cpus_allowed() call
> cpuset_cpus_allowed_locked(), following the call chain used under
> CONFIG_CPUSETS case.

That is fine too.

Cheers,
Longman

>
> Thanks,
>
> Pingfan
>


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-11-18 14:33 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20251117092732.16419-1-piliu@redhat.com>
2025-11-17  9:27 ` [PATCHv6 1/2] cgroup/cpuset: Introduce cpuset_cpus_allowed_locked() Pingfan Liu
2025-11-17 20:37   ` Waiman Long
2025-11-18  6:30     ` Pingfan Liu
2025-11-18 14:33       ` Waiman Long

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).