aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/sched_fair.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index e3081fb65d63..ec445cadbb01 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -116,22 +116,28 @@ static inline struct task_struct *task_of(struct sched_entity *se)
116 * Scheduling class tree data structure manipulation methods: 116 * Scheduling class tree data structure manipulation methods:
117 */ 117 */
118 118
119static inline u64
120max_vruntime(u64 min_vruntime, u64 vruntime)
121{
122 if ((vruntime > min_vruntime) ||
123 (min_vruntime > (1ULL << 61) && vruntime < (1ULL << 50)))
124 min_vruntime = vruntime;
125
126 return min_vruntime;
127}
128
119static inline void 129static inline void
120set_leftmost(struct cfs_rq *cfs_rq, struct rb_node *leftmost) 130set_leftmost(struct cfs_rq *cfs_rq, struct rb_node *leftmost)
121{ 131{
122 struct sched_entity *se; 132 struct sched_entity *se;
123 133
124 cfs_rq->rb_leftmost = leftmost; 134 cfs_rq->rb_leftmost = leftmost;
125 if (leftmost) { 135 if (leftmost)
126 se = rb_entry(leftmost, struct sched_entity, run_node); 136 se = rb_entry(leftmost, struct sched_entity, run_node);
127 if ((se->vruntime > cfs_rq->min_vruntime) ||
128 (cfs_rq->min_vruntime > (1ULL << 61) &&
129 se->vruntime < (1ULL << 50)))
130 cfs_rq->min_vruntime = se->vruntime;
131 }
132} 137}
133 138
134s64 entity_key(struct cfs_rq *cfs_rq, struct sched_entity *se) 139static inline s64
140entity_key(struct cfs_rq *cfs_rq, struct sched_entity *se)
135{ 141{
136 return se->fair_key - cfs_rq->min_vruntime; 142 return se->fair_key - cfs_rq->min_vruntime;
137} 143}
@@ -254,6 +260,7 @@ __update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr,
254 unsigned long delta_exec) 260 unsigned long delta_exec)
255{ 261{
256 unsigned long delta_exec_weighted; 262 unsigned long delta_exec_weighted;
263 u64 next_vruntime, min_vruntime;
257 264
258 schedstat_set(curr->exec_max, max((u64)delta_exec, curr->exec_max)); 265 schedstat_set(curr->exec_max, max((u64)delta_exec, curr->exec_max));
259 266
@@ -265,6 +272,25 @@ __update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr,
265 &curr->load); 272 &curr->load);
266 } 273 }
267 curr->vruntime += delta_exec_weighted; 274 curr->vruntime += delta_exec_weighted;
275
276 /*
277 * maintain cfs_rq->min_vruntime to be a monotonic increasing
278 * value tracking the leftmost vruntime in the tree.
279 */
280 if (first_fair(cfs_rq)) {
281 next_vruntime = __pick_next_entity(cfs_rq)->vruntime;
282
283 /* min_vruntime() := !max_vruntime() */
284 min_vruntime = max_vruntime(curr->vruntime, next_vruntime);
285 if (min_vruntime == next_vruntime)
286 min_vruntime = curr->vruntime;
287 else
288 min_vruntime = next_vruntime;
289 } else
290 min_vruntime = curr->vruntime;
291
292 cfs_rq->min_vruntime =
293 max_vruntime(cfs_rq->min_vruntime, min_vruntime);
268} 294}
269 295
270static void update_curr(struct cfs_rq *cfs_rq) 296static void update_curr(struct cfs_rq *cfs_rq)