diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-12 16:55:06 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-12 16:55:06 -0400 |
commit | 3bc6d8c155fbbbe789b6caa44b9e658a5b2995d3 (patch) | |
tree | 6975d22e6c40174e4836187c7f22e4d11a09a977 | |
parent | e6e7214fbbdab1f90254af68e0927bdb24708d22 (diff) | |
parent | 22cc1ca3c5469cf17e149be232817b9223afa5e4 (diff) |
Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer fixes from Ingo Molnar:
"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"
* 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/hpet: Fix /dev/rtc breakage caused by RTC cleanup
x86/timers/apic: Inform TSC deadline clockevent device about recalibration
x86/timers/apic: Fix imprecise timer interrupts by eliminating TSC clockevents frequency roundoff error
timers: Fix get_next_timer_interrupt() computation
clocksource/arm_arch_timer: Force per-CPU interrupt to be level-triggered
-rw-r--r-- | arch/x86/include/asm/apic.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 28 | ||||
-rw-r--r-- | arch/x86/kernel/hpet.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/tsc.c | 4 | ||||
-rw-r--r-- | drivers/clocksource/arm_arch_timer.c | 26 | ||||
-rw-r--r-- | 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); | |||
135 | void register_lapic_address(unsigned long address); | 135 | void register_lapic_address(unsigned long address); |
136 | extern void setup_boot_APIC_clock(void); | 136 | extern void setup_boot_APIC_clock(void); |
137 | extern void setup_secondary_APIC_clock(void); | 137 | extern void setup_secondary_APIC_clock(void); |
138 | extern void lapic_update_tsc_freq(void); | ||
138 | extern int APIC_init_uniprocessor(void); | 139 | extern int APIC_init_uniprocessor(void); |
139 | 140 | ||
140 | #ifdef CONFIG_X86_64 | 141 | #ifdef CONFIG_X86_64 |
@@ -170,6 +171,7 @@ static inline void init_apic_mappings(void) { } | |||
170 | static inline void disable_local_APIC(void) { } | 171 | static inline void disable_local_APIC(void) { } |
171 | # define setup_boot_APIC_clock x86_init_noop | 172 | # define setup_boot_APIC_clock x86_init_noop |
172 | # define setup_secondary_APIC_clock x86_init_noop | 173 | # define setup_secondary_APIC_clock x86_init_noop |
174 | static inline void lapic_update_tsc_freq(void) { } | ||
173 | #endif /* !CONFIG_X86_LOCAL_APIC */ | 175 | #endif /* !CONFIG_X86_LOCAL_APIC */ |
174 | 176 | ||
175 | #ifdef CONFIG_X86_X2APIC | 177 | #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) | |||
313 | 313 | ||
314 | /* Clock divisor */ | 314 | /* Clock divisor */ |
315 | #define APIC_DIVISOR 16 | 315 | #define APIC_DIVISOR 16 |
316 | #define TSC_DIVISOR 32 | 316 | #define TSC_DIVISOR 8 |
317 | 317 | ||
318 | /* | 318 | /* |
319 | * This function sets up the local APIC timer, with a timeout of | 319 | * This function sets up the local APIC timer, with a timeout of |
@@ -565,13 +565,37 @@ static void setup_APIC_timer(void) | |||
565 | CLOCK_EVT_FEAT_DUMMY); | 565 | CLOCK_EVT_FEAT_DUMMY); |
566 | levt->set_next_event = lapic_next_deadline; | 566 | levt->set_next_event = lapic_next_deadline; |
567 | clockevents_config_and_register(levt, | 567 | clockevents_config_and_register(levt, |
568 | (tsc_khz / TSC_DIVISOR) * 1000, | 568 | tsc_khz * (1000 / TSC_DIVISOR), |
569 | 0xF, ~0UL); | 569 | 0xF, ~0UL); |
570 | } else | 570 | } else |
571 | clockevents_register_device(levt); | 571 | clockevents_register_device(levt); |
572 | } | 572 | } |
573 | 573 | ||
574 | /* | 574 | /* |
575 | * Install the updated TSC frequency from recalibration at the TSC | ||
576 | * deadline clockevent devices. | ||
577 | */ | ||
578 | static void __lapic_update_tsc_freq(void *info) | ||
579 | { | ||
580 | struct clock_event_device *levt = this_cpu_ptr(&lapic_events); | ||
581 | |||
582 | if (!this_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) | ||
583 | return; | ||
584 | |||
585 | clockevents_update_freq(levt, tsc_khz * (1000 / TSC_DIVISOR)); | ||
586 | } | ||
587 | |||
588 | void lapic_update_tsc_freq(void) | ||
589 | { | ||
590 | /* | ||
591 | * The clockevent device's ->mult and ->shift can both be | ||
592 | * changed. In order to avoid races, schedule the frequency | ||
593 | * update code on each CPU. | ||
594 | */ | ||
595 | on_each_cpu(__lapic_update_tsc_freq, NULL, 0); | ||
596 | } | ||
597 | |||
598 | /* | ||
575 | * In this functions we calibrate APIC bus clocks to the external timer. | 599 | * In this functions we calibrate APIC bus clocks to the external timer. |
576 | * | 600 | * |
577 | * We want to do the calibration only once since we want to have local timer | 601 | * 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) | |||
1242 | memset(&curr_time, 0, sizeof(struct rtc_time)); | 1242 | memset(&curr_time, 0, sizeof(struct rtc_time)); |
1243 | 1243 | ||
1244 | if (hpet_rtc_flags & (RTC_UIE | RTC_AIE)) | 1244 | if (hpet_rtc_flags & (RTC_UIE | RTC_AIE)) |
1245 | mc146818_set_time(&curr_time); | 1245 | mc146818_get_time(&curr_time); |
1246 | 1246 | ||
1247 | if (hpet_rtc_flags & RTC_UIE && | 1247 | if (hpet_rtc_flags & RTC_UIE && |
1248 | curr_time.tm_sec != hpet_prev_update_sec) { | 1248 | 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 @@ | |||
22 | #include <asm/nmi.h> | 22 | #include <asm/nmi.h> |
23 | #include <asm/x86_init.h> | 23 | #include <asm/x86_init.h> |
24 | #include <asm/geode.h> | 24 | #include <asm/geode.h> |
25 | #include <asm/apic.h> | ||
25 | 26 | ||
26 | unsigned int __read_mostly cpu_khz; /* TSC clocks / usec, not used here */ | 27 | unsigned int __read_mostly cpu_khz; /* TSC clocks / usec, not used here */ |
27 | EXPORT_SYMBOL(cpu_khz); | 28 | EXPORT_SYMBOL(cpu_khz); |
@@ -1249,6 +1250,9 @@ static void tsc_refine_calibration_work(struct work_struct *work) | |||
1249 | (unsigned long)tsc_khz / 1000, | 1250 | (unsigned long)tsc_khz / 1000, |
1250 | (unsigned long)tsc_khz % 1000); | 1251 | (unsigned long)tsc_khz % 1000); |
1251 | 1252 | ||
1253 | /* Inform the TSC deadline clockevent devices about the recalibration */ | ||
1254 | lapic_update_tsc_freq(); | ||
1255 | |||
1252 | out: | 1256 | out: |
1253 | if (boot_cpu_has(X86_FEATURE_ART)) | 1257 | if (boot_cpu_has(X86_FEATURE_ART)) |
1254 | art_related_clocksource = &clocksource_tsc; | 1258 | 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 @@ | |||
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | |||
12 | #define pr_fmt(fmt) "arm_arch_timer: " fmt | ||
13 | |||
11 | #include <linux/init.h> | 14 | #include <linux/init.h> |
12 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
13 | #include <linux/device.h> | 16 | #include <linux/device.h> |
@@ -370,16 +373,33 @@ static bool arch_timer_has_nonsecure_ppi(void) | |||
370 | arch_timer_ppi[PHYS_NONSECURE_PPI]); | 373 | arch_timer_ppi[PHYS_NONSECURE_PPI]); |
371 | } | 374 | } |
372 | 375 | ||
376 | static u32 check_ppi_trigger(int irq) | ||
377 | { | ||
378 | u32 flags = irq_get_trigger_type(irq); | ||
379 | |||
380 | if (flags != IRQF_TRIGGER_HIGH && flags != IRQF_TRIGGER_LOW) { | ||
381 | pr_warn("WARNING: Invalid trigger for IRQ%d, assuming level low\n", irq); | ||
382 | pr_warn("WARNING: Please fix your firmware\n"); | ||
383 | flags = IRQF_TRIGGER_LOW; | ||
384 | } | ||
385 | |||
386 | return flags; | ||
387 | } | ||
388 | |||
373 | static int arch_timer_starting_cpu(unsigned int cpu) | 389 | static int arch_timer_starting_cpu(unsigned int cpu) |
374 | { | 390 | { |
375 | struct clock_event_device *clk = this_cpu_ptr(arch_timer_evt); | 391 | struct clock_event_device *clk = this_cpu_ptr(arch_timer_evt); |
392 | u32 flags; | ||
376 | 393 | ||
377 | __arch_timer_setup(ARCH_CP15_TIMER, clk); | 394 | __arch_timer_setup(ARCH_CP15_TIMER, clk); |
378 | 395 | ||
379 | enable_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], 0); | 396 | flags = check_ppi_trigger(arch_timer_ppi[arch_timer_uses_ppi]); |
397 | enable_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], flags); | ||
380 | 398 | ||
381 | if (arch_timer_has_nonsecure_ppi()) | 399 | if (arch_timer_has_nonsecure_ppi()) { |
382 | enable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], 0); | 400 | flags = check_ppi_trigger(arch_timer_ppi[PHYS_NONSECURE_PPI]); |
401 | enable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], flags); | ||
402 | } | ||
383 | 403 | ||
384 | arch_counter_set_user_access(); | 404 | arch_counter_set_user_access(); |
385 | if (evtstrm_enable) | 405 | 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) | |||
1496 | struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]); | 1496 | struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]); |
1497 | u64 expires = KTIME_MAX; | 1497 | u64 expires = KTIME_MAX; |
1498 | unsigned long nextevt; | 1498 | unsigned long nextevt; |
1499 | bool is_max_delta; | ||
1499 | 1500 | ||
1500 | /* | 1501 | /* |
1501 | * Pretend that there is no timer pending if the cpu is offline. | 1502 | * 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) | |||
1506 | 1507 | ||
1507 | spin_lock(&base->lock); | 1508 | spin_lock(&base->lock); |
1508 | nextevt = __next_timer_interrupt(base); | 1509 | nextevt = __next_timer_interrupt(base); |
1510 | is_max_delta = (nextevt == base->clk + NEXT_TIMER_MAX_DELTA); | ||
1509 | base->next_expiry = nextevt; | 1511 | base->next_expiry = nextevt; |
1510 | /* | 1512 | /* |
1511 | * We have a fresh next event. Check whether we can forward the base: | 1513 | * 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) | |||
1519 | expires = basem; | 1521 | expires = basem; |
1520 | base->is_idle = false; | 1522 | base->is_idle = false; |
1521 | } else { | 1523 | } else { |
1522 | expires = basem + (nextevt - basej) * TICK_NSEC; | 1524 | if (!is_max_delta) |
1525 | expires = basem + (nextevt - basej) * TICK_NSEC; | ||
1523 | /* | 1526 | /* |
1524 | * If we expect to sleep more than a tick, mark the base idle: | 1527 | * If we expect to sleep more than a tick, mark the base idle: |
1525 | */ | 1528 | */ |