From: Ingo Molnar <mingo@kernel.org>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: linux-kernel@vger.kernel.org,
Thomas Gleixner <tglx@linutronix.de>,
Peter Zijlstra <a.p.zijlstra@chello.nl>,
Andrew Morton <akpm@linux-foundation.org>
Subject: [GIT PULL] timer fixes
Date: Fri, 12 Aug 2016 21:43:00 +0200 [thread overview]
Message-ID: <20160812194300.GA30748@gmail.com> (raw)
Linus,
Please pull the latest timers-urgent-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-for-linus
# HEAD: 22cc1ca3c5469cf17e149be232817b9223afa5e4 x86/hpet: Fix /dev/rtc breakage caused by RTC cleanup
Misc fixes: a /dev/rtc regression fix, two APIC timer period calibration fixes, an
ARM clocksource driver fix and a NOHZ power use regression fix.
Thanks,
Ingo
------------------>
Arnd Bergmann (1):
x86/hpet: Fix /dev/rtc breakage caused by RTC cleanup
Chris Metcalf (1):
timers: Fix get_next_timer_interrupt() computation
Marc Zyngier (1):
clocksource/arm_arch_timer: Force per-CPU interrupt to be level-triggered
Nicolai Stange (2):
x86/timers/apic: Fix imprecise timer interrupts by eliminating TSC clockevents frequency roundoff error
x86/timers/apic: Inform TSC deadline clockevent device about recalibration
arch/x86/include/asm/apic.h | 2 ++
arch/x86/kernel/apic/apic.c | 28 ++++++++++++++++++++++++++--
arch/x86/kernel/hpet.c | 2 +-
arch/x86/kernel/tsc.c | 4 ++++
drivers/clocksource/arm_arch_timer.c | 26 +++++++++++++++++++++++---
kernel/time/timer.c | 5 ++++-
6 files changed, 60 insertions(+), 7 deletions(-)
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index f5befd4945f2..124357773ffa 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -135,6 +135,7 @@ extern void init_apic_mappings(void);
void register_lapic_address(unsigned long address);
extern void setup_boot_APIC_clock(void);
extern void setup_secondary_APIC_clock(void);
+extern void lapic_update_tsc_freq(void);
extern int APIC_init_uniprocessor(void);
#ifdef CONFIG_X86_64
@@ -170,6 +171,7 @@ static inline void init_apic_mappings(void) { }
static inline void disable_local_APIC(void) { }
# define setup_boot_APIC_clock x86_init_noop
# define setup_secondary_APIC_clock x86_init_noop
+static inline void lapic_update_tsc_freq(void) { }
#endif /* !CONFIG_X86_LOCAL_APIC */
#ifdef CONFIG_X86_X2APIC
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 20abd912f0e4..cea4fc19e844 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -313,7 +313,7 @@ int lapic_get_maxlvt(void)
/* Clock divisor */
#define APIC_DIVISOR 16
-#define TSC_DIVISOR 32
+#define TSC_DIVISOR 8
/*
* This function sets up the local APIC timer, with a timeout of
@@ -565,13 +565,37 @@ static void setup_APIC_timer(void)
CLOCK_EVT_FEAT_DUMMY);
levt->set_next_event = lapic_next_deadline;
clockevents_config_and_register(levt,
- (tsc_khz / TSC_DIVISOR) * 1000,
+ tsc_khz * (1000 / TSC_DIVISOR),
0xF, ~0UL);
} else
clockevents_register_device(levt);
}
/*
+ * Install the updated TSC frequency from recalibration at the TSC
+ * deadline clockevent devices.
+ */
+static void __lapic_update_tsc_freq(void *info)
+{
+ struct clock_event_device *levt = this_cpu_ptr(&lapic_events);
+
+ if (!this_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER))
+ return;
+
+ clockevents_update_freq(levt, tsc_khz * (1000 / TSC_DIVISOR));
+}
+
+void lapic_update_tsc_freq(void)
+{
+ /*
+ * The clockevent device's ->mult and ->shift can both be
+ * changed. In order to avoid races, schedule the frequency
+ * update code on each CPU.
+ */
+ on_each_cpu(__lapic_update_tsc_freq, NULL, 0);
+}
+
+/*
* In this functions we calibrate APIC bus clocks to the external timer.
*
* We want to do the calibration only once since we want to have local timer
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index ed16e58658a4..c6dfd801df97 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -1242,7 +1242,7 @@ irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id)
memset(&curr_time, 0, sizeof(struct rtc_time));
if (hpet_rtc_flags & (RTC_UIE | RTC_AIE))
- mc146818_set_time(&curr_time);
+ mc146818_get_time(&curr_time);
if (hpet_rtc_flags & RTC_UIE &&
curr_time.tm_sec != hpet_prev_update_sec) {
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 1ef87e887051..78b9cb5a26af 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -22,6 +22,7 @@
#include <asm/nmi.h>
#include <asm/x86_init.h>
#include <asm/geode.h>
+#include <asm/apic.h>
unsigned int __read_mostly cpu_khz; /* TSC clocks / usec, not used here */
EXPORT_SYMBOL(cpu_khz);
@@ -1249,6 +1250,9 @@ static void tsc_refine_calibration_work(struct work_struct *work)
(unsigned long)tsc_khz / 1000,
(unsigned long)tsc_khz % 1000);
+ /* Inform the TSC deadline clockevent devices about the recalibration */
+ lapic_update_tsc_freq();
+
out:
if (boot_cpu_has(X86_FEATURE_ART))
art_related_clocksource = &clocksource_tsc;
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 28bce3f4f81d..57700541f951 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -8,6 +8,9 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+
+#define pr_fmt(fmt) "arm_arch_timer: " fmt
+
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/device.h>
@@ -370,16 +373,33 @@ static bool arch_timer_has_nonsecure_ppi(void)
arch_timer_ppi[PHYS_NONSECURE_PPI]);
}
+static u32 check_ppi_trigger(int irq)
+{
+ u32 flags = irq_get_trigger_type(irq);
+
+ if (flags != IRQF_TRIGGER_HIGH && flags != IRQF_TRIGGER_LOW) {
+ pr_warn("WARNING: Invalid trigger for IRQ%d, assuming level low\n", irq);
+ pr_warn("WARNING: Please fix your firmware\n");
+ flags = IRQF_TRIGGER_LOW;
+ }
+
+ return flags;
+}
+
static int arch_timer_starting_cpu(unsigned int cpu)
{
struct clock_event_device *clk = this_cpu_ptr(arch_timer_evt);
+ u32 flags;
__arch_timer_setup(ARCH_CP15_TIMER, clk);
- enable_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], 0);
+ flags = check_ppi_trigger(arch_timer_ppi[arch_timer_uses_ppi]);
+ enable_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], flags);
- if (arch_timer_has_nonsecure_ppi())
- enable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], 0);
+ if (arch_timer_has_nonsecure_ppi()) {
+ flags = check_ppi_trigger(arch_timer_ppi[PHYS_NONSECURE_PPI]);
+ enable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], flags);
+ }
arch_counter_set_user_access();
if (evtstrm_enable)
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 555670a5143c..32bf6f75a8fe 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -1496,6 +1496,7 @@ u64 get_next_timer_interrupt(unsigned long basej, u64 basem)
struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]);
u64 expires = KTIME_MAX;
unsigned long nextevt;
+ bool is_max_delta;
/*
* Pretend that there is no timer pending if the cpu is offline.
@@ -1506,6 +1507,7 @@ u64 get_next_timer_interrupt(unsigned long basej, u64 basem)
spin_lock(&base->lock);
nextevt = __next_timer_interrupt(base);
+ is_max_delta = (nextevt == base->clk + NEXT_TIMER_MAX_DELTA);
base->next_expiry = nextevt;
/*
* We have a fresh next event. Check whether we can forward the base:
@@ -1519,7 +1521,8 @@ u64 get_next_timer_interrupt(unsigned long basej, u64 basem)
expires = basem;
base->is_idle = false;
} else {
- expires = basem + (nextevt - basej) * TICK_NSEC;
+ if (!is_max_delta)
+ expires = basem + (nextevt - basej) * TICK_NSEC;
/*
* If we expect to sleep more than a tick, mark the base idle:
*/
next reply other threads:[~2016-08-12 19:43 UTC|newest]
Thread overview: 77+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-08-12 19:43 Ingo Molnar [this message]
-- strict thread matches above, loose matches on Subject: below --
2025-04-10 21:34 [GIT PULL] timer fixes Ingo Molnar
2025-04-10 22:52 ` pr-tracker-bot
2025-02-08 9:27 Ingo Molnar
2025-02-08 20:07 ` pr-tracker-bot
2024-04-14 8:42 Ingo Molnar
2024-04-14 18:48 ` pr-tracker-bot
2024-04-07 8:03 Ingo Molnar
2024-04-07 16:44 ` pr-tracker-bot
2023-01-12 14:44 Ingo Molnar
2023-01-12 23:01 ` pr-tracker-bot
2022-08-13 10:25 Ingo Molnar
2022-08-13 16:25 ` Borislav Petkov
2022-08-13 20:27 ` Linus Torvalds
2022-08-14 8:57 ` Ingo Molnar
2022-08-14 12:41 ` Borislav Petkov
2022-08-14 17:24 ` Paul E. McKenney
2022-08-14 17:42 ` Borislav Petkov
2022-08-13 21:48 ` pr-tracker-bot
2020-12-27 9:26 Ingo Molnar
2020-12-27 17:27 ` pr-tracker-bot
2019-12-17 11:55 Ingo Molnar
2019-12-17 19:14 ` Linus Torvalds
2019-12-17 19:30 ` Peter Zijlstra
2019-12-17 20:16 ` Linus Torvalds
2019-12-17 20:35 ` Peter Zijlstra
2019-12-17 20:43 ` Linus Torvalds
2019-12-17 20:54 ` Peter Zijlstra
2019-12-17 19:20 ` pr-tracker-bot
2019-05-16 16:09 Ingo Molnar
2019-05-16 18:20 ` pr-tracker-bot
2019-04-20 7:45 Ingo Molnar
2019-04-20 19:25 ` pr-tracker-bot
2018-07-13 20:01 Ingo Molnar
2017-03-07 20:36 Ingo Molnar
2016-10-28 8:38 Ingo Molnar
2016-08-18 20:46 Ingo Molnar
2016-01-14 10:12 Ingo Molnar
2015-10-03 10:20 Ingo Molnar
2015-09-17 8:13 Ingo Molnar
2015-03-28 13:50 Ingo Molnar
2015-03-17 16:50 Ingo Molnar
2015-03-01 17:06 Ingo Molnar
2013-12-17 13:52 Ingo Molnar
2013-09-28 18:19 Ingo Molnar
2013-08-19 9:41 Ingo Molnar
2013-02-26 11:32 Ingo Molnar
2012-09-21 19:12 Ingo Molnar
2012-08-03 16:47 Ingo Molnar
2011-12-20 19:25 Ingo Molnar
2011-12-05 19:00 Ingo Molnar
2011-06-19 8:51 Ingo Molnar
2011-06-13 9:55 Ingo Molnar
2011-06-06 19:10 [GIT pull] " Thomas Gleixner
2011-05-20 17:52 Thomas Gleixner
2011-04-19 16:03 [GIT PULL] " Ingo Molnar
2011-04-16 10:09 Ingo Molnar
2011-04-07 17:42 Ingo Molnar
2011-02-06 12:06 Ingo Molnar
2011-01-24 13:24 Ingo Molnar
2010-11-26 13:40 Ingo Molnar
2010-03-26 15:34 Ingo Molnar
2009-12-18 18:49 Ingo Molnar
2009-10-08 18:35 Ingo Molnar
2009-08-25 18:04 Ingo Molnar
2009-06-26 19:03 Ingo Molnar
2009-04-09 15:43 Ingo Molnar
2009-01-30 23:07 [git pull] " Ingo Molnar
2009-01-26 17:21 Ingo Molnar
2009-01-06 16:18 Ingo Molnar
2008-12-04 20:52 Ingo Molnar
2008-11-11 18:47 Ingo Molnar
2008-09-23 19:41 Ingo Molnar
2008-09-17 9:59 Ingo Molnar
2008-08-25 17:52 Ingo Molnar
2008-08-22 12:24 Ingo Molnar
2008-07-24 15:18 Ingo Molnar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160812194300.GA30748@gmail.com \
--to=mingo@kernel.org \
--cc=a.p.zijlstra@chello.nl \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).