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 tag 'timers_urgent_for_v6.8_rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull timer fixes from Borislav Petkov:

- Preserve the number of idle calls and sleep entries across CPU
hotplug events in order to be able to compute correct averages

- Limit the duration of the clocksource watchdog checking interval as
too long intervals lead to wrongly marking the TSC as unstable

* tag 'timers_urgent_for_v6.8_rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
tick/sched: Preserve number of idle sleeps across CPU hotplug events
clocksource: Skip watchdog check for large watchdog intervals

+29 -1
+24 -1
kernel/time/clocksource.c
··· 99 99 * Interval: 0.5sec. 100 100 */ 101 101 #define WATCHDOG_INTERVAL (HZ >> 1) 102 + #define WATCHDOG_INTERVAL_MAX_NS ((2 * WATCHDOG_INTERVAL) * (NSEC_PER_SEC / HZ)) 102 103 103 104 /* 104 105 * Threshold: 0.0312s, when doubled: 0.0625s. ··· 135 134 static DEFINE_SPINLOCK(watchdog_lock); 136 135 static int watchdog_running; 137 136 static atomic_t watchdog_reset_pending; 137 + static int64_t watchdog_max_interval; 138 138 139 139 static inline void clocksource_watchdog_lock(unsigned long *flags) 140 140 { ··· 401 399 static void clocksource_watchdog(struct timer_list *unused) 402 400 { 403 401 u64 csnow, wdnow, cslast, wdlast, delta; 402 + int64_t wd_nsec, cs_nsec, interval; 404 403 int next_cpu, reset_pending; 405 - int64_t wd_nsec, cs_nsec; 406 404 struct clocksource *cs; 407 405 enum wd_read_status read_ret; 408 406 unsigned long extra_wait = 0; ··· 471 469 472 470 if (atomic_read(&watchdog_reset_pending)) 473 471 continue; 472 + 473 + /* 474 + * The processing of timer softirqs can get delayed (usually 475 + * on account of ksoftirqd not getting to run in a timely 476 + * manner), which causes the watchdog interval to stretch. 477 + * Skew detection may fail for longer watchdog intervals 478 + * on account of fixed margins being used. 479 + * Some clocksources, e.g. acpi_pm, cannot tolerate 480 + * watchdog intervals longer than a few seconds. 481 + */ 482 + interval = max(cs_nsec, wd_nsec); 483 + if (unlikely(interval > WATCHDOG_INTERVAL_MAX_NS)) { 484 + if (system_state > SYSTEM_SCHEDULING && 485 + interval > 2 * watchdog_max_interval) { 486 + watchdog_max_interval = interval; 487 + pr_warn("Long readout interval, skipping watchdog check: cs_nsec: %lld wd_nsec: %lld\n", 488 + cs_nsec, wd_nsec); 489 + } 490 + watchdog_timer.expires = jiffies; 491 + continue; 492 + } 474 493 475 494 /* Check the deviation from the watchdog clocksource. */ 476 495 md = cs->uncertainty_margin + watchdog->uncertainty_margin;
+5
kernel/time/tick-sched.c
··· 1577 1577 { 1578 1578 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); 1579 1579 ktime_t idle_sleeptime, iowait_sleeptime; 1580 + unsigned long idle_calls, idle_sleeps; 1580 1581 1581 1582 # ifdef CONFIG_HIGH_RES_TIMERS 1582 1583 if (ts->sched_timer.base) ··· 1586 1585 1587 1586 idle_sleeptime = ts->idle_sleeptime; 1588 1587 iowait_sleeptime = ts->iowait_sleeptime; 1588 + idle_calls = ts->idle_calls; 1589 + idle_sleeps = ts->idle_sleeps; 1589 1590 memset(ts, 0, sizeof(*ts)); 1590 1591 ts->idle_sleeptime = idle_sleeptime; 1591 1592 ts->iowait_sleeptime = iowait_sleeptime; 1593 + ts->idle_calls = idle_calls; 1594 + ts->idle_sleeps = idle_sleeps; 1592 1595 } 1593 1596 #endif 1594 1597