Skip to content

Commit dc799d0

Browse files
committed
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
2 parents 7ab85d4 + 1ca8ec5 commit dc799d0

File tree

11 files changed

+245
-36
lines changed

11 files changed

+245
-36
lines changed

drivers/clocksource/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ config CLKSRC_MMIO
3030
config DIGICOLOR_TIMER
3131
bool "Digicolor timer driver" if COMPILE_TEST
3232
depends on GENERIC_CLOCKEVENTS
33+
select CLKSRC_MMIO
34+
depends on HAS_IOMEM
3335
help
3436
Enables the support for the digicolor timer driver.
3537

@@ -55,6 +57,7 @@ config ARMADA_370_XP_TIMER
5557
bool "Armada 370 and XP timer driver" if COMPILE_TEST
5658
depends on ARM
5759
select CLKSRC_OF
60+
select CLKSRC_MMIO
5861
help
5962
Enables the support for the Armada 370 and XP timer driver.
6063

@@ -76,6 +79,7 @@ config ORION_TIMER
7679
config SUN4I_TIMER
7780
bool "Sun4i timer driver" if COMPILE_TEST
7881
depends on GENERIC_CLOCKEVENTS
82+
depends on HAS_IOMEM
7983
select CLKSRC_MMIO
8084
help
8185
Enables support for the Sun4i timer.
@@ -89,13 +93,15 @@ config SUN5I_HSTIMER
8993

9094
config TEGRA_TIMER
9195
bool "Tegra timer driver" if COMPILE_TEST
96+
select CLKSRC_MMIO
9297
depends on ARM
9398
help
9499
Enables support for the Tegra driver.
95100

96101
config VT8500_TIMER
97102
bool "VT8500 timer driver" if COMPILE_TEST
98103
depends on GENERIC_CLOCKEVENTS
104+
depends on HAS_IOMEM
99105
help
100106
Enables support for the VT8500 driver.
101107

@@ -131,6 +137,7 @@ config CLKSRC_NOMADIK_MTU_SCHED_CLOCK
131137
config CLKSRC_DBX500_PRCMU
132138
bool "Clocksource PRCMU Timer" if COMPILE_TEST
133139
depends on GENERIC_CLOCKEVENTS
140+
depends on HAS_IOMEM
134141
help
135142
Use the always on PRCMU Timer as clocksource
136143

@@ -248,6 +255,7 @@ config CLKSRC_EXYNOS_MCT
248255
config CLKSRC_SAMSUNG_PWM
249256
bool "PWM timer drvier for Samsung S3C, S5P" if COMPILE_TEST
250257
depends on GENERIC_CLOCKEVENTS
258+
depends on HAS_IOMEM
251259
help
252260
This is a new clocksource driver for the PWM timer found in
253261
Samsung S3C, S5P and Exynos SoCs, replacing an earlier driver
@@ -257,12 +265,14 @@ config CLKSRC_SAMSUNG_PWM
257265
config FSL_FTM_TIMER
258266
bool "Freescale FlexTimer Module driver" if COMPILE_TEST
259267
depends on GENERIC_CLOCKEVENTS
268+
depends on HAS_IOMEM
260269
select CLKSRC_MMIO
261270
help
262271
Support for Freescale FlexTimer Module (FTM) timer.
263272

264273
config VF_PIT_TIMER
265274
bool
275+
select CLKSRC_MMIO
266276
help
267277
Support for Period Interrupt Timer on Freescale Vybrid Family SoCs.
268278

@@ -360,6 +370,7 @@ config CLKSRC_TANGO_XTAL
360370
config CLKSRC_PXA
361371
bool "Clocksource for PXA or SA-11x0 platform" if COMPILE_TEST
362372
depends on GENERIC_CLOCKEVENTS
373+
depends on HAS_IOMEM
363374
select CLKSRC_MMIO
364375
help
365376
This enables OST0 support available on PXA and SA-11x0
@@ -394,6 +405,7 @@ config CLKSRC_ST_LPC
394405
bool "Low power clocksource found in the LPC" if COMPILE_TEST
395406
select CLKSRC_OF if OF
396407
depends on HAS_IOMEM
408+
select CLKSRC_MMIO
397409
help
398410
Enable this option to use the Low Power controller timer
399411
as clocksource.

