diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2008-04-19 13:45:00 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-04-19 13:45:00 -0400 |
commit | 58d6c2d72f8628f39e8689fbde8aa177fcf00a37 (patch) | |
tree | 0be40bd788856b3cabb99ff258561b15a574f2f3 | |
parent | d19ca30874f2ad343d054e0b5c0576744afeecd4 (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.h | 1 | ||||
-rw-r--r-- | kernel/sched_rt.c | 27 |
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 | */ |
485 | static void dequeue_rt_stack(struct task_struct *p) | 483 | static 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 | /* |