diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-31 18:49:06 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-31 18:49:06 -0500 |
| commit | dc799d0179baa7f62d2e73a8217a273ca82adbdf (patch) | |
| tree | bb8fbed12bf25334d85ce7e247f3ffce86527535 | |
| parent | 7ab85d4a85160ea2ffc96b1255443cbc83be180f (diff) | |
| parent | 1ca8ec532fc2d986f1f4a319857bb18e0c9739b4 (diff) | |
Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer fixes from Thomas Gleixner:
"The timer departement delivers:
- a regression fix for the NTP code along with a proper selftest
- prevent a spurious timer interrupt in the NOHZ lowres code
- a fix for user space interfaces returning the remaining time on
architectures with CONFIG_TIME_LOW_RES=y
- a few patches to fix COMPILE_TEST fallout"
* 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
tick/nohz: Set the correct expiry when switching to nohz/lowres mode
clocksource: Fix dependencies for archs w/o HAS_IOMEM
clocksource: Select CLKSRC_MMIO where needed
tick/sched: Hide unused oneshot timer code
kselftests: timers: Add adjtimex SETOFFSET validity tests
ntp: Fix ADJ_SETOFFSET being used w/ ADJ_NANO
itimers: Handle relative timers with CONFIG_TIME_LOW_RES proper
posix-timers: Handle relative timers with CONFIG_TIME_LOW_RES proper
timerfd: Handle relative timers with CONFIG_TIME_LOW_RES proper
hrtimer: Handle remaining time proper for TIME_LOW_RES
clockevents/tcb_clksrc: Prevent disabling an already disabled clock
| -rw-r--r-- | drivers/clocksource/Kconfig | 12 | ||||
| -rw-r--r-- | drivers/clocksource/tcb_clksrc.c | 3 | ||||
| -rw-r--r-- | fs/timerfd.c | 2 | ||||
| -rw-r--r-- | include/linux/hrtimer.h | 34 | ||||
| -rw-r--r-- | kernel/time/hrtimer.c | 55 | ||||
| -rw-r--r-- | kernel/time/itimer.c | 2 | ||||
| -rw-r--r-- | kernel/time/ntp.c | 14 | ||||
| -rw-r--r-- | kernel/time/posix-timers.c | 2 | ||||
| -rw-r--r-- | kernel/time/tick-sched.c | 16 | ||||
| -rw-r--r-- | kernel/time/timer_list.c | 2 | ||||
| -rw-r--r-- | tools/testing/selftests/timers/valid-adjtimex.c | 139 |
11 files changed, 245 insertions, 36 deletions
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 56777f04d2d9..33db7406c0e2 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig | |||
| @@ -30,6 +30,8 @@ config CLKSRC_MMIO | |||
| 30 | config DIGICOLOR_TIMER | 30 | config DIGICOLOR_TIMER |
| 31 | bool "Digicolor timer driver" if COMPILE_TEST | 31 | bool "Digicolor timer driver" if COMPILE_TEST |
| 32 | depends on GENERIC_CLOCKEVENTS | 32 | depends on GENERIC_CLOCKEVENTS |
| 33 | select CLKSRC_MMIO | ||
| 34 | depends on HAS_IOMEM | ||
| 33 | help | 35 | help |
| 34 | Enables the support for the digicolor timer driver. | 36 | Enables the support for the digicolor timer driver. |
| 35 | 37 | ||
| @@ -55,6 +57,7 @@ config ARMADA_370_XP_TIMER | |||
| 55 | bool "Armada 370 and XP timer driver" if COMPILE_TEST | 57 | bool "Armada 370 and XP timer driver" if COMPILE_TEST |
| 56 | depends on ARM | 58 | depends on ARM |
| 57 | select CLKSRC_OF | 59 | select CLKSRC_OF |
| 60 | select CLKSRC_MMIO | ||
| 58 | help | 61 | help |
| 59 | Enables the support for the Armada 370 and XP timer driver. | 62 | Enables the support for the Armada 370 and XP timer driver. |
| 60 | 63 | ||
| @@ -76,6 +79,7 @@ config ORION_TIMER | |||
| 76 | config SUN4I_TIMER | 79 | config SUN4I_TIMER |
| 77 | bool "Sun4i timer driver" if COMPILE_TEST | 80 | bool "Sun4i timer driver" if COMPILE_TEST |
| 78 | depends on GENERIC_CLOCKEVENTS | 81 | depends on GENERIC_CLOCKEVENTS |
| 82 | depends on HAS_IOMEM | ||
| 79 | select CLKSRC_MMIO | 83 | select CLKSRC_MMIO |
| 80 | help | 84 | help |
| 81 | Enables support for the Sun4i timer. | 85 | Enables support for the Sun4i timer. |
| @@ -89,6 +93,7 @@ config SUN5I_HSTIMER | |||
| 89 | 93 | ||
| 90 | config TEGRA_TIMER | 94 | config TEGRA_TIMER |
| 91 | bool "Tegra timer driver" if COMPILE_TEST | 95 | bool "Tegra timer driver" if COMPILE_TEST |
| 96 | select CLKSRC_MMIO | ||
| 92 | depends on ARM | 97 | depends on ARM |
| 93 | help | 98 | help |
| 94 | Enables support for the Tegra driver. | 99 | Enables support for the Tegra driver. |
| @@ -96,6 +101,7 @@ config TEGRA_TIMER | |||
| 96 | config VT8500_TIMER | 101 | config VT8500_TIMER |
| 97 | bool "VT8500 timer driver" if COMPILE_TEST | 102 | bool "VT8500 timer driver" if COMPILE_TEST |
| 98 | depends on GENERIC_CLOCKEVENTS | 103 | depends on GENERIC_CLOCKEVENTS |
| 104 | depends on HAS_IOMEM | ||
| 99 | help | 105 | help |
| 100 | Enables support for the VT8500 driver. | 106 | Enables support for the VT8500 driver. |
| 101 | 107 | ||
| @@ -131,6 +137,7 @@ config CLKSRC_NOMADIK_MTU_SCHED_CLOCK | |||
| 131 | config CLKSRC_DBX500_PRCMU | 137 | config CLKSRC_DBX500_PRCMU |
| 132 | bool "Clocksource PRCMU Timer" if COMPILE_TEST | 138 | bool "Clocksource PRCMU Timer" if COMPILE_TEST |
| 133 | depends on GENERIC_CLOCKEVENTS | 139 | depends on GENERIC_CLOCKEVENTS |
| 140 | depends on HAS_IOMEM | ||
| 134 | help | 141 | help |
| 135 | Use the always on PRCMU Timer as clocksource | 142 | Use the always on PRCMU Timer as clocksource |
| 136 | 143 | ||
| @@ -248,6 +255,7 @@ config CLKSRC_EXYNOS_MCT | |||
| 248 | config CLKSRC_SAMSUNG_PWM | 255 | config CLKSRC_SAMSUNG_PWM |
| 249 | bool "PWM timer drvier for Samsung S3C, S5P" if COMPILE_TEST | 256 | bool "PWM timer drvier for Samsung S3C, S5P" if COMPILE_TEST |
| 250 | depends on GENERIC_CLOCKEVENTS | 257 | depends on GENERIC_CLOCKEVENTS |
| 258 | depends on HAS_IOMEM | ||
| 251 | help | 259 | help |
| 252 | This is a new clocksource driver for the PWM timer found in | 260 | This is a new clocksource driver for the PWM timer found in |
| 253 | Samsung S3C, S5P and Exynos SoCs, replacing an earlier driver | 261 | Samsung S3C, S5P and Exynos SoCs, replacing an earlier driver |
| @@ -257,12 +265,14 @@ config CLKSRC_SAMSUNG_PWM | |||
| 257 | config FSL_FTM_TIMER | 265 | config FSL_FTM_TIMER |
| 258 | bool "Freescale FlexTimer Module driver" if COMPILE_TEST | 266 | bool "Freescale FlexTimer Module driver" if COMPILE_TEST |
| 259 | depends on GENERIC_CLOCKEVENTS | 267 | depends on GENERIC_CLOCKEVENTS |
| 268 | depends on HAS_IOMEM | ||
| 260 | select CLKSRC_MMIO | 269 | select CLKSRC_MMIO |
| 261 | help | 270 | help |
| 262 | Support for Freescale FlexTimer Module (FTM) timer. | 271 | Support for Freescale FlexTimer Module (FTM) timer. |
| 263 | 272 | ||
| 264 | config VF_PIT_TIMER | 273 | config VF_PIT_TIMER |
| 265 | bool | 274 | bool |
| 275 | select CLKSRC_MMIO | ||
| 266 | help | 276 | help |
| 267 | Support for Period Interrupt Timer on Freescale Vybrid Family SoCs. | 277 | Support for Period Interrupt Timer on Freescale Vybrid Family SoCs. |
| 268 | 278 | ||
| @@ -360,6 +370,7 @@ config CLKSRC_TANGO_XTAL | |||
| 360 | config CLKSRC_PXA | 370 | config CLKSRC_PXA |
| 361 | bool "Clocksource for PXA or SA-11x0 platform" if COMPILE_TEST | 371 | bool "Clocksource for PXA or SA-11x0 platform" if COMPILE_TEST |
| 362 | depends on GENERIC_CLOCKEVENTS | 372 | depends on GENERIC_CLOCKEVENTS |
| 373 | depends on HAS_IOMEM | ||
| 363 | select CLKSRC_MMIO | 374 | select CLKSRC_MMIO |
| 364 | help | 375 | help |
| 365 | This enables OST0 support available on PXA and SA-11x0 | 376 | This enables OST0 support available on PXA and SA-11x0 |
| @@ -394,6 +405,7 @@ config CLKSRC_ST_LPC | |||
| 394 | bool "Low power clocksource found in the LPC" if COMPILE_TEST | 405 | bool "Low power clocksource found in the LPC" if COMPILE_TEST |
| 395 | select CLKSRC_OF if OF | 406 | select CLKSRC_OF if OF |
| 396 | depends on HAS_IOMEM | 407 | depends on HAS_IOMEM |
| 408 | select CLKSRC_MMIO | ||
| 397 | help | 409 | help |
| 398 | Enable this option to use the Low Power controller timer | 410 | Enable this option to use the Low Power controller timer |
| 399 | as clocksource. | 411 | as clocksource. |
diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c index 6ee91401918e..4da2af9694a2 100644 --- a/drivers/clocksource/tcb_clksrc.c +++ b/drivers/clocksource/tcb_clksrc.c | |||
| @@ -98,7 +98,8 @@ static int tc_shutdown(struct clock_event_device *d) | |||
| 98 | 98 | ||
| 99 | __raw_writel(0xff, regs + ATMEL_TC_REG(2, IDR)); | 99 | __raw_writel(0xff, regs + ATMEL_TC_REG(2, IDR)); |
| 100 | __raw_writel(ATMEL_TC_CLKDIS, regs + ATMEL_TC_REG(2, CCR)); | 100 | __raw_writel(ATMEL_TC_CLKDIS, regs + ATMEL_TC_REG(2, CCR)); |
| 101 | clk_disable(tcd->clk); | 101 | if (!clockevent_state_detached(d)) |
| 102 | clk_disable(tcd->clk); | ||
| 102 | 103 | ||
| 103 | return 0; | 104 | return 0; |
| 104 | } | 105 | } |
diff --git a/fs/timerfd.c b/fs/timerfd.c index b94fa6c3c6eb..053818dd6c18 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c | |||
| @@ -153,7 +153,7 @@ static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx) | |||
| 153 | if (isalarm(ctx)) | 153 | if (isalarm(ctx)) |
| 154 | remaining = alarm_expires_remaining(&ctx->t.alarm); | 154 | remaining = alarm_expires_remaining(&ctx->t.alarm); |
| 155 | else | 155 | else |
| 156 | remaining = hrtimer_expires_remaining(&ctx->t.tmr); | 156 | remaining = hrtimer_expires_remaining_adjusted(&ctx->t.tmr); |
| 157 | 157 | ||
| 158 | return remaining.tv64 < 0 ? ktime_set(0, 0): remaining; | 158 | return remaining.tv64 < 0 ? ktime_set(0, 0): remaining; |
| 159 | } | 159 | } |
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 76dd4f0da5ca..2ead22dd74a0 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h | |||
| @@ -87,7 +87,8 @@ enum hrtimer_restart { | |||
| 87 | * @function: timer expiry callback function | 87 | * @function: timer expiry callback function |
| 88 | * @base: pointer to the timer base (per cpu and per clock) | 88 | * @base: pointer to the timer base (per cpu and per clock) |
| 89 | * @state: state information (See bit values above) | 89 | * @state: state information (See bit values above) |
| 90 | * @start_pid: timer statistics field to store the pid of the task which | 90 | * @is_rel: Set if the timer was armed relative |
| 91 | * @start_pid: timer statistics field to store the pid of the task which | ||
| 91 | * started the timer | 92 | * started the timer |
| 92 | * @start_site: timer statistics field to store the site where the timer | 93 | * @start_site: timer statistics field to store the site where the timer |
| 93 | * was started | 94 | * was started |
| @@ -101,7 +102,8 @@ struct hrtimer { | |||
| 101 | ktime_t _softexpires; | 102 | ktime_t _softexpires; |
| 102 | enum hrtimer_restart (*function)(struct hrtimer *); | 103 | enum hrtimer_restart (*function)(struct hrtimer *); |
| 103 | struct hrtimer_clock_base *base; | 104 | struct hrtimer_clock_base *base; |
| 104 | unsigned long state; | 105 | u8 state; |
| 106 | u8 is_rel; | ||
| 105 | #ifdef CONFIG_TIMER_STATS | 107 | #ifdef CONFIG_TIMER_STATS |
| 106 | int start_pid; | 108 | int start_pid; |
| 107 | void *start_site; | 109 | void *start_site; |
| @@ -321,6 +323,27 @@ static inline void clock_was_set_delayed(void) { } | |||
| 321 | 323 | ||
| 322 | #endif | 324 | #endif |
| 323 | 325 | ||
| 326 | static inline ktime_t | ||
| 327 | __hrtimer_expires_remaining_adjusted(const struct hrtimer *timer, ktime_t now) | ||
| 328 | { | ||
| 329 | ktime_t rem = ktime_sub(timer->node.expires, now); | ||
| 330 | |||
| 331 | /* | ||
| 332 | * Adjust relative timers for the extra we added in | ||
| 333 | * hrtimer_start_range_ns() to prevent short timeouts. | ||
| 334 | */ | ||
| 335 | if (IS_ENABLED(CONFIG_TIME_LOW_RES) && timer->is_rel) | ||
| 336 | rem.tv64 -= hrtimer_resolution; | ||
| 337 | return rem; | ||
| 338 | } | ||
| 339 | |||
| 340 | static inline ktime_t | ||
| 341 | hrtimer_expires_remaining_adjusted(const struct hrtimer *timer) | ||
| 342 | { | ||
| 343 | return __hrtimer_expires_remaining_adjusted(timer, | ||
| 344 | timer->base->get_time()); | ||
| 345 | } | ||
| 346 | |||
| 324 | extern void clock_was_set(void); | 347 | extern void clock_was_set(void); |
| 325 | #ifdef CONFIG_TIMERFD | 348 | #ifdef CONFIG_TIMERFD |
| 326 | extern void timerfd_clock_was_set(void); | 349 | extern void timerfd_clock_was_set(void); |
| @@ -390,7 +413,12 @@ static inline void hrtimer_restart(struct hrtimer *timer) | |||
| 390 | } | 413 | } |
| 391 | 414 | ||
| 392 | /* Query timers: */ | 415 | /* Query timers: */ |
| 393 | extern ktime_t hrtimer_get_remaining(const struct hrtimer *timer); | 416 | extern ktime_t __hrtimer_get_remaining(const struct hrtimer *timer, bool adjust); |
| 417 | |||
| 418 | static inline ktime_t hrtimer_get_remaining(const struct hrtimer *timer) | ||
| 419 | { | ||
| 420 | return __hrtimer_get_remaining(timer, false); | ||
| 421 | } | ||
| 394 | 422 | ||
| 395 | extern u64 hrtimer_get_next_event(void); | 423 | extern u64 hrtimer_get_next_event(void); |
| 396 | 424 | ||
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 435b8850dd80..fa909f9fd559 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c | |||
| @@ -897,10 +897,10 @@ static int enqueue_hrtimer(struct hrtimer *timer, | |||
| 897 | */ | 897 | */ |
| 898 | static void __remove_hrtimer(struct hrtimer *timer, | 898 | static void __remove_hrtimer(struct hrtimer *timer, |
| 899 | struct hrtimer_clock_base *base, | 899 | struct hrtimer_clock_base *base, |
| 900 | unsigned long newstate, int reprogram) | 900 | u8 newstate, int reprogram) |
| 901 | { | 901 | { |
| 902 | struct hrtimer_cpu_base *cpu_base = base->cpu_base; | 902 | struct hrtimer_cpu_base *cpu_base = base->cpu_base; |
| 903 | unsigned int state = timer->state; | 903 | u8 state = timer->state; |
| 904 | 904 | ||
| 905 | timer->state = newstate; | 905 | timer->state = newstate; |
| 906 | if (!(state & HRTIMER_STATE_ENQUEUED)) | 906 | if (!(state & HRTIMER_STATE_ENQUEUED)) |
| @@ -930,7 +930,7 @@ static inline int | |||
| 930 | remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base, bool restart) | 930 | remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base, bool restart) |
| 931 | { | 931 | { |
| 932 | if (hrtimer_is_queued(timer)) { | 932 | if (hrtimer_is_queued(timer)) { |
| 933 | unsigned long state = timer->state; | 933 | u8 state = timer->state; |
| 934 | int reprogram; | 934 | int reprogram; |
| 935 | 935 | ||
| 936 | /* | 936 | /* |
| @@ -954,6 +954,22 @@ remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base, bool rest | |||
| 954 | return 0; | 954 | return 0; |
| 955 | } | 955 | } |
| 956 | 956 | ||
| 957 | static inline ktime_t hrtimer_update_lowres(struct hrtimer *timer, ktime_t tim, | ||
| 958 | const enum hrtimer_mode mode) | ||
| 959 | { | ||
| 960 | #ifdef CONFIG_TIME_LOW_RES | ||
| 961 | /* | ||
| 962 | * CONFIG_TIME_LOW_RES indicates that the system has no way to return | ||
| 963 | * granular time values. For relative timers we add hrtimer_resolution | ||
| 964 | * (i.e. one jiffie) to prevent short timeouts. | ||
| 965 | */ | ||
| 966 | timer->is_rel = mode & HRTIMER_MODE_REL; | ||
| 967 | if (timer->is_rel) | ||
| 968 | tim = ktime_add_safe(tim, ktime_set(0, hrtimer_resolution)); | ||
| 969 | #endif | ||
| 970 | return tim; | ||
| 971 | } | ||
| 972 | |||
| 957 | /** | 973 | /** |
| 958 | * hrtimer_start_range_ns - (re)start an hrtimer on the current CPU | 974 | * hrtimer_start_range_ns - (re)start an hrtimer on the current CPU |
| 959 | * @timer: the timer to be added | 975 | * @timer: the timer to be added |
| @@ -974,19 +990,10 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, | |||
| 974 | /* Remove an active timer from the queue: */ | 990 | /* Remove an active timer from the queue: */ |
| 975 | remove_hrtimer(timer, base, true); | 991 | remove_hrtimer(timer, base, true); |
| 976 | 992 | ||
| 977 | if (mode & HRTIMER_MODE_REL) { | 993 | if (mode & HRTIMER_MODE_REL) |
| 978 | tim = ktime_add_safe(tim, base->get_time()); | 994 | tim = ktime_add_safe(tim, base->get_time()); |
| 979 | /* | 995 | |
| 980 | * CONFIG_TIME_LOW_RES is a temporary way for architectures | 996 | tim = hrtimer_update_lowres(timer, tim, mode); |
| 981 | * to signal that they simply return xtime in | ||
| 982 | * do_gettimeoffset(). In this case we want to round up by | ||
| 983 | * resolution when starting a relative timer, to avoid short | ||
| 984 | * timeouts. This will go away with the GTOD framework. | ||
| 985 | */ | ||
| 986 | #ifdef CONFIG_TIME_LOW_RES | ||
| 987 | tim = ktime_add_safe(tim, ktime_set(0, hrtimer_resolution)); | ||
| 988 | #endif | ||
| 989 | } | ||
| 990 | 997 | ||
| 991 | hrtimer_set_expires_range_ns(timer, tim, delta_ns); | 998 | hrtimer_set_expires_range_ns(timer, tim, delta_ns); |
| 992 | 999 | ||
| @@ -1074,19 +1081,23 @@ EXPORT_SYMBOL_GPL(hrtimer_cancel); | |||
| 1074 | /** | 1081 | /** |
| 1075 | * hrtimer_get_remaining - get remaining time for the timer | 1082 | * hrtimer_get_remaining - get remaining time for the timer |
| 1076 | * @timer: the timer to read | 1083 | * @timer: the timer to read |
| 1084 | * @adjust: adjust relative timers when CONFIG_TIME_LOW_RES=y | ||
| 1077 | */ | 1085 | */ |
| 1078 | ktime_t hrtimer_get_remaining(const struct hrtimer *timer) | 1086 | ktime_t __hrtimer_get_remaining(const struct hrtimer *timer, bool adjust) |
| 1079 | { | 1087 | { |
| 1080 | unsigned long flags; | 1088 | unsigned long flags; |
| 1081 | ktime_t rem; | 1089 | ktime_t rem; |
| 1082 | 1090 | ||
| 1083 | lock_hrtimer_base(timer, &flags); | 1091 | lock_hrtimer_base(timer, &flags); |
| 1084 | rem = hrtimer_expires_remaining(timer); | 1092 | if (IS_ENABLED(CONFIG_TIME_LOW_RES) && adjust) |
| 1093 | rem = hrtimer_expires_remaining_adjusted(timer); | ||
| 1094 | else | ||
| 1095 | rem = hrtimer_expires_remaining(timer); | ||
| 1085 | unlock_hrtimer_base(timer, &flags); | 1096 | unlock_hrtimer_base(timer, &flags); |
| 1086 | 1097 | ||
| 1087 | return rem; | 1098 | return rem; |
| 1088 | } | 1099 | } |
| 1089 | EXPORT_SYMBOL_GPL(hrtimer_get_remaining); | 1100 | EXPORT_SYMBOL_GPL(__hrtimer_get_remaining); |
| 1090 | 1101 | ||
| 1091 | #ifdef CONFIG_NO_HZ_COMMON | 1102 | #ifdef CONFIG_NO_HZ_COMMON |
| 1092 | /** | 1103 | /** |
| @@ -1220,6 +1231,14 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base, | |||
| 1220 | fn = timer->function; | 1231 | fn = timer->function; |
| 1221 | 1232 | ||
| 1222 | /* | 1233 | /* |
| 1234 | * Clear the 'is relative' flag for the TIME_LOW_RES case. If the | ||
| 1235 | * timer is restarted with a period then it becomes an absolute | ||
| 1236 | * timer. If its not restarted it does not matter. | ||
| 1237 | */ | ||
| 1238 | if (IS_ENABLED(CONFIG_TIME_LOW_RES)) | ||
| 1239 | timer->is_rel = false; | ||
| 1240 | |||
| 1241 | /* | ||
| 1223 | * Because we run timers from hardirq context, there is no chance | 1242 | * Because we run timers from hardirq context, there is no chance |
| 1224 | * they get migrated to another cpu, therefore its safe to unlock | 1243 | * they get migrated to another cpu, therefore its safe to unlock |
| 1225 | * the timer base. | 1244 | * the timer base. |
diff --git a/kernel/time/itimer.c b/kernel/time/itimer.c index 8d262b467573..1d5c7204ddc9 100644 --- a/kernel/time/itimer.c +++ b/kernel/time/itimer.c | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | */ | 26 | */ |
| 27 | static struct timeval itimer_get_remtime(struct hrtimer *timer) | 27 | static struct timeval itimer_get_remtime(struct hrtimer *timer) |
| 28 | { | 28 | { |
| 29 | ktime_t rem = hrtimer_get_remaining(timer); | 29 | ktime_t rem = __hrtimer_get_remaining(timer, true); |
| 30 | 30 | ||
| 31 | /* | 31 | /* |
| 32 | * Racy but safe: if the itimer expires after the above | 32 | * Racy but safe: if the itimer expires after the above |
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 36f2ca09aa5e..6df8927c58a5 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
| @@ -685,8 +685,18 @@ int ntp_validate_timex(struct timex *txc) | |||
| 685 | if (!capable(CAP_SYS_TIME)) | 685 | if (!capable(CAP_SYS_TIME)) |
| 686 | return -EPERM; | 686 | return -EPERM; |
| 687 | 687 | ||
| 688 | if (!timeval_inject_offset_valid(&txc->time)) | 688 | if (txc->modes & ADJ_NANO) { |
| 689 | return -EINVAL; | 689 | struct timespec ts; |
| 690 | |||
| 691 | ts.tv_sec = txc->time.tv_sec; | ||
| 692 | ts.tv_nsec = txc->time.tv_usec; | ||
| 693 | if (!timespec_inject_offset_valid(&ts)) | ||
| 694 | return -EINVAL; | ||
| 695 | |||
| 696 | } else { | ||
| 697 | if (!timeval_inject_offset_valid(&txc->time)) | ||
| 698 | return -EINVAL; | ||
| 699 | } | ||
| 690 | } | 700 | } |
| 691 | 701 | ||
| 692 | /* | 702 | /* |
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 31d11ac9fa47..f2826c35e918 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c | |||
| @@ -760,7 +760,7 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) | |||
| 760 | (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) | 760 | (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) |
| 761 | timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv); | 761 | timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv); |
| 762 | 762 | ||
| 763 | remaining = ktime_sub(hrtimer_get_expires(timer), now); | 763 | remaining = __hrtimer_expires_remaining_adjusted(timer, now); |
| 764 | /* Return 0 only, when the timer is expired and not pending */ | 764 | /* Return 0 only, when the timer is expired and not pending */ |
| 765 | if (remaining.tv64 <= 0) { | 765 | if (remaining.tv64 <= 0) { |
| 766 | /* | 766 | /* |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 9d7a053545f5..0b17424349eb 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
| @@ -36,16 +36,17 @@ | |||
| 36 | */ | 36 | */ |
| 37 | static DEFINE_PER_CPU(struct tick_sched, tick_cpu_sched); | 37 | static DEFINE_PER_CPU(struct tick_sched, tick_cpu_sched); |
| 38 | 38 | ||
| 39 | /* | ||
| 40 | * The time, when the last jiffy update happened. Protected by jiffies_lock. | ||
| 41 | */ | ||
| 42 | static ktime_t last_jiffies_update; | ||
| 43 | |||
| 44 | struct tick_sched *tick_get_tick_sched(int cpu) | 39 | struct tick_sched *tick_get_tick_sched(int cpu) |
| 45 | { | 40 | { |
| 46 | return &per_cpu(tick_cpu_sched, cpu); | 41 | return &per_cpu(tick_cpu_sched, cpu); |
| 47 | } | 42 | } |
| 48 | 43 | ||
| 44 | #if defined(CONFIG_NO_HZ_COMMON) || defined(CONFIG_HIGH_RES_TIMERS) | ||
| 45 | /* | ||
| 46 | * The time, when the last jiffy update happened. Protected by jiffies_lock. | ||
| 47 | */ | ||
| 48 | static ktime_t last_jiffies_update; | ||
| 49 | |||
| 49 | /* | 50 | /* |
| 50 | * Must be called with interrupts disabled ! | 51 | * Must be called with interrupts disabled ! |
| 51 | */ | 52 | */ |
| @@ -151,6 +152,7 @@ static void tick_sched_handle(struct tick_sched *ts, struct pt_regs *regs) | |||
| 151 | update_process_times(user_mode(regs)); | 152 | update_process_times(user_mode(regs)); |
| 152 | profile_tick(CPU_PROFILING); | 153 | profile_tick(CPU_PROFILING); |
| 153 | } | 154 | } |
| 155 | #endif | ||
| 154 | 156 | ||
| 155 | #ifdef CONFIG_NO_HZ_FULL | 157 | #ifdef CONFIG_NO_HZ_FULL |
| 156 | cpumask_var_t tick_nohz_full_mask; | 158 | cpumask_var_t tick_nohz_full_mask; |
| @@ -993,9 +995,9 @@ static void tick_nohz_switch_to_nohz(void) | |||
| 993 | /* Get the next period */ | 995 | /* Get the next period */ |
| 994 | next = tick_init_jiffy_update(); | 996 | next = tick_init_jiffy_update(); |
| 995 | 997 | ||
| 996 | hrtimer_forward_now(&ts->sched_timer, tick_period); | ||
| 997 | hrtimer_set_expires(&ts->sched_timer, next); | 998 | hrtimer_set_expires(&ts->sched_timer, next); |
| 998 | tick_program_event(next, 1); | 999 | hrtimer_forward_now(&ts->sched_timer, tick_period); |
| 1000 | tick_program_event(hrtimer_get_expires(&ts->sched_timer), 1); | ||
| 999 | tick_nohz_activate(ts, NOHZ_MODE_LOWRES); | 1001 | tick_nohz_activate(ts, NOHZ_MODE_LOWRES); |
| 1000 | } | 1002 | } |
| 1001 | 1003 | ||
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c index f75e35b60149..ba7d8b288bb3 100644 --- a/kernel/time/timer_list.c +++ b/kernel/time/timer_list.c | |||
| @@ -69,7 +69,7 @@ print_timer(struct seq_file *m, struct hrtimer *taddr, struct hrtimer *timer, | |||
| 69 | print_name_offset(m, taddr); | 69 | print_name_offset(m, taddr); |
| 70 | SEQ_printf(m, ", "); | 70 | SEQ_printf(m, ", "); |
| 71 | print_name_offset(m, timer->function); | 71 | print_name_offset(m, timer->function); |
| 72 | SEQ_printf(m, ", S:%02lx", timer->state); | 72 | SEQ_printf(m, ", S:%02x", timer->state); |
| 73 | #ifdef CONFIG_TIMER_STATS | 73 | #ifdef CONFIG_TIMER_STATS |
| 74 | SEQ_printf(m, ", "); | 74 | SEQ_printf(m, ", "); |
| 75 | print_name_offset(m, timer->start_site); | 75 | print_name_offset(m, timer->start_site); |
diff --git a/tools/testing/selftests/timers/valid-adjtimex.c b/tools/testing/selftests/timers/valid-adjtimex.c index e86d937cc22c..60fe3c569bd9 100644 --- a/tools/testing/selftests/timers/valid-adjtimex.c +++ b/tools/testing/selftests/timers/valid-adjtimex.c | |||
| @@ -45,7 +45,17 @@ static inline int ksft_exit_fail(void) | |||
| 45 | } | 45 | } |
| 46 | #endif | 46 | #endif |
| 47 | 47 | ||
| 48 | #define NSEC_PER_SEC 1000000000L | 48 | #define NSEC_PER_SEC 1000000000LL |
| 49 | #define USEC_PER_SEC 1000000LL | ||
| 50 | |||
| 51 | #define ADJ_SETOFFSET 0x0100 | ||
| 52 | |||
| 53 | #include <sys/syscall.h> | ||
| 54 | static int clock_adjtime(clockid_t id, struct timex *tx) | ||
| 55 | { | ||
| 56 | return syscall(__NR_clock_adjtime, id, tx); | ||
| 57 | } | ||
| 58 | |||
| 49 | 59 | ||
| 50 | /* clear NTP time_status & time_state */ | 60 | /* clear NTP time_status & time_state */ |
| 51 | int clear_time_state(void) | 61 | int clear_time_state(void) |
| @@ -193,10 +203,137 @@ out: | |||
| 193 | } | 203 | } |
| 194 | 204 | ||
| 195 | 205 | ||
| 206 | int set_offset(long long offset, int use_nano) | ||
| 207 | { | ||
| 208 | struct timex tmx = {}; | ||
| 209 | int ret; | ||
| 210 | |||
| 211 | tmx.modes = ADJ_SETOFFSET; | ||
| 212 | if (use_nano) { | ||
| 213 | tmx.modes |= ADJ_NANO; | ||
| 214 | |||
| 215 | tmx.time.tv_sec = offset / NSEC_PER_SEC; | ||
| 216 | tmx.time.tv_usec = offset % NSEC_PER_SEC; | ||
| 217 | |||
| 218 | if (offset < 0 && tmx.time.tv_usec) { | ||
| 219 | tmx.time.tv_sec -= 1; | ||
| 220 | tmx.time.tv_usec += NSEC_PER_SEC; | ||
| 221 | } | ||
| 222 | } else { | ||
| 223 | tmx.time.tv_sec = offset / USEC_PER_SEC; | ||
| 224 | tmx.time.tv_usec = offset % USEC_PER_SEC; | ||
| 225 | |||
| 226 | if (offset < 0 && tmx.time.tv_usec) { | ||
| 227 | tmx.time.tv_sec -= 1; | ||
| 228 | tmx.time.tv_usec += USEC_PER_SEC; | ||
| 229 | } | ||
| 230 | } | ||
| 231 | |||
| 232 | ret = clock_adjtime(CLOCK_REALTIME, &tmx); | ||
| 233 | if (ret < 0) { | ||
| 234 | printf("(sec: %ld usec: %ld) ", tmx.time.tv_sec, tmx.time.tv_usec); | ||
| 235 | printf("[FAIL]\n"); | ||
| 236 | return -1; | ||
| 237 | } | ||
| 238 | return 0; | ||
| 239 | } | ||
| 240 | |||
| 241 | int set_bad_offset(long sec, long usec, int use_nano) | ||
| 242 | { | ||
| 243 | struct timex tmx = {}; | ||
| 244 | int ret; | ||
| 245 | |||
| 246 | tmx.modes = ADJ_SETOFFSET; | ||
| 247 | if (use_nano) | ||
| 248 | tmx.modes |= ADJ_NANO; | ||
| 249 | |||
| 250 | tmx.time.tv_sec = sec; | ||
| 251 | tmx.time.tv_usec = usec; | ||
| 252 | ret = clock_adjtime(CLOCK_REALTIME, &tmx); | ||
| 253 | if (ret >= 0) { | ||
| 254 | printf("Invalid (sec: %ld usec: %ld) did not fail! ", tmx.time.tv_sec, tmx.time.tv_usec); | ||
| 255 | printf("[FAIL]\n"); | ||
| 256 | return -1; | ||
| 257 | } | ||
| 258 | return 0; | ||
| 259 | } | ||
| 260 | |||
| 261 | int validate_set_offset(void) | ||
| 262 | { | ||
| 263 | printf("Testing ADJ_SETOFFSET... "); | ||
| 264 | |||
| 265 | /* Test valid values */ | ||
| 266 | if (set_offset(NSEC_PER_SEC - 1, 1)) | ||
| 267 | return -1; | ||
| 268 | |||
| 269 | if (set_offset(-NSEC_PER_SEC + 1, 1)) | ||
| 270 | return -1; | ||
| 271 | |||
| 272 | if (set_offset(-NSEC_PER_SEC - 1, 1)) | ||
| 273 | return -1; | ||
| 274 | |||
| 275 | if (set_offset(5 * NSEC_PER_SEC, 1)) | ||
| 276 | return -1; | ||
| 277 | |||
| 278 | if (set_offset(-5 * NSEC_PER_SEC, 1)) | ||
| 279 | return -1; | ||
| 280 | |||
| 281 | if (set_offset(5 * NSEC_PER_SEC + NSEC_PER_SEC / 2, 1)) | ||
| 282 | return -1; | ||
| 283 | |||
| 284 | if (set_offset(-5 * NSEC_PER_SEC - NSEC_PER_SEC / 2, 1)) | ||
| 285 | return -1; | ||
| 286 | |||
| 287 | if (set_offset(USEC_PER_SEC - 1, 0)) | ||
| 288 | return -1; | ||
| 289 | |||
| 290 | if (set_offset(-USEC_PER_SEC + 1, 0)) | ||
| 291 | return -1; | ||
| 292 | |||
| 293 | if (set_offset(-USEC_PER_SEC - 1, 0)) | ||
| 294 | return -1; | ||
| 295 | |||
| 296 | if (set_offset(5 * USEC_PER_SEC, 0)) | ||
| 297 | return -1; | ||
| 298 | |||
| 299 | if (set_offset(-5 * USEC_PER_SEC, 0)) | ||
| 300 | return -1; | ||
| 301 | |||
| 302 | if (set_offset(5 * USEC_PER_SEC + USEC_PER_SEC / 2, 0)) | ||
| 303 | return -1; | ||
| 304 | |||
| 305 | if (set_offset(-5 * USEC_PER_SEC - USEC_PER_SEC / 2, 0)) | ||
| 306 | return -1; | ||
| 307 | |||
| 308 | /* Test invalid values */ | ||
| 309 | if (set_bad_offset(0, -1, 1)) | ||
| 310 | return -1; | ||
| 311 | if (set_bad_offset(0, -1, 0)) | ||
| 312 | return -1; | ||
| 313 | if (set_bad_offset(0, 2 * NSEC_PER_SEC, 1)) | ||
| 314 | return -1; | ||
| 315 | if (set_bad_offset(0, 2 * USEC_PER_SEC, 0)) | ||
| 316 | return -1; | ||
| 317 | if (set_bad_offset(0, NSEC_PER_SEC, 1)) | ||
| 318 | return -1; | ||
| 319 | if (set_bad_offset(0, USEC_PER_SEC, 0)) | ||
| 320 | return -1; | ||
| 321 | if (set_bad_offset(0, -NSEC_PER_SEC, 1)) | ||
| 322 | return -1; | ||
| 323 | if (set_bad_offset(0, -USEC_PER_SEC, 0)) | ||
| 324 | return -1; | ||
| 325 | |||
| 326 | printf("[OK]\n"); | ||
| 327 | return 0; | ||
| 328 | } | ||
| 329 | |||
| 196 | int main(int argc, char **argv) | 330 | int main(int argc, char **argv) |
| 197 | { | 331 | { |
| 198 | if (validate_freq()) | 332 | if (validate_freq()) |
| 199 | return ksft_exit_fail(); | 333 | return ksft_exit_fail(); |
| 200 | 334 | ||
| 335 | if (validate_set_offset()) | ||
| 336 | return ksft_exit_fail(); | ||
| 337 | |||
| 201 | return ksft_exit_pass(); | 338 | return ksft_exit_pass(); |
| 202 | } | 339 | } |
