diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2007-10-15 11:00:05 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2007-10-15 11:00:05 -0400 |
commit | 9014623c0e3545be58a7f19f55793f6517bdc274 (patch) | |
tree | 064267aecedeacb8154282c6475d67f4e34f41e3 | |
parent | 94dfb5e75ef59068a8cf68fa6e18f25ebdcd20b9 (diff) |
sched: handle vruntime 64-bit overflow
Handle vruntime overflow by centering the key space around min_vruntime.
( otherwise we could overflow 64-bit vruntime in a few days with SCHED_IDLE
tasks - or in a few years with nice +19. )
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Mike Galbraith <efault@gmx.de>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | kernel/sched_fair.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 86e5e8c5d101..895fef74d99a 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -124,11 +124,18 @@ set_leftmost(struct cfs_rq *cfs_rq, struct rb_node *leftmost) | |||
124 | cfs_rq->rb_leftmost = leftmost; | 124 | cfs_rq->rb_leftmost = leftmost; |
125 | if (leftmost) { | 125 | if (leftmost) { |
126 | se = rb_entry(leftmost, struct sched_entity, run_node); | 126 | se = rb_entry(leftmost, struct sched_entity, run_node); |
127 | cfs_rq->min_vruntime = max(se->vruntime, | 127 | if ((se->vruntime > cfs_rq->min_vruntime) || |
128 | cfs_rq->min_vruntime); | 128 | (cfs_rq->min_vruntime > (1ULL << 61) && |
129 | se->vruntime < (1ULL << 50))) | ||
130 | cfs_rq->min_vruntime = se->vruntime; | ||
129 | } | 131 | } |
130 | } | 132 | } |
131 | 133 | ||
134 | s64 entity_key(struct cfs_rq *cfs_rq, struct sched_entity *se) | ||
135 | { | ||
136 | return se->fair_key - cfs_rq->min_vruntime; | ||
137 | } | ||
138 | |||
132 | /* | 139 | /* |
133 | * Enqueue an entity into the rb-tree: | 140 | * Enqueue an entity into the rb-tree: |
134 | */ | 141 | */ |
@@ -138,7 +145,7 @@ __enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) | |||
138 | struct rb_node **link = &cfs_rq->tasks_timeline.rb_node; | 145 | struct rb_node **link = &cfs_rq->tasks_timeline.rb_node; |
139 | struct rb_node *parent = NULL; | 146 | struct rb_node *parent = NULL; |
140 | struct sched_entity *entry; | 147 | struct sched_entity *entry; |
141 | s64 key = se->fair_key; | 148 | s64 key = entity_key(cfs_rq, se); |
142 | int leftmost = 1; | 149 | int leftmost = 1; |
143 | 150 | ||
144 | /* | 151 | /* |
@@ -151,7 +158,7 @@ __enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) | |||
151 | * We dont care about collisions. Nodes with | 158 | * We dont care about collisions. Nodes with |
152 | * the same key stay together. | 159 | * the same key stay together. |
153 | */ | 160 | */ |
154 | if (key - entry->fair_key < 0) { | 161 | if (key < entity_key(cfs_rq, entry)) { |
155 | link = &parent->rb_left; | 162 | link = &parent->rb_left; |
156 | } else { | 163 | } else { |
157 | link = &parent->rb_right; | 164 | link = &parent->rb_right; |