do_sched_cfs_period_timer() will refill cfs_b runtime and call distribute_cfs_runtime() to unthrottle cfs_rq, sometimes cfs_b->runtime will allocate all quota to one cfs_rq incorrectly. This will cause other cfs_rq can't get runtime and will be throttled. We find that one throttled cfs_rq has non-negative cfs_rq->runtime_remaining and cause an unexpetced cast from s64 to u64 in snippet: distribute_cfs_runtime() { runtime = -cfs_rq->runtime_remaining + 1; }. This cast will cause that runtime will be a large number and cfs_b->runtime will be subtracted to be zero at last.
This commit prevents cfs_rq to be assgined new runtime if it has been throttled to avoid the above incorrect type cast. Signed-off-by: Liangyan <liangyan.p...@linux.alibaba.com> --- kernel/sched/fair.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 81fd8a2a605b..b14d67d28138 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -4068,6 +4068,8 @@ static void __account_cfs_rq_runtime(struct cfs_rq *cfs_rq, u64 delta_exec) if (likely(cfs_rq->runtime_remaining > 0)) return; + if (cfs_rq->throttled) + return; /* * if we're unable to extend our runtime we resched so that the active * hierarchy can be throttled -- 2.14.4.44.g2045bb6