Skip to content

Commit 560b803

Browse files
committed
Merge tag 'timers-core-2023-02-20' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer updates from Thomas Gleixner: "Updates for timekeeping, timers and clockevent/source drivers: Core: - Yet another round of improvements to make the clocksource watchdog more robust: - Relax the clocksource-watchdog skew criteria to match the NTP criteria. - Temporarily skip the watchdog when high memory latencies are detected which can lead to false-positives. - Provide an option to enable TSC skew detection even on systems where TSC is marked as reliable. Sigh! - Initialize the restart block in the nanosleep syscalls to be directed to the no restart function instead of doing a partial setup on entry. This prevents an erroneous restart_syscall() invocation from corrupting user space data. While such a situation is clearly a user space bug, preventing this is a correctness issue and caters to the least suprise principle. - Ignore the hrtimer slack for realtime tasks in schedule_hrtimeout() to align it with the nanosleep semantics. Drivers: - The obligatory new driver bindings for Mediatek, Rockchip and RISC-V variants. - Add support for the C3STOP misfeature to the RISC-V timer to handle the case where the timer stops in deeper idle state. - Set up a static key in the RISC-V timer correctly before first use. - The usual small improvements and fixes all over the place" * tag 'timers-core-2023-02-20' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (30 commits) clocksource/drivers/timer-sun4i: Add CLOCK_EVT_FEAT_DYNIRQ clocksource/drivers/em_sti: Mark driver as non-removable clocksource/drivers/sh_tmu: Mark driver as non-removable clocksource/drivers/riscv: Patch riscv_clock_next_event() jump before first use clocksource/drivers/timer-microchip-pit64b: Add delay timer clocksource/drivers/timer-microchip-pit64b: Select driver only on ARM dt-bindings: timer: sifive,clint: add comaptibles for T-Head's C9xx dt-bindings: timer: mediatek,mtk-timer: add MT8365 clocksource/drivers/riscv: Get rid of clocksource_arch_init() callback clocksource/drivers/sh_cmt: Mark driver as non-removable clocksource/drivers/timer-microchip-pit64b: Drop obsolete dependency on COMPILE_TEST clocksource/drivers/riscv: Increase the clock source rating clocksource/drivers/timer-riscv: Set CLOCK_EVT_FEAT_C3STOP based on DT dt-bindings: timer: Add bindings for the RISC-V timer device RISC-V: time: initialize hrtimer based broadcast clock event device dt-bindings: timer: rk-timer: Add rktimer for rv1126 time/debug: Fix memory leak with using debugfs_lookup() clocksource: Enable TSC watchdog checking of HPET and PMTMR only when requested posix-timers: Use atomic64_try_cmpxchg() in __update_gt_cputime() clocksource: Verify HPET and PMTMR when TSC unverified ...
2 parents 056612f + ab407a1 commit 560b803

File tree

27 files changed

+252
-77
lines changed

27 files changed

+252
-77
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6369,6 +6369,16 @@
63696369
in situations with strict latency requirements (where
63706370
interruptions from clocksource watchdog are not
63716371
acceptable).
6372+
[x86] recalibrate: force recalibration against a HW timer
6373+
(HPET or PM timer) on systems whose TSC frequency was
6374+
obtained from HW or FW using either an MSR or CPUID(0x15).
6375+
Warn if the difference is more than 500 ppm.
6376+
[x86] watchdog: Use TSC as the watchdog clocksource with
6377+
which to check other HW timers (HPET or PM timer), but
6378+
only on systems where TSC has been deemed trustworthy.
6379+
This will be suppressed by an earlier tsc=nowatchdog and
6380+
can be overridden by a later tsc=nowatchdog. A console
6381+
message will flag any such suppression or overriding.
63726382

63736383
tsc_early_khz= [X86] Skip early TSC calibration and use the given
63746384
value instead. Useful when the early TSC frequency discovery

Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Required properties:
3333

3434
For those SoCs that use CPUX
3535
* "mediatek,mt6795-systimer" for MT6795 compatible timers (CPUX)
36+
* "mediatek,mt8365-systimer" for MT8365 compatible timers (CPUX)
3637

