From: Con Kolivas <kernel@kolivas.org>
To: linux kernel mailing list <linux-kernel@vger.kernel.org>
Cc: ck list <ck@vds.kolivas.org>,
Andrew Morton <akpm@linux-foundation.org>,
Ingo Molnar <mingo@elte.hu>
Subject: Re: [PATCH] sched: implement staircase deadline scheduler further improvements-1
Date: Thu, 19 Apr 2007 12:03:54 +1000 [thread overview]
Message-ID: <200704191203.54812.kernel@kolivas.org> (raw)
In-Reply-To: <200704190948.36649.kernel@kolivas.org>
On Thursday 19 April 2007 09:48, Con Kolivas wrote:
> While the Staircase Deadline scheduler has not been completely killed off
> and is still in -mm I would like to fix some outstanding issues that I've
> found since it still serves for comparison with all the upcoming
> schedulers.
>
> While still in -mm can we queue this on top please?
>
> A set of staircase-deadline v 0.41 patches will make their way into the
> usual place for those willing to test it.
>
> http://ck.kolivas.org/patches/staircase-deadline/
Oops! Minor thinko! Here is a respin. Please apply this one instead.
I better make a 0.42 heh.
---
The prio_level was being inappropriately decreased if a higher priority
task was still using previous timeslice. Fix that.
Task expiration of higher priority tasks was not being taken into account
with allocating priority slots. Check the expired best_static_prio level
to facilitate that.
Explicitly check all better static priority prio_levels when deciding on
allocating slots for niced tasks.
These changes improve behaviour in many ways.
Signed-off-by: Con Kolivas <kernel@kolivas.org>
---
kernel/sched.c | 64 ++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 43 insertions(+), 21 deletions(-)
Index: linux-2.6.21-rc7-sd/kernel/sched.c
===================================================================
--- linux-2.6.21-rc7-sd.orig/kernel/sched.c 2007-04-19 08:51:54.000000000 +1000
+++ linux-2.6.21-rc7-sd/kernel/sched.c 2007-04-19 12:03:29.000000000 +1000
@@ -145,6 +145,12 @@ struct prio_array {
*/
DECLARE_BITMAP(prio_bitmap, MAX_PRIO + 1);
+ /*
+ * The best static priority (of the dynamic priority tasks) queued
+ * this array.
+ */
+ int best_static_prio;
+
#ifdef CONFIG_SMP
/* For convenience looks back at rq */
struct rq *rq;
@@ -191,9 +197,9 @@ struct rq {
/*
* The current dynamic priority level this runqueue is at per static
- * priority level, and the best static priority queued this rotation.
+ * priority level.
*/
- int prio_level[PRIO_RANGE], best_static_prio;
+ int prio_level[PRIO_RANGE];
/* How many times we have rotated the priority queue */
unsigned long prio_rotation;
@@ -669,7 +675,7 @@ static void task_new_array(struct task_s
}
/* Find the first slot from the relevant prio_matrix entry */
-static inline int first_prio_slot(struct task_struct *p)
+static int first_prio_slot(struct task_struct *p)
{
if (unlikely(p->policy == SCHED_BATCH))
return p->static_prio;
@@ -682,11 +688,18 @@ static inline int first_prio_slot(struct
* level. SCHED_BATCH tasks do not use the priority matrix. They only take
* priority slots from their static_prio and above.
*/
-static inline int next_entitled_slot(struct task_struct *p, struct rq *rq)
+static int next_entitled_slot(struct task_struct *p, struct rq *rq)
{
+ int search_prio = MAX_RT_PRIO, uprio = USER_PRIO(p->static_prio);
+ struct prio_array *array = rq->active;
DECLARE_BITMAP(tmp, PRIO_RANGE);
- int search_prio, uprio = USER_PRIO(p->static_prio);
+ /*
+ * Go straight to expiration if there are higher priority tasks
+ * already expired.
+ */
+ if (p->static_prio > rq->expired->best_static_prio)
+ return MAX_PRIO;
if (!rq->prio_level[uprio])
rq->prio_level[uprio] = MAX_RT_PRIO;
/*
@@ -694,15 +707,22 @@ static inline int next_entitled_slot(str
* static_prio are acceptable, and only if it's not better than
* a queued better static_prio's prio_level.
*/
- if (p->static_prio < rq->best_static_prio) {
- search_prio = MAX_RT_PRIO;
+ if (p->static_prio < array->best_static_prio) {
if (likely(p->policy != SCHED_BATCH))
- rq->best_static_prio = p->static_prio;
- } else if (p->static_prio == rq->best_static_prio)
+ array->best_static_prio = p->static_prio;
+ } else if (p->static_prio == array->best_static_prio) {
search_prio = rq->prio_level[uprio];
- else {
- search_prio = max(rq->prio_level[uprio],
- rq->prio_level[USER_PRIO(rq->best_static_prio)]);
+ } else {
+ int i;
+
+ search_prio = rq->prio_level[uprio];
+ /* A bound O(n) function, worst case n is 40 */
+ for (i = array->best_static_prio; i <= p->static_prio ; i++) {
+ if (!rq->prio_level[USER_PRIO(i)])
+ rq->prio_level[USER_PRIO(i)] = MAX_RT_PRIO;
+ search_prio = max(search_prio,
+ rq->prio_level[USER_PRIO(i)]);
+ }
}
if (unlikely(p->policy == SCHED_BATCH)) {
search_prio = max(search_prio, p->static_prio);
@@ -718,6 +738,8 @@ static void queue_expired(struct task_st
{
task_new_array(p, rq, rq->expired);
p->prio = p->normal_prio = first_prio_slot(p);
+ if (p->static_prio < rq->expired->best_static_prio)
+ rq->expired->best_static_prio = p->static_prio;
}
#ifdef CONFIG_SMP
@@ -726,7 +748,7 @@ static void queue_expired(struct task_st
* update its data appropriately. Note we may be reading data from src_rq->
* outside of lock, but the occasional inaccurate result should be harmless.
*/
- static inline void update_if_moved(struct task_struct *p, struct rq *rq)
+ static void update_if_moved(struct task_struct *p, struct rq *rq)
{
struct rq *src_rq = p->array->rq;
@@ -3217,8 +3239,10 @@ EXPORT_SYMBOL(sub_preempt_count);
#endif
-static inline void reset_prio_levels(struct rq *rq)
+static void reset_prio_levels(struct rq *rq)
{
+ rq->active->best_static_prio = MAX_PRIO - 1;
+ rq->expired->best_static_prio = MAX_PRIO - 1;
memset(rq->prio_level, 0, sizeof(int) * PRIO_RANGE);
}
@@ -3239,7 +3263,6 @@ retry:
rq->active = array;
rq->exp_bitmap = rq->expired->prio_bitmap;
rq->dyn_bitmap = rq->active->prio_bitmap;
- rq->best_static_prio = MAX_PRIO - 1;
rq->prio_rotation++;
idx = find_next_bit(rq->dyn_bitmap, MAX_PRIO, MAX_RT_PRIO);
reset_prio_levels(rq);
@@ -3261,9 +3284,10 @@ retry:
if (likely(next->policy != SCHED_BATCH)) {
int nstatic = next->static_prio;
- if (nstatic < rq->best_static_prio)
- rq->best_static_prio = nstatic;
- rq->prio_level[USER_PRIO(nstatic)] = idx;
+ if (nstatic < array->best_static_prio)
+ array->best_static_prio = nstatic;
+ if (idx > rq->prio_level[USER_PRIO(nstatic)])
+ rq->prio_level[USER_PRIO(nstatic)] = idx;
}
return next;
}
@@ -3348,7 +3372,6 @@ need_resched_nonpreemptible:
}
switch_tasks:
if (next == rq->idle) {
- rq->best_static_prio = MAX_PRIO - 1;
reset_prio_levels(rq);
rq->prio_rotation++;
schedstat_inc(rq, sched_goidle);
@@ -6671,10 +6694,9 @@ void __init sched_init(void)
lockdep_set_class(&rq->lock, &rq->rq_lock_key);
rq->nr_running = 0;
rq->prio_rotation = 0;
- rq->best_static_prio = MAX_PRIO - 1;
- reset_prio_levels(rq);
rq->active = rq->arrays;
rq->expired = rq->arrays + 1;
+ reset_prio_levels(rq);
rq->dyn_bitmap = rq->active->prio_bitmap;
rq->exp_bitmap = rq->expired->prio_bitmap;
--
-ck
prev parent reply other threads:[~2007-04-19 2:03 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-04-18 23:48 [PATCH] sched: implement staircase deadline scheduler further improvements Con Kolivas
2007-04-19 2:03 ` Con Kolivas [this message]
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=200704191203.54812.kernel@kolivas.org \
--to=kernel@kolivas.org \
--cc=akpm@linux-foundation.org \
--cc=ck@vds.kolivas.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
/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: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.