diff mbox series

[v8,12/19] sched: Introduce task_cpus_dl_admissible() to check proposed affinity

Message ID 20210602164719.31777-13-will@kernel.org (mailing list archive)
State New, archived
Headers show
Series Add support for 32-bit tasks on asymmetric AArch32 systems | expand

Commit Message

Will Deacon June 2, 2021, 4:47 p.m. UTC
In preparation for restricting the affinity of a task during execve()
on arm64, introduce a new task_cpus_dl_admissible() helper function to
give an indication as to whether the restricted mask is admissible for
a deadline task.

Signed-off-by: Will Deacon <will@kernel.org>
---
 include/linux/sched.h |  6 ++++++
 kernel/sched/core.c   | 44 +++++++++++++++++++++++++++----------------
 2 files changed, 34 insertions(+), 16 deletions(-)

Comments

Daniel Bristot de Oliveira June 3, 2021, 9:43 a.m. UTC | #1
On 6/2/21 6:47 PM, Will Deacon wrote:
> In preparation for restricting the affinity of a task during execve()
> on arm64, introduce a new task_cpus_dl_admissible() helper function to
> give an indication as to whether the restricted mask is admissible for
> a deadline task.
> 
> Signed-off-by: Will Deacon <will@kernel.org>
> ---
>  include/linux/sched.h |  6 ++++++
>  kernel/sched/core.c   | 44 +++++++++++++++++++++++++++----------------
>  2 files changed, 34 insertions(+), 16 deletions(-)
> 
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index 91a6cfeae242..9b17d8cfa6ef 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -1691,6 +1691,7 @@ extern void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new
>  extern int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask);
>  extern int dup_user_cpus_ptr(struct task_struct *dst, struct task_struct *src, int node);
>  extern void release_user_cpus_ptr(struct task_struct *p);
> +extern bool task_cpus_dl_admissible(struct task_struct *p, const struct cpumask *mask);
>  extern void force_compatible_cpus_allowed_ptr(struct task_struct *p);
>  extern void relax_compatible_cpus_allowed_ptr(struct task_struct *p);
>  #else
> @@ -1713,6 +1714,11 @@ static inline void release_user_cpus_ptr(struct task_struct *p)
>  {
>  	WARN_ON(p->user_cpus_ptr);
>  }
> +
> +static inline bool task_cpus_dl_admissible(struct task_struct *p, const struct cpumask *mask)
> +{
> +	return true;
> +}
>  #endif
>  
>  extern int yield_to(struct task_struct *p, bool preempt);
> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index 58e2cf7520c0..b4f8dc18ae11 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -6933,6 +6933,31 @@ SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr,
>  	return retval;
>  }
>  
> +#ifdef CONFIG_SMP
> +bool task_cpus_dl_admissible(struct task_struct *p, const struct cpumask *mask)

Would you mind renaming it to dl_task_check_affinity(), in the case of a v9? It
will look coherent with dl_task_can_attach()...

Reviewed-by: Daniel Bristot de Oliveira <bristot@redhat.com>

Thanks!
-- Daniel
Will Deacon June 3, 2021, 9:52 a.m. UTC | #2
On Thu, Jun 03, 2021 at 11:43:08AM +0200, Daniel Bristot de Oliveira wrote:
> On 6/2/21 6:47 PM, Will Deacon wrote:
> > In preparation for restricting the affinity of a task during execve()
> > on arm64, introduce a new task_cpus_dl_admissible() helper function to
> > give an indication as to whether the restricted mask is admissible for
> > a deadline task.
> > 
> > Signed-off-by: Will Deacon <will@kernel.org>
> > ---
> >  include/linux/sched.h |  6 ++++++
> >  kernel/sched/core.c   | 44 +++++++++++++++++++++++++++----------------
> >  2 files changed, 34 insertions(+), 16 deletions(-)
> > 
> > diff --git a/include/linux/sched.h b/include/linux/sched.h
> > index 91a6cfeae242..9b17d8cfa6ef 100644
> > --- a/include/linux/sched.h
> > +++ b/include/linux/sched.h
> > @@ -1691,6 +1691,7 @@ extern void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new
> >  extern int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask);
> >  extern int dup_user_cpus_ptr(struct task_struct *dst, struct task_struct *src, int node);
> >  extern void release_user_cpus_ptr(struct task_struct *p);
> > +extern bool task_cpus_dl_admissible(struct task_struct *p, const struct cpumask *mask);
> >  extern void force_compatible_cpus_allowed_ptr(struct task_struct *p);
> >  extern void relax_compatible_cpus_allowed_ptr(struct task_struct *p);
> >  #else
> > @@ -1713,6 +1714,11 @@ static inline void release_user_cpus_ptr(struct task_struct *p)
> >  {
> >  	WARN_ON(p->user_cpus_ptr);
> >  }
> > +
> > +static inline bool task_cpus_dl_admissible(struct task_struct *p, const struct cpumask *mask)
> > +{
> > +	return true;
> > +}
> >  #endif
> >  
> >  extern int yield_to(struct task_struct *p, bool preempt);
> > diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> > index 58e2cf7520c0..b4f8dc18ae11 100644
> > --- a/kernel/sched/core.c
> > +++ b/kernel/sched/core.c
> > @@ -6933,6 +6933,31 @@ SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr,
> >  	return retval;
> >  }
> >  
> > +#ifdef CONFIG_SMP
> > +bool task_cpus_dl_admissible(struct task_struct *p, const struct cpumask *mask)
> 
> Would you mind renaming it to dl_task_check_affinity(), in the case of a v9? It
> will look coherent with dl_task_can_attach()...

