aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2008-04-19 13:45:00 -0400
committerIngo Molnar <mingo@elte.hu>2008-04-19 13:45:00 -0400
commit58d6c2d72f8628f39e8689fbde8aa177fcf00a37 (patch)
tree0be40bd788856b3cabb99ff258561b15a574f2f3
parentd19ca30874f2ad343d054e0b5c0576744afeecd4 (diff)
sched: rt-group: optimize dequeue_rt_stack
Now that the group hierarchy can have an arbitrary depth the O(n^2) nature of RT task dequeues will really hurt. Optimize this by providing space to store the tree path, so we can walk it the other way. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--include/linux/sched.h1
-rw-r--r--kernel/sched_rt.c27
2 files changed, 12 insertions, 16 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 0a32059e6ed4..887f5db8942d 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1005,6 +1005,7 @@ struct sched_rt_entity {
1005 unsigned long timeout; 1005 unsigned long timeout;
1006 int nr_cpus_allowed; 1006 int nr_cpus_allowed;
1007 1007
1008 struct sched_rt_entity *back;
1008#ifdef CONFIG_RT_GROUP_SCHED 1009#ifdef CONFIG_RT_GROUP_SCHED
1009 struct sched_rt_entity *parent; 1010 struct sched_rt_entity *parent;
1010 /* rq on which this entity is (to be) queued: */ 1011 /* rq on which this entity is (to be) queued: */
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index 736fb8fd8977..c2730a5a4f05 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -479,26 +479,21 @@ static void dequeue_rt_entity(struct sched_rt_entity *rt_se)
479/* 479/*
480 * Because the prio of an upper entry depends on the lower 480 * Because the prio of an upper entry depends on the lower
481 * entries, we must remove entries top - down. 481 * entries, we must remove entries top - down.
482 *
483 * XXX: O(1/2 h^2) because we can only walk up, not down the chain.
484 */ 482 */
485static void dequeue_rt_stack(struct task_struct *p) 483static void dequeue_rt_stack(struct task_struct *p)
486{ 484{
487 struct sched_rt_entity *rt_se, *top_se; 485 struct sched_rt_entity *rt_se, *back = NULL;
488 486
489 /* 487 rt_se = &p->rt;
490 * dequeue all, top - down. 488 for_each_sched_rt_entity(rt_se) {
491 */ 489 rt_se->back = back;
492 do { 490 back = rt_se;
493 rt_se = &p->rt; 491 }
494 top_se = NULL; 492
495 for_each_sched_rt_entity(rt_se) { 493 for (rt_se = back; rt_se; rt_se = rt_se->back) {
496 if (on_rt_rq(rt_se)) 494 if (on_rt_rq(rt_se))
497 top_se = rt_se; 495 dequeue_rt_entity(rt_se);
498 } 496 }
499 if (top_se)
500 dequeue_rt_entity(top_se);
501 } while (top_se);
502} 497}
503 498
504/* 499/*