Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+60 -7
+2
arch/x86/include/asm/apic.h
··· 135 135 void register_lapic_address(unsigned long address); 136 136 extern void setup_boot_APIC_clock(void); 137 137 extern void setup_secondary_APIC_clock(void); 138 + extern void lapic_update_tsc_freq(void); 138 139 extern int APIC_init_uniprocessor(void); 139 140 140 141 #ifdef CONFIG_X86_64 ··· 171 170 static inline void disable_local_APIC(void) { } 172 171 # define setup_boot_APIC_clock x86_init_noop 173 172 # define setup_secondary_APIC_clock x86_init_noop 173 + static inline void lapic_update_tsc_freq(void) { } 174 174 #endif /* !CONFIG_X86_LOCAL_APIC */ 175 175 176 176 #ifdef CONFIG_X86_X2APIC
+26 -2
arch/x86/kernel/apic/apic.c
··· 313 313 314 314 /* Clock divisor */ 315 315 #define APIC_DIVISOR 16 316 - #define TSC_DIVISOR 32 316 + #define TSC_DIVISOR 8 317 317 318 318 /* 319 319 * This function sets up the local APIC timer, with a timeout of ··· 565 565 CLOCK_EVT_FEAT_DUMMY); 566 566 levt->set_next_event = lapic_next_deadline; 567 567 clockevents_config_and_register(levt, 568 - (tsc_khz / TSC_DIVISOR) * 1000, 568 + tsc_khz * (1000 / TSC_DIVISOR), 569 569 0xF, ~0UL); 570 570 } else 571 571 clockevents_register_device(levt); 572 + } 573 + 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); 572 596 } 573 597 574 598 /*
+1 -1
arch/x86/kernel/hpet.c
··· 1242 1242 memset(&curr_time, 0, sizeof(struct rtc_time)); 1243 1243 1244 1244 if (hpet_rtc_flags & (RTC_UIE | RTC_AIE)) 1245 - mc146818_set_time(&curr_time); 1245 + mc146818_get_time(&curr_time); 1246 1246 1247 1247 if (hpet_rtc_flags & RTC_UIE && 1248 1248 curr_time.tm_sec != hpet_prev_update_sec) {
+4
arch/x86/kernel/tsc.c
··· 22 22 #include <asm/nmi.h> 23 23 #include <asm/x86_init.h> 24 24 #include <asm/geode.h> 25 + #include <asm/apic.h> 25 26 26 27 unsigned int __read_mostly cpu_khz; /* TSC clocks / usec, not used here */ 27 28 EXPORT_SYMBOL(cpu_khz); ··· 1249 1248 pr_info("Refined TSC clocksource calibration: %lu.%03lu MHz\n", 1250 1249 (unsigned long)tsc_khz / 1000, 1251 1250 (unsigned long)tsc_khz % 1000); 1251 + 1252 + /* Inform the TSC deadline clockevent devices about the recalibration */ 1253 + lapic_update_tsc_freq(); 1252 1254 1253 1255 out: 1254 1256 if (boot_cpu_has(X86_FEATURE_ART))
+23 -3
drivers/clocksource/arm_arch_timer.c
··· 8 8 * it under the terms of the GNU General Public License version 2 as 9 9 * published by the Free Software Foundation. 10 10 */ 11 + 12 + #define pr_fmt(fmt) "arm_arch_timer: " fmt 13 + 11 14 #include <linux/init.h> 12 15 #include <linux/kernel.h> 13 16 #include <linux/device.h> ··· 373 370 arch_timer_ppi[PHYS_NONSECURE_PPI]); 374 371 } 375 372 373 + static u32 check_ppi_trigger(int irq) 374 + { 375 + u32 flags = irq_get_trigger_type(irq); 376 + 377 + if (flags != IRQF_TRIGGER_HIGH && flags != IRQF_TRIGGER_LOW) { 378 + pr_warn("WARNING: Invalid trigger for IRQ%d, assuming level low\n", irq); 379 + pr_warn("WARNING: Please fix your firmware\n"); 380 + flags = IRQF_TRIGGER_LOW; 381 + } 382 + 383 + return flags; 384 + } 385 + 376 386 static int arch_timer_starting_cpu(unsigned int cpu) 377 387 { 378 388 struct clock_event_device *clk = this_cpu_ptr(arch_timer_evt); 389 + u32 flags; 379 390 380 391 __arch_timer_setup(ARCH_CP15_TIMER, clk); 381 392 382 - enable_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], 0); 393 + flags = check_ppi_trigger(arch_timer_ppi[arch_timer_uses_ppi]); 394 + enable_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], flags); 383 395 384 - if (arch_timer_has_nonsecure_ppi()) 385 - enable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], 0); 396 + if (arch_timer_has_nonsecure_ppi()) { 397 + flags = check_ppi_trigger(arch_timer_ppi[PHYS_NONSECURE_PPI]); 398 + enable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], flags); 399 + } 386 400 387 401 arch_counter_set_user_access(); 388 402 if (evtstrm_enable)
+4 -1
kernel/time/timer.c
··· 1496 1496 struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]); 1497 1497 u64 expires = KTIME_MAX; 1498 1498 unsigned long nextevt; 1499 + bool is_max_delta; 1499 1500 1500 1501 /* 1501 1502 * Pretend that there is no timer pending if the cpu is offline. ··· 1507 1506 1508 1507 spin_lock(&base->lock); 1509 1508 nextevt = __next_timer_interrupt(base); 1509 + is_max_delta = (nextevt == base->clk + NEXT_TIMER_MAX_DELTA); 1510 1510 base->next_expiry = nextevt; 1511 1511 /* 1512 1512 * We have a fresh next event. Check whether we can forward the base: ··· 1521 1519 expires = basem; 1522 1520 base->is_idle = false; 1523 1521 } else { 1524 - expires = basem + (nextevt - basej) * TICK_NSEC; 1522 + if (!is_max_delta) 1523 + expires = basem + (nextevt - basej) * TICK_NSEC; 1525 1524 /* 1526 1525 * If we expect to sleep more than a tick, mark the base idle: 1527 1526 */