LKML Archive on lore.kernel.org help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org> To: Xunlei Pang <pang.xunlei@linaro.org> Cc: linux-kernel@vger.kernel.org, Juri Lelli <juri.lelli@gmail.com>, Steven Rostedt <rostedt@goodmis.org> Subject: Re: [PATCH 4/5] sched/rt: Consider deadline tasks in cpupri_find() Date: Tue, 27 Jan 2015 13:58:59 +0100 [thread overview] Message-ID: <20150127125859.GD21418@twins.programming.kicks-ass.net> (raw) In-Reply-To: <1421642980-10045-4-git-send-email-pang.xunlei@linaro.org> On Mon, Jan 19, 2015 at 04:49:39AM +0000, Xunlei Pang wrote: > Currently, RT global scheduling doesn't factor deadline > tasks, this may cause some problems. > > See a case below: > On a 3 CPU system, CPU0 has one running deadline task, > CPU1 has one running low priority RT task or idle, CPU3 > has one running high priority RT task. When another mid > priority RT task is woken on CPU3, it will be pushed to > CPU0(this also disturbs the deadline task on CPU0), while > it is reasonable to put it on CPU1. > > This patch eliminates this issue by filtering CPUs that > have runnable deadline tasks, using cpudl->free_cpus in > cpupri_find(). Not a bad idea, Cc'ed Steve who likes to look after the RT bits, excessive quoting for him. > NOTE: We want to make the most use of percpu local_cpu_mask > to save an extra mask allocation, so always passing a non-NULL > lowest_mask to cpupri_find(). > > Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org> > --- > kernel/sched/core.c | 2 ++ > kernel/sched/cpupri.c | 22 +++++----------------- > kernel/sched/cpupri.h | 1 + > kernel/sched/rt.c | 9 +++++---- > 4 files changed, 13 insertions(+), 21 deletions(-) > > diff --git a/kernel/sched/core.c b/kernel/sched/core.c > index ade2958..48c9576 100644 > --- a/kernel/sched/core.c > +++ b/kernel/sched/core.c > @@ -5652,6 +5652,8 @@ static int init_rootdomain(struct root_domain *rd) > > if (cpupri_init(&rd->cpupri) != 0) > goto free_rto_mask; > + > + rd->cpupri.cpudl = &rd->cpudl; This is disgusting though; it breaks the cpuri abstraction. Why not pass in the mask in the one place you actually need it? > return 0; > > free_rto_mask: > diff --git a/kernel/sched/cpupri.c b/kernel/sched/cpupri.c > index 981fcd7..40b8e81 100644 > --- a/kernel/sched/cpupri.c > +++ b/kernel/sched/cpupri.c > @@ -32,6 +32,7 @@ > #include <linux/sched/rt.h> > #include <linux/slab.h> > #include "cpupri.h" > +#include "cpudeadline.h" > > /* Convert between a 140 based task->prio, and our 102 based cpupri */ > static int convert_prio(int prio) > @@ -54,7 +55,7 @@ static int convert_prio(int prio) > * cpupri_find - find the best (lowest-pri) CPU in the system > * @cp: The cpupri context > * @p: The task > - * @lowest_mask: A mask to fill in with selected CPUs (or NULL) > + * @lowest_mask: A mask to fill in with selected CPUs (not NULL) > * > * Note: This function returns the recommended CPUs as calculated during the > * current invocation. By the time the call returns, the CPUs may have in > @@ -103,24 +104,11 @@ int cpupri_find(struct cpupri *cp, struct task_struct *p, > if (skip) > continue; > > - if (cpumask_any_and(&p->cpus_allowed, vec->mask) >= nr_cpu_ids) > + cpumask_and(lowest_mask, &p->cpus_allowed, vec->mask); > + cpumask_and(lowest_mask, lowest_mask, cp->cpudl->free_cpus); > + if (cpumask_any(lowest_mask) >= nr_cpu_ids) > continue; > > - if (lowest_mask) { > - cpumask_and(lowest_mask, &p->cpus_allowed, vec->mask); > - > - /* > - * We have to ensure that we have at least one bit > - * still set in the array, since the map could have > - * been concurrently emptied between the first and > - * second reads of vec->mask. If we hit this > - * condition, simply act as though we never hit this > - * priority level and continue on. > - */ > - if (cpumask_any(lowest_mask) >= nr_cpu_ids) > - continue; > - } > - > return 1; > } > > diff --git a/kernel/sched/cpupri.h b/kernel/sched/cpupri.h > index 63cbb9c..acd7ccf 100644 > --- a/kernel/sched/cpupri.h > +++ b/kernel/sched/cpupri.h > @@ -18,6 +18,7 @@ struct cpupri_vec { > struct cpupri { > struct cpupri_vec pri_to_cpu[CPUPRI_NR_PRIORITIES]; > int *cpu_to_pri; > + struct cpudl *cpudl; > }; > > #ifdef CONFIG_SMP > diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c > index 6725e3c..d28cfa4 100644 > --- a/kernel/sched/rt.c > +++ b/kernel/sched/rt.c > @@ -1349,14 +1349,17 @@ out: > return cpu; > } > > +static DEFINE_PER_CPU(cpumask_var_t, local_cpu_mask); > static void check_preempt_equal_prio(struct rq *rq, struct task_struct *p) > { > + struct cpumask *lowest_mask = this_cpu_cpumask_var_ptr(local_cpu_mask); > + > /* > * Current can't be migrated, useless to reschedule, > * let's hope p can move out. > */ > if (rq->curr->nr_cpus_allowed == 1 || > - !cpupri_find(&rq->rd->cpupri, rq->curr, NULL)) > + !cpupri_find(&rq->rd->cpupri, rq->curr, lowest_mask)) > return; > > /* Again; should you not put something useful in the mask before you pass it to cpupri_find()? > @@ -1364,7 +1367,7 @@ static void check_preempt_equal_prio(struct rq *rq, struct task_struct *p) > * see if it is pushed or pulled somewhere else. > */ > if (p->nr_cpus_allowed != 1 > - && cpupri_find(&rq->rd->cpupri, p, NULL)) > + && cpupri_find(&rq->rd->cpupri, p, lowest_mask)) > return; > > /* > @@ -1526,8 +1529,6 @@ static struct task_struct *pick_highest_pushable_task(struct rq *rq, int cpu) > return NULL; > } > > -static DEFINE_PER_CPU(cpumask_var_t, local_cpu_mask); > - > static int find_lowest_rq(struct task_struct *task) > { > struct sched_domain *sd; > -- > 1.9.1 >
next prev parent reply other threads:[~2015-01-27 12:59 UTC|newest] Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top 2015-01-19 4:49 [PATCH 1/5] sched/deadline: Modify cpudl::free_cpus to reflect rd->online Xunlei Pang 2015-01-19 4:49 ` [PATCH 2/5] sched/deadline: Remove cpu_active_mask from cpudl_find() Xunlei Pang 2015-01-27 15:04 ` Peter Zijlstra 2015-02-04 14:36 ` [tip:sched/core] " tip-bot for Xunlei Pang 2015-01-19 4:49 ` [PATCH 3/5] sched/deadline: Fix wrong cpudl_find() in check_preempt_equal_dl() Xunlei Pang 2015-01-27 12:48 ` Peter Zijlstra 2015-01-27 14:15 ` Peter Zijlstra 2015-01-27 16:47 ` Peter Zijlstra 2015-01-28 15:18 ` Xunlei Pang 2015-01-19 4:49 ` [PATCH 4/5] sched/rt: Consider deadline tasks in cpupri_find() Xunlei Pang 2015-01-27 12:58 ` Peter Zijlstra [this message] 2015-01-27 14:18 ` Peter Zijlstra 2015-01-27 23:04 ` Steven Rostedt 2015-01-28 15:21 ` Xunlei Pang 2015-01-19 4:49 ` [PATCH 5/5] sched/rt: Optimize find_lowest_rq() to select a cache hot cpu Xunlei Pang 2015-01-27 14:21 ` Peter Zijlstra 2015-01-27 14:56 ` Steven Rostedt 2015-01-27 16:28 ` Peter Zijlstra 2015-01-29 16:42 ` Xunlei Pang 2015-01-29 17:17 ` Steven Rostedt 2015-01-29 19:23 ` Peter Zijlstra 2015-02-04 13:07 ` Xunlei Pang 2015-01-23 18:09 ` [PATCH 1/5] sched/deadline: Modify cpudl::free_cpus to reflect rd->online Xunlei Pang 2015-02-01 17:53 ` [tip:sched/core] sched/deadline: Modify cpudl:: free_cpus " tip-bot for Xunlei Pang
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20150127125859.GD21418@twins.programming.kicks-ass.net \ --to=peterz@infradead.org \ --cc=juri.lelli@gmail.com \ --cc=linux-kernel@vger.kernel.org \ --cc=pang.xunlei@linaro.org \ --cc=rostedt@goodmis.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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).