Of course! I struggled with the naming myself, and your suggestion is much
better.

> Reviewed-by: Daniel Bristot de Oliveira <bristot@redhat.com>

Cheers!

Will
diff mbox series

Patch

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 91a6cfeae242..9b17d8cfa6ef 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1691,6 +1691,7 @@  extern void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new
 extern int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask);
 extern int dup_user_cpus_ptr(struct task_struct *dst, struct task_struct *src, int node);
 extern void release_user_cpus_ptr(struct task_struct *p);
+extern bool task_cpus_dl_admissible(struct task_struct *p, const struct cpumask *mask);
 extern void force_compatible_cpus_allowed_ptr(struct task_struct *p);
 extern void relax_compatible_cpus_allowed_ptr(struct task_struct *p);
 #else
@@ -1713,6 +1714,11 @@  static inline void release_user_cpus_ptr(struct task_struct *p)
 {
 	WARN_ON(p->user_cpus_ptr);
 }
+
+static inline bool task_cpus_dl_admissible(struct task_struct *p, const struct cpumask *mask)
+{
+	return true;
+}
 #endif
 
 extern int yield_to(struct task_struct *p, bool preempt);
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 58e2cf7520c0..b4f8dc18ae11 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6933,6 +6933,31 @@  SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr,
 	return retval;
 }
 
+#ifdef CONFIG_SMP
+bool task_cpus_dl_admissible(struct task_struct *p, const struct cpumask *mask)
+{
+	bool ret;
+
+	/*
+	 * If the task isn't a deadline task or admission control is
+	 * disabled then we don't care about affinity changes.
+	 */
+	if (!task_has_dl_policy(p) || !dl_bandwidth_enabled())
+		return true;
+
+	/*
+	 * Since bandwidth control happens on root_domain basis,
+	 * if admission test is enabled, we only admit -deadline
+	 * tasks allowed to run on all the CPUs in the task's
+	 * root_domain.
+	 */
+	rcu_read_lock();
+	ret = cpumask_subset(task_rq(p)->rd->span, mask);
+	rcu_read_unlock();
+	return ret;
+}
+#endif
+
 static int
 __sched_setaffinity(struct task_struct *p, const struct cpumask *mask)
 {
@@ -6950,23 +6975,10 @@  __sched_setaffinity(struct task_struct *p, const struct cpumask *mask)
 	cpuset_cpus_allowed(p, cpus_allowed);
 	cpumask_and(new_mask, mask, cpus_allowed);
 
-	/*
-	 * Since bandwidth control happens on root_domain basis,
-	 * if admission test is enabled, we only admit -deadline
-	 * tasks allowed to run on all the CPUs in the task's
-	 * root_domain.
-	 */
-#ifdef CONFIG_SMP
-	if (task_has_dl_policy(p) && dl_bandwidth_enabled()) {
-		rcu_read_lock();
-		if (!cpumask_subset(task_rq(p)->rd->span, new_mask)) {
-			retval = -EBUSY;
-			rcu_read_unlock();
-			goto out_free_new_mask;
-		}
-		rcu_read_unlock();
+	if (!task_cpus_dl_admissible(p, new_mask)) {
+		retval = -EBUSY;
+		goto out_free_new_mask;
 	}
-#endif
 again:
 	retval = __set_cpus_allowed_ptr(p, new_mask, SCA_CHECK | SCA_USER);
 	if (retval)