3738
- reg: Should contain location and length for timer register.
3839
- clocks: Should contain system clock.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/timer/riscv,timer.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: RISC-V timer
8+
9+
maintainers:
10+
- Anup Patel <[email protected]>
11+
12+
description: |+
13+
RISC-V platforms always have a RISC-V timer device for the supervisor-mode
14+
based on the time CSR defined by the RISC-V privileged specification. The
15+
timer interrupts of this device are configured using the RISC-V SBI Time
16+
extension or the RISC-V Sstc extension.
17+
18+
The clock frequency of RISC-V timer device is specified via the
19+
"timebase-frequency" DT property of "/cpus" DT node which is described
20+
in Documentation/devicetree/bindings/riscv/cpus.yaml
21+
22+
properties:
23+
compatible:
24+
enum:
25+
- riscv,timer
26+
27+
interrupts-extended:
28+
minItems: 1
29+
maxItems: 4096 # Should be enough?
30+
31+
riscv,timer-cannot-wake-cpu:
32+
type: boolean
33+
description:
34+
If present, the timer interrupt cannot wake up the CPU from one or
35+
more suspend/idle states.
36+
37+
additionalProperties: false
38+
39+
required:
40+
- compatible
41+
- interrupts-extended
42+
43+
examples:
44+
- |
45+
timer {
46+
compatible = "riscv,timer";
47+
interrupts-extended = <&cpu1intc 5>,
48+
<&cpu2intc 5>,
49+
<&cpu3intc 5>,
50+
<&cpu4intc 5>;
51+
};
52+
...

Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ properties:
1717
- items:
1818
- enum:
1919
- rockchip,rv1108-timer
20+
- rockchip,rv1126-timer
2021
- rockchip,rk3036-timer
2122
- rockchip,rk3128-timer
2223
- rockchip,rk3188-timer

Documentation/devicetree/bindings/timer/sifive,clint.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ description:
2020
property of "/cpus" DT node. The "timebase-frequency" DT property is
2121
described in Documentation/devicetree/bindings/riscv/cpus.yaml
2222

23+
T-Head C906/C910 CPU cores include an implementation of CLINT too, however
24+
their implementation lacks a memory-mapped MTIME register, thus not
25+
compatible with SiFive ones.
26+
2327
properties:
2428
compatible:
2529
oneOf:
@@ -29,6 +33,10 @@ properties:
2933
- starfive,jh7100-clint
3034
- canaan,k210-clint
3135
- const: sifive,clint0
36+
- items:
37+
- enum:
38+
- allwinner,sun20i-d1-clint
39+
- const: thead,c900-clint
3240
- items:
3341
- const: sifive,clint0
3442
- const: riscv,clint0

arch/riscv/Kconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ config 32BIT
1212

1313
config RISCV
1414
def_bool y
15-
select ARCH_CLOCKSOURCE_INIT
1615
select ARCH_ENABLE_HUGEPAGE_MIGRATION if HUGETLB_PAGE && MIGRATION
1716
select ARCH_ENABLE_SPLIT_PMD_PTLOCK if PGTABLE_LEVELS > 2
1817
select ARCH_HAS_BINFMT_FLAT

arch/riscv/kernel/time.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
#include <linux/of_clk.h>
8+
#include <linux/clockchips.h>
89
#include <linux/clocksource.h>
910
#include <linux/delay.h>
1011
#include <asm/sbi.h>
@@ -29,13 +30,6 @@ void __init time_init(void)
2930

3031
of_clk_init(NULL);
3132
timer_probe();
32-
}
3333

34-
void clocksource_arch_init(struct clocksource *cs)
35-
{
36-
#ifdef CONFIG_GENERIC_GETTIMEOFDAY
37-
cs->vdso_clock_mode = VDSO_CLOCKMODE_ARCHTIMER;
38-
#else
39-
cs->vdso_clock_mode = VDSO_CLOCKMODE_NONE;
40-
#endif
34+
tick_setup_hrtimer_broadcast();
4135
}

arch/x86/include/asm/time.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
extern void hpet_time_init(void);
99
extern void time_init(void);
1010
extern bool pit_timer_init(void);
11+
extern bool tsc_clocksource_watchdog_disabled(void);
1112

1213
extern struct clock_event_device *global_clock_event;
1314

arch/x86/kernel/hpet.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,6 +1091,8 @@ int __init hpet_enable(void)
10911091
if (!hpet_counting())
10921092
goto out_nohpet;
10931093

1094+
if (tsc_clocksource_watchdog_disabled())
1095+
clocksource_hpet.flags |= CLOCK_SOURCE_MUST_VERIFY;
10941096
clocksource_register_hz(&clocksource_hpet, (u32)hpet_freq);
10951097