drivers/clocksource/tcb_clksrc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ static int tc_shutdown(struct clock_event_device *d)
9898

9999
__raw_writel(0xff, regs + ATMEL_TC_REG(2, IDR));
100100
__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);
102103

103104
return 0;
104105
}

fs/timerfd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx)
153153
if (isalarm(ctx))
154154
remaining = alarm_expires_remaining(&ctx->t.alarm);
155155
else
156-
remaining = hrtimer_expires_remaining(&ctx->t.tmr);
156+
remaining = hrtimer_expires_remaining_adjusted(&ctx->t.tmr);
157157

158158
return remaining.tv64 < 0 ? ktime_set(0, 0): remaining;
159159
}

include/linux/hrtimer.h

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ enum hrtimer_restart {
8787
* @function: timer expiry callback function
8888
* @base: pointer to the timer base (per cpu and per clock)
8989
* @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
9192
* started the timer
9293
* @start_site: timer statistics field to store the site where the timer
9394
* was started
@@ -101,7 +102,8 @@ struct hrtimer {
101102
ktime_t _softexpires;
102103
enum hrtimer_restart (*function)(struct hrtimer *);
103104
struct hrtimer_clock_base *base;
104-
unsigned long state;
105+
u8 state;
106+
u8 is_rel;
105107
#ifdef CONFIG_TIMER_STATS
106108
int start_pid;
107109
void *start_site;
@@ -321,6 +323,27 @@ static inline void clock_was_set_delayed(void) { }
321323

322324
#endif
323325

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+
324347
extern void clock_was_set(void);
325348
#ifdef CONFIG_TIMERFD
326349
extern void timerfd_clock_was_set(void);
@@ -390,7 +413,12 @@ static inline void hrtimer_restart(struct hrtimer *timer)
390413
}
391414

392415
/* 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+
}
394422

395423
extern u64 hrtimer_get_next_event(void);
396424

kernel/time/hrtimer.c

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -897,10 +897,10 @@ static int enqueue_hrtimer(struct hrtimer *timer,
897897
*/
898898
static void __remove_hrtimer(struct hrtimer *timer,
899899
struct hrtimer_clock_base *base,
900-
unsigned long newstate, int reprogram)
900+
u8 newstate, int reprogram)
901901
{
902902
struct hrtimer_cpu_base *cpu_base = base->cpu_base;
903-
unsigned int state = timer->state;
903+
u8 state = timer->state;
904904

905905
timer->state = newstate;
906906
if (!(state & HRTIMER_STATE_ENQUEUED))
@@ -930,7 +930,7 @@ static inline int
930930
remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base, bool restart)
931931
{
932932
if (hrtimer_is_queued(timer)) {
933-
unsigned long state = timer->state;
933+
u8 state = timer->state;
934934
int reprogram;
935935

936936
/*
@@ -954,6 +954,22 @@ remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base, bool rest
954954
return 0;
955955
}
956956

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+
957973
/**
958974
* hrtimer_start_range_ns - (re)start an hrtimer on the current CPU
959975
* @timer: the timer to be added
@@ -974,19 +990,10 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
974990
/* Remove an active timer from the queue: */
975991
remove_hrtimer(timer, base, true);
976992

977-
if (mode & HRTIMER_MODE_REL) {
993+
if (mode & HRTIMER_MODE_REL)
978994
tim = ktime_add_safe(tim, base->get_time());
979-
/*
980-
* CONFIG_TIME_LOW_RES is a temporary way for architectures
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-
}
995+
996+
tim = hrtimer_update_lowres(timer, tim, mode);
990997

991998
hrtimer_set_expires_range_ns(timer, tim, delta_ns);
992999

@@ -1074,19 +1081,23 @@ EXPORT_SYMBOL_GPL(hrtimer_cancel);
10741081
/**
10751082
* hrtimer_get_remaining - get remaining time for the timer
10761083
* @timer: the timer to read
1084+
* @adjust: adjust relative timers when CONFIG_TIME_LOW_RES=y
10771085
*/
1078-
ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
1086+
ktime_t __hrtimer_get_remaining(const struct hrtimer *timer, bool adjust)
10791087
{
10801088
unsigned long flags;
10811089
ktime_t rem;
10821090

10831091
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);
10851096
unlock_hrtimer_base(timer, &flags);
10861097

10871098
return rem;
10881099
}
1089-
EXPORT_SYMBOL_GPL(hrtimer_get_remaining);
1100+
EXPORT_SYMBOL_GPL(__hrtimer_get_remaining);
10901101

10911102
#ifdef CONFIG_NO_HZ_COMMON
10921103
/**
@@ -1219,6 +1230,14 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base,
12191230
timer_stats_account_hrtimer(timer);
12201231
fn = timer->function;
12211232

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+
12221241
/*
12231242
* Because we run timers from hardirq context, there is no chance
12241243
* they get migrated to another cpu, therefore its safe to unlock

kernel/time/itimer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
*/
2727
static struct timeval itimer_get_remtime(struct hrtimer *timer)
2828
{
29-
ktime_t rem = hrtimer_get_remaining(timer);
29+
ktime_t rem = __hrtimer_get_remaining(timer, true);
3030

3131
/*
3232
* Racy but safe: if the itimer expires after the above

kernel/time/ntp.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -685,8 +685,18 @@ int ntp_validate_timex(struct timex *txc)
685685
if (!capable(CAP_SYS_TIME))
686686
return -EPERM;
687687

688-
if (!timeval_inject_offset_valid(&txc->time))
689-
return -EINVAL;
688+
if (txc->modes & ADJ_NANO) {
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+
}
690700
}
691701

692702
/*

kernel/time/posix-timers.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,7 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
760760
(timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE))
761761
timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv);
762762

763-
remaining = ktime_sub(hrtimer_get_expires(timer), now);
763+
remaining = __hrtimer_expires_remaining_adjusted(timer, now);
764764
/* Return 0 only, when the timer is expired and not pending */
765765
if (remaining.tv64 <= 0) {
766766
/*

kernel/time/tick-sched.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,17 @@
3636
*/
3737
static DEFINE_PER_CPU(struct tick_sched, tick_cpu_sched);
3838

39-
/*
40-
* The time, when the last jiffy update happened. Protected by jiffies_lock.
41-
*/
42-
static ktime_t last_jiffies_update;
43-
4439
struct tick_sched *tick_get_tick_sched(int cpu)
4540
{
4641
return &per_cpu(tick_cpu_sched, cpu);
4742
}
4843

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+
4950
/*
5051
* Must be called with interrupts disabled !
5152
*/
@@ -151,6 +152,7 @@ static void tick_sched_handle(struct tick_sched *ts, struct pt_regs *regs)
151152
update_process_times(user_mode(regs));
152153
profile_tick(CPU_PROFILING);
153154
}
155+
#endif
154156

155157
#ifdef CONFIG_NO_HZ_FULL
156158
cpumask_var_t tick_nohz_full_mask;
@@ -993,9 +995,9 @@ static void tick_nohz_switch_to_nohz(void)
993995
/* Get the next period */
994996
next = tick_init_jiffy_update();
995997

996-
hrtimer_forward_now(&ts->sched_timer, tick_period);
997998
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);
9991001
tick_nohz_activate(ts, NOHZ_MODE_LOWRES);
10001002
}
10011003

kernel/time/timer_list.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ print_timer(struct seq_file *m, struct hrtimer *taddr, struct hrtimer *timer,
6969
print_name_offset(m, taddr);
7070
SEQ_printf(m, ", ");
7171
print_name_offset(m, timer->function);
72-
SEQ_printf(m, ", S:%02lx", timer->state);
72+
SEQ_printf(m, ", S:%02x", timer->state);
7373
#ifdef CONFIG_TIMER_STATS
7474
SEQ_printf(m, ", ");
7575
print_name_offset(m, timer->start_site);

0 commit comments

Comments
 (0)