From 3a44e838d0e4ae53caeb40b17abcabf5b7709f84 Mon Sep 17 00:00:00 2001 From: Zhang Qiao Date: Sat, 24 Dec 2022 08:24:22 +0000 Subject: [PATCH] sched: Reinit task's vruntime if a task sleep over 200 days 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 Reviewed-by: Chen Hui Reviewed-by: songping yu Signed-off-by: Yongqiang Liu --- 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); -- GitLab