Commit 63070a79ba482c274bad10ac8c4b587a3e011f2c
1 parent
5a7780e725
Exists in
master
and in
4 other branches
hrtimer: catch expired CLOCK_REALTIME timers early
A CLOCK_REALTIME timer, which has an absolute expiry time less than the clock realtime offset calls with a negative delta into the clock events code and triggers the WARN_ON() there. This is a false positive and needs to be prevented. Check the result of timer->expires - timer->base->offset right away and return -ETIME right away. Thanks to Frans Pop, who reported the problem and tested the fixes. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Frans Pop <elendil@planet.nl>
Showing 1 changed file with 11 additions and 0 deletions Side-by-side Diff
kernel/hrtimer.c
... | ... | @@ -442,6 +442,8 @@ |
442 | 442 | ktime_t expires = ktime_sub(timer->expires, base->offset); |
443 | 443 | int res; |
444 | 444 | |
445 | + WARN_ON_ONCE(timer->expires.tv64 < 0); | |
446 | + | |
445 | 447 | /* |
446 | 448 | * When the callback is running, we do not reprogram the clock event |
447 | 449 | * device. The timer callback is either running on a different CPU or |
... | ... | @@ -451,6 +453,15 @@ |
451 | 453 | */ |
452 | 454 | if (hrtimer_callback_running(timer)) |
453 | 455 | return 0; |
456 | + | |
457 | + /* | |
458 | + * CLOCK_REALTIME timer might be requested with an absolute | |
459 | + * expiry time which is less than base->offset. Nothing wrong | |
460 | + * about that, just avoid to call into the tick code, which | |
461 | + * has now objections against negative expiry values. | |
462 | + */ | |
463 | + if (expires.tv64 < 0) | |
464 | + return -ETIME; | |
454 | 465 | |
455 | 466 | if (expires.tv64 >= expires_next->tv64) |
456 | 467 | return 0; |