| From 4aec9c4af1bf4965c27231186eaa9e397a8c0fdd Mon Sep 17 00:00:00 2001 |
| From: Frederic Weisbecker <frederic@kernel.org> |
| Date: Fri, 17 Jul 2020 16:05:40 +0200 |
| Subject: [PATCH] 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: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/kernel/time/timer.c b/kernel/time/timer.c |
| index b2e2991c8c7d..e70451eb2495 100644 |
| --- a/kernel/time/timer.c |
| +++ b/kernel/time/timer.c |
| @@ -519,8 +519,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); |
| } |
| -- |
| 2.27.0 |
| |