| From 20bb813c0fefeeb650843364250971b66e5c11c9 Mon Sep 17 00:00:00 2001 |
| From: "Ahmed S. Darwish" <a.darwish@linutronix.de> |
| Date: Mon, 9 Mar 2020 18:15:29 +0000 |
| Subject: [PATCH] time/sched_clock: Expire timer in hardirq context |
| |
| commit 2c8bd58812ee3dbf0d78b566822f7eacd34bdd7b upstream. |
| |
| To minimize latency, PREEMPT_RT kernels expires hrtimers in preemptible |
| softirq context by default. This can be overriden by marking the timer's |
| expiry with HRTIMER_MODE_HARD. |
| |
| sched_clock_timer is missing this annotation: if its callback is preempted |
| and the duration of the preemption exceeds the wrap around time of the |
| underlying clocksource, sched clock will get out of sync. |
| |
| Mark the sched_clock_timer for expiry in hard interrupt context. |
| |
| Signed-off-by: Ahmed S. Darwish <a.darwish@linutronix.de> |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Link: https://lkml.kernel.org/r/20200309181529.26558-1-a.darwish@linutronix.de |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/kernel/time/sched_clock.c b/kernel/time/sched_clock.c |
| index 142b07619918..3f16750ec7a3 100644 |
| --- a/kernel/time/sched_clock.c |
| +++ b/kernel/time/sched_clock.c |
| @@ -205,7 +205,8 @@ sched_clock_register(u64 (*read)(void), int bits, unsigned long rate) |
| |
| if (sched_clock_timer.function != NULL) { |
| /* update timeout for clock wrap */ |
| - hrtimer_start(&sched_clock_timer, cd.wrap_kt, HRTIMER_MODE_REL); |
| + hrtimer_start(&sched_clock_timer, cd.wrap_kt, |
| + HRTIMER_MODE_REL_HARD); |
| } |
| |
| r = rate; |
| @@ -249,9 +250,9 @@ void __init generic_sched_clock_init(void) |
| * Start the timer to keep sched_clock() properly updated and |
| * sets the initial epoch. |
| */ |
| - hrtimer_init(&sched_clock_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
| + hrtimer_init(&sched_clock_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD); |
| sched_clock_timer.function = sched_clock_poll; |
| - hrtimer_start(&sched_clock_timer, cd.wrap_kt, HRTIMER_MODE_REL); |
| + hrtimer_start(&sched_clock_timer, cd.wrap_kt, HRTIMER_MODE_REL_HARD); |
| } |
| |
| /* |
| @@ -288,7 +289,7 @@ void sched_clock_resume(void) |
| struct clock_read_data *rd = &cd.read_data[0]; |
| |
| rd->epoch_cyc = cd.actual_read_sched_clock(); |
| - hrtimer_start(&sched_clock_timer, cd.wrap_kt, HRTIMER_MODE_REL); |
| + hrtimer_start(&sched_clock_timer, cd.wrap_kt, HRTIMER_MODE_REL_HARD); |
| rd->read_sched_clock = cd.actual_read_sched_clock; |
| } |
| |
| -- |
| 2.7.4 |
| |