summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorFrederic Weisbecker <frederic@kernel.org>2020-07-17 16:05:40 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-07-22 09:33:14 +0200
commitc28501385945f55444b4bc560e5827b6e45d6d16 (patch)
treea72050ca36f13caf81c28230c4ccb7b176fee09e /kernel
parent6c2388e2a12b7d9c37b83187e4f499d0596bdf93 (diff)
downloadlinux-stable-c28501385945f55444b4bc560e5827b6e45d6d16.tar.gz
linux-stable-c28501385945f55444b4bc560e5827b6e45d6d16.tar.bz2
linux-stable-c28501385945f55444b4bc560e5827b6e45d6d16.zip
timer: Fix wheel index calculation on last level
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 <frederic@kernel.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20200717140551.29076-2-frederic@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/time/timer.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 405fe3fcfe6d..1e9b81a930c0 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -522,8 +522,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);
}