aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2007-10-15 11:00:05 -0400
committerIngo Molnar <mingo@elte.hu>2007-10-15 11:00:05 -0400
commit9014623c0e3545be58a7f19f55793f6517bdc274 (patch)
tree064267aecedeacb8154282c6475d67f4e34f41e3 /kernel
parent94dfb5e75ef59068a8cf68fa6e18f25ebdcd20b9 (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>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched_fair.c15
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
134s64 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;