[PATCH] sched: prevent getting too much vruntime

From: byungchul.park
Date: Wed Nov 11 2015 - 03:50:48 EST


From: Byungchul Park <byungchul.park@xxxxxxx>

Especially in the case below, se->vruntime can be too large and
scheduling cannot work properly.

1. set se->vruntime to "cfs_rq->min_vruntime - sysctl_sched_latency" in
place_entity() when detaching the se from cfs_rq.
2. do a normalization by "se->vruntime -= cfs_rq->min_vruntime".
(see detach_task_cfs_rq().)
3. do "se->vruntime += cfs_rq->min_vruntime", when attaching the se to
a cfs_rq where cfs_rq->min_vruntime < sysctl_sched_latency.

In this case, se->vruntime is suppose to be a negative value, but
actually it is a too large value because vruntime is a unsigned type.
It's wrong. To avoid this situation, this patch takes the case into
account.

Signed-off-by: Byungchul Park <byungchul.park@xxxxxxx>
---
kernel/sched/fair.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 077076f..a7cc8e8 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -480,6 +480,13 @@ static void update_min_vruntime(struct cfs_rq *cfs_rq)
#endif
}

+static inline void vruntime_unnormalize(struct cfs_rq *cfs_rq, struct sched_entity *se)
+{
+ se->vruntime += cfs_rq->min_vruntime;
+ if (unlikely((s64)se->vruntime < 0))
+ se->vruntime = 0;
+}
+
/*
* Enqueue an entity into the rb-tree:
*/
@@ -3002,7 +3009,7 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
* through calling update_curr().
*/
if (!(flags & ENQUEUE_WAKEUP) || (flags & ENQUEUE_WAKING))
- se->vruntime += cfs_rq->min_vruntime;
+ vruntime_unnormalize(cfs_rq, se);

/*
* Update run-time statistics of the 'current'.
@@ -8019,7 +8026,7 @@ static void attach_task_cfs_rq(struct task_struct *p)
attach_entity_load_avg(cfs_rq, se);

if (!vruntime_normalized(p))
- se->vruntime += cfs_rq->min_vruntime;
+ vruntime_unnormalize(cfs_rq, se);
}

static void switched_from_fair(struct rq *rq, struct task_struct *p)
--
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/