| From 78c181fa84b6e1ec75e70b7e687e069dc9387122 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 13 Jul 2021 15:39:48 +0200 |
| Subject: hrtimer: Ensure timerfd notification for HIGHRES=n |
| |
| From: Thomas Gleixner <tglx@linutronix.de> |
| |
| [ Upstream commit 8c3b5e6ec0fee18bc2ce38d1dfe913413205f908 ] |
| |
| If high resolution timers are disabled the timerfd notification about a |
| clock was set event is not happening for all cases which use |
| clock_was_set_delayed() because that's a NOP for HIGHRES=n, which is wrong. |
| |
| Make clock_was_set_delayed() unconditially available to fix that. |
| |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Link: https://lore.kernel.org/r/20210713135158.196661266@linutronix.de |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| include/linux/hrtimer.h | 5 ----- |
| kernel/time/hrtimer.c | 32 ++++++++++++++++---------------- |
| kernel/time/tick-internal.h | 3 +++ |
| 3 files changed, 19 insertions(+), 21 deletions(-) |
| |
| diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h |
| index bb5e7b0a4274..77295af72426 100644 |
| --- a/include/linux/hrtimer.h |
| +++ b/include/linux/hrtimer.h |
| @@ -318,16 +318,12 @@ struct clock_event_device; |
| |
| extern void hrtimer_interrupt(struct clock_event_device *dev); |
| |
| -extern void clock_was_set_delayed(void); |
| - |
| extern unsigned int hrtimer_resolution; |
| |
| #else |
| |
| #define hrtimer_resolution (unsigned int)LOW_RES_NSEC |
| |
| -static inline void clock_was_set_delayed(void) { } |
| - |
| #endif |
| |
| static inline ktime_t |
| @@ -351,7 +347,6 @@ hrtimer_expires_remaining_adjusted(const struct hrtimer *timer) |
| timer->base->get_time()); |
| } |
| |
| -extern void clock_was_set(void); |
| #ifdef CONFIG_TIMERFD |
| extern void timerfd_clock_was_set(void); |
| #else |
| diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c |
| index ba2e0d0a0e5a..5af758473488 100644 |
| --- a/kernel/time/hrtimer.c |
| +++ b/kernel/time/hrtimer.c |
| @@ -758,22 +758,6 @@ static void hrtimer_switch_to_hres(void) |
| retrigger_next_event(NULL); |
| } |
| |
| -static void clock_was_set_work(struct work_struct *work) |
| -{ |
| - clock_was_set(); |
| -} |
| - |
| -static DECLARE_WORK(hrtimer_work, clock_was_set_work); |
| - |
| -/* |
| - * Called from timekeeping and resume code to reprogram the hrtimer |
| - * interrupt device on all cpus. |
| - */ |
| -void clock_was_set_delayed(void) |
| -{ |
| - schedule_work(&hrtimer_work); |
| -} |
| - |
| #else |
| |
| static inline int hrtimer_is_hres_enabled(void) { return 0; } |
| @@ -891,6 +875,22 @@ void clock_was_set(void) |
| timerfd_clock_was_set(); |
| } |
| |
| +static void clock_was_set_work(struct work_struct *work) |
| +{ |
| + clock_was_set(); |
| +} |
| + |
| +static DECLARE_WORK(hrtimer_work, clock_was_set_work); |
| + |
| +/* |
| + * Called from timekeeping and resume code to reprogram the hrtimer |
| + * interrupt device on all cpus and to notify timerfd. |
| + */ |
| +void clock_was_set_delayed(void) |
| +{ |
| + schedule_work(&hrtimer_work); |
| +} |
| + |
| /* |
| * During resume we might have to reprogram the high resolution timer |
| * interrupt on all online CPUs. However, all other CPUs will be |
| diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h |
| index 7a981c9e87a4..e61c1244e7d4 100644 |
| --- a/kernel/time/tick-internal.h |
| +++ b/kernel/time/tick-internal.h |
| @@ -164,3 +164,6 @@ DECLARE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases); |
| |
| extern u64 get_next_timer_interrupt(unsigned long basej, u64 basem); |
| void timer_clear_idle(void); |
| + |
| +void clock_was_set(void); |
| +void clock_was_set_delayed(void); |
| -- |
| 2.30.2 |
| |