From 1d95ade87dd1ea0bcc0acc090e06e8fc25d69b51 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Tue, 22 Sep 2020 10:22:23 +0800 Subject: [PATCH] timer: Fix wheel index calculation on last level stable inclusion from linux-4.19.134 commit 5b9caae6153484239d90cb8a73f0c1b614dd2a89 -------------------------------- commit e2a71bdea81690b6ef11f4368261ec6f5b6891aa upstream. When an expiration delta falls into the last level of the wheel, that delta has be compared against the maximum possible delay and reduced to fit in if necessary. However instead of comparing the delta against the maximum, the code compares the actual expiry against the maximum. Then instead of fixing the delta to fit in, it sets the maximum delta as the expiry value. This can result in various undesired outcomes, the worst possible one being a timer expiring 15 days ahead to fire immediately. Fixes: 500462a9de65 ("timers: Switch to a non-cascading wheel") Signed-off-by: Frederic Weisbecker Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20200717140551.29076-2-frederic@kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Yang Yingliang --- kernel/time/timer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/time/timer.c b/kernel/time/timer.c index f145d7b5c818..61e41ea3a96e 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -520,8 +520,8 @@ static int calc_wheel_index(unsigned long expires, unsigned long clk) * Force expire obscene large timeouts to expire at the * capacity limit of the wheel. */ - if (expires >= WHEEL_TIMEOUT_CUTOFF) - expires = WHEEL_TIMEOUT_MAX; + if (delta >= WHEEL_TIMEOUT_CUTOFF) + expires = clk + WHEEL_TIMEOUT_MAX; idx = calc_index(expires, LVL_DEPTH - 1); } -- GitLab