10961098
if (id & HPET_ID_LEGSUP) {

arch/x86/kernel/tsc.c

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ static DEFINE_STATIC_KEY_FALSE(__use_tsc);
4848

4949
int tsc_clocksource_reliable;
5050

51+
static int __read_mostly tsc_force_recalibrate;
52+
5153
static u32 art_to_tsc_numerator;
5254
static u32 art_to_tsc_denominator;
5355
static u64 art_to_tsc_offset;
@@ -291,6 +293,7 @@ __setup("notsc", notsc_setup);
291293

292294
static int no_sched_irq_time;
293295
static int no_tsc_watchdog;
296+
static int tsc_as_watchdog;
294297

295298
static int __init tsc_setup(char *str)
296299
{
@@ -300,8 +303,22 @@ static int __init tsc_setup(char *str)
300303
no_sched_irq_time = 1;
301304
if (!strcmp(str, "unstable"))
302305
mark_tsc_unstable("boot parameter");
303-
if (!strcmp(str, "nowatchdog"))
306+
if (!strcmp(str, "nowatchdog")) {
304307
no_tsc_watchdog = 1;
308+
if (tsc_as_watchdog)
309+
pr_alert("%s: Overriding earlier tsc=watchdog with tsc=nowatchdog\n",
310+
__func__);
311+
tsc_as_watchdog = 0;
312+
}
313+
if (!strcmp(str, "recalibrate"))
314+
tsc_force_recalibrate = 1;
315+
if (!strcmp(str, "watchdog")) {
316+
if (no_tsc_watchdog)
317+
pr_alert("%s: tsc=watchdog overridden by earlier tsc=nowatchdog\n",
318+
__func__);
319+
else
320+
tsc_as_watchdog = 1;
321+
}
305322
return 1;
306323
}
307324

@@ -1184,6 +1201,12 @@ static void __init tsc_disable_clocksource_watchdog(void)
11841201
clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY;
11851202
}
11861203

1204+
bool tsc_clocksource_watchdog_disabled(void)
1205+
{
1206+
return !(clocksource_tsc.flags & CLOCK_SOURCE_MUST_VERIFY) &&
1207+
tsc_as_watchdog && !no_tsc_watchdog;
1208+
}
1209+
11871210
static void __init check_system_tsc_reliable(void)
11881211
{
11891212
#if defined(CONFIG_MGEODEGX1) || defined(CONFIG_MGEODE_LX) || defined(CONFIG_X86_GENERIC)
@@ -1372,6 +1395,25 @@ static void tsc_refine_calibration_work(struct work_struct *work)
13721395
else
13731396
freq = calc_pmtimer_ref(delta, ref_start, ref_stop);
13741397

1398+
/* Will hit this only if tsc_force_recalibrate has been set */
1399+
if (boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) {
1400+
1401+
/* Warn if the deviation exceeds 500 ppm */
1402+
if (abs(tsc_khz - freq) > (tsc_khz >> 11)) {
1403+
pr_warn("Warning: TSC freq calibrated by CPUID/MSR differs from what is calibrated by HW timer, please check with vendor!!\n");
1404+
pr_info("Previous calibrated TSC freq:\t %lu.%03lu MHz\n",
1405+
(unsigned long)tsc_khz / 1000,
1406+
(unsigned long)tsc_khz % 1000);
1407+
}
1408+
1409+
pr_info("TSC freq recalibrated by [%s]:\t %lu.%03lu MHz\n",
1410+
hpet ? "HPET" : "PM_TIMER",
1411+
(unsigned long)freq / 1000,
1412+
(unsigned long)freq % 1000);
1413+
1414+
return;
1415+
}
1416+
13751417
/* Make sure we're within 1% */
13761418
if (abs(tsc_khz - freq) > tsc_khz/100)
13771419
goto out;
@@ -1405,8 +1447,10 @@ static int __init init_tsc_clocksource(void)
14051447
if (!boot_cpu_has(X86_FEATURE_TSC) || !tsc_khz)
14061448
return 0;
14071449

1408-
if (tsc_unstable)
1409-
goto unreg;
1450+
if (tsc_unstable) {
1451+
clocksource_unregister(&clocksource_tsc_early);
1452+
return 0;
1453+
}
14101454

14111455
if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC_S3))
14121456
clocksource_tsc.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
@@ -1419,9 +1463,10 @@ static int __init init_tsc_clocksource(void)
14191463
if (boot_cpu_has(X86_FEATURE_ART))
14201464
art_related_clocksource = &clocksource_tsc;
14211465
clocksource_register_khz(&clocksource_tsc, tsc_khz);
1422-
unreg:
14231466
clocksource_unregister(&clocksource_tsc_early);
1424-
return 0;
1467+
1468+
if (!tsc_force_recalibrate)
1469+
return 0;
14251470
}
14261471

14271472
schedule_delayed_work(&tsc_irqwork, 0);

0 commit comments

Comments
 (0)