From: Zhang Qiao zhangqiao22@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I67BL1 CVE: NA
-------------------------------
If a task sleep for long time, it maybe cause a s64 overflow issue at max_vruntime() and the task will be set an incorrect vruntime, lead to the task be starve.
For fix it, we set the task's vruntime as cfs_rq->min_vruntime when wakeup.
Signed-off-by: Zhang Qiao zhangqiao22@huawei.com Reviewed-by: Chen Hui judy.chenhui@huawei.com Reviewed-by: songping yu yusongping@huawei.com Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com --- kernel/sched/fair.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 0dba06ce0677..ad6a7923c9ed 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -3949,10 +3949,14 @@ static void check_spread(struct cfs_rq *cfs_rq, struct sched_entity *se) #endif }
+/* The threshold when the wakee's vruntime should be set cfs_rq->min_vruntime, default: 200 days */ +#define WAKEUP_REINIT_THRESHOLD_NS (200 * 24 * 3600 * NSEC_PER_SEC) + static void place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) { u64 vruntime = cfs_rq->min_vruntime; + struct rq *rq = rq_of(cfs_rq);
/* * The 'current' period is already promised to the current tasks, @@ -3977,8 +3981,11 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) vruntime -= thresh; }
+ if (unlikely(!initial && (s64)(rq_clock_task(rq) - se->exec_start) > WAKEUP_REINIT_THRESHOLD_NS)) + se->vruntime = vruntime; + else /* ensure we never gain time by being placed backwards. */ - se->vruntime = max_vruntime(se->vruntime, vruntime); + se->vruntime = max_vruntime(se->vruntime, vruntime); }
static void check_enqueue_throttle(struct cfs_rq *cfs_rq);