Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dc799d01 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents 7ab85d4a 1ca8ec53
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@ config CLKSRC_MMIO
config DIGICOLOR_TIMER
	bool "Digicolor timer driver" if COMPILE_TEST
	depends on GENERIC_CLOCKEVENTS
	select CLKSRC_MMIO
	depends on HAS_IOMEM
	help
	  Enables the support for the digicolor timer driver.

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

@@ -76,6 +79,7 @@ config ORION_TIMER
config SUN4I_TIMER
	bool "Sun4i timer driver" if COMPILE_TEST
	depends on GENERIC_CLOCKEVENTS
	depends on HAS_IOMEM
	select CLKSRC_MMIO
	help
	  Enables support for the Sun4i timer.
@@ -89,6 +93,7 @@ config SUN5I_HSTIMER

config TEGRA_TIMER
	bool "Tegra timer driver" if COMPILE_TEST
	select CLKSRC_MMIO
	depends on ARM
	help
	  Enables support for the Tegra driver.
@@ -96,6 +101,7 @@ config TEGRA_TIMER
config VT8500_TIMER
	bool "VT8500 timer driver" if COMPILE_TEST
	depends on GENERIC_CLOCKEVENTS
	depends on HAS_IOMEM
	help
	  Enables support for the VT8500 driver.

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

@@ -248,6 +255,7 @@ config CLKSRC_EXYNOS_MCT
config CLKSRC_SAMSUNG_PWM
	bool "PWM timer drvier for Samsung S3C, S5P" if COMPILE_TEST
	depends on GENERIC_CLOCKEVENTS
	depends on HAS_IOMEM
	help
	  This is a new clocksource driver for the PWM timer found in
	  Samsung S3C, S5P and Exynos SoCs, replacing an earlier driver
@@ -257,12 +265,14 @@ config CLKSRC_SAMSUNG_PWM
config FSL_FTM_TIMER
	bool "Freescale FlexTimer Module driver" if COMPILE_TEST
	depends on GENERIC_CLOCKEVENTS
	depends on HAS_IOMEM
	select CLKSRC_MMIO
	help
	  Support for Freescale FlexTimer Module (FTM) timer.

config VF_PIT_TIMER
	bool
	select CLKSRC_MMIO
	help
	  Support for Period Interrupt Timer on Freescale Vybrid Family SoCs.

@@ -360,6 +370,7 @@ config CLKSRC_TANGO_XTAL
config CLKSRC_PXA
	bool "Clocksource for PXA or SA-11x0 platform" if COMPILE_TEST
	depends on GENERIC_CLOCKEVENTS
	depends on HAS_IOMEM
	select CLKSRC_MMIO
	help
	  This enables OST0 support available on PXA and SA-11x0
@@ -394,6 +405,7 @@ config CLKSRC_ST_LPC
	bool "Low power clocksource found in the LPC" if COMPILE_TEST
	select CLKSRC_OF if OF
	depends on HAS_IOMEM
	select CLKSRC_MMIO
	help
	  Enable this option to use the Low Power controller timer
	  as clocksource.
+2 −1
Original line number Diff line number Diff line
@@ -98,6 +98,7 @@ static int tc_shutdown(struct clock_event_device *d)

	__raw_writel(0xff, regs + ATMEL_TC_REG(2, IDR));
	__raw_writel(ATMEL_TC_CLKDIS, regs + ATMEL_TC_REG(2, CCR));
	if (!clockevent_state_detached(d))
		clk_disable(tcd->clk);

	return 0;
+1 −1
Original line number Diff line number Diff line
@@ -153,7 +153,7 @@ static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx)
	if (isalarm(ctx))
		remaining = alarm_expires_remaining(&ctx->t.alarm);
	else
		remaining = hrtimer_expires_remaining(&ctx->t.tmr);
		remaining = hrtimer_expires_remaining_adjusted(&ctx->t.tmr);

	return remaining.tv64 < 0 ? ktime_set(0, 0): remaining;
}
+31 −3
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ enum hrtimer_restart {
 * @function:	timer expiry callback function
 * @base:	pointer to the timer base (per cpu and per clock)
 * @state:	state information (See bit values above)
 * @is_rel:	Set if the timer was armed relative
 * @start_pid:  timer statistics field to store the pid of the task which
 *		started the timer
 * @start_site:	timer statistics field to store the site where the timer
@@ -101,7 +102,8 @@ struct hrtimer {
	ktime_t				_softexpires;
	enum hrtimer_restart		(*function)(struct hrtimer *);
	struct hrtimer_clock_base	*base;
	unsigned long			state;
	u8				state;
	u8				is_rel;
#ifdef CONFIG_TIMER_STATS
	int				start_pid;
	void				*start_site;
@@ -321,6 +323,27 @@ static inline void clock_was_set_delayed(void) { }

#endif

static inline ktime_t
__hrtimer_expires_remaining_adjusted(const struct hrtimer *timer, ktime_t now)
{
	ktime_t rem = ktime_sub(timer->node.expires, now);

	/*
	 * Adjust relative timers for the extra we added in
	 * hrtimer_start_range_ns() to prevent short timeouts.
	 */
	if (IS_ENABLED(CONFIG_TIME_LOW_RES) && timer->is_rel)
		rem.tv64 -= hrtimer_resolution;
	return rem;
}

static inline ktime_t
hrtimer_expires_remaining_adjusted(const struct hrtimer *timer)
{
	return __hrtimer_expires_remaining_adjusted(timer,
						    timer->base->get_time());
}

extern void clock_was_set(void);
#ifdef CONFIG_TIMERFD
extern void timerfd_clock_was_set(void);
@@ -390,7 +413,12 @@ static inline void hrtimer_restart(struct hrtimer *timer)
}

/* Query timers: */
extern ktime_t hrtimer_get_remaining(const struct hrtimer *timer);
extern ktime_t __hrtimer_get_remaining(const struct hrtimer *timer, bool adjust);

static inline ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
{
	return __hrtimer_get_remaining(timer, false);
}

extern u64 hrtimer_get_next_event(void);

+37 −18
Original line number Diff line number Diff line
@@ -897,10 +897,10 @@ static int enqueue_hrtimer(struct hrtimer *timer,
 */
static void __remove_hrtimer(struct hrtimer *timer,
			     struct hrtimer_clock_base *base,
			     unsigned long newstate, int reprogram)
			     u8 newstate, int reprogram)
{
	struct hrtimer_cpu_base *cpu_base = base->cpu_base;
	unsigned int state = timer->state;
	u8 state = timer->state;

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

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

static inline ktime_t hrtimer_update_lowres(struct hrtimer *timer, ktime_t tim,
					    const enum hrtimer_mode mode)
{
#ifdef CONFIG_TIME_LOW_RES
	/*
	 * CONFIG_TIME_LOW_RES indicates that the system has no way to return
	 * granular time values. For relative timers we add hrtimer_resolution
	 * (i.e. one jiffie) to prevent short timeouts.
	 */
	timer->is_rel = mode & HRTIMER_MODE_REL;
	if (timer->is_rel)
		tim = ktime_add_safe(tim, ktime_set(0, hrtimer_resolution));
#endif
	return tim;
}

/**
 * hrtimer_start_range_ns - (re)start an hrtimer on the current CPU
 * @timer:	the timer to be added
@@ -974,19 +990,10 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
	/* Remove an active timer from the queue: */
	remove_hrtimer(timer, base, true);

	if (mode & HRTIMER_MODE_REL) {
	if (mode & HRTIMER_MODE_REL)
		tim = ktime_add_safe(tim, base->get_time());
		/*
		 * CONFIG_TIME_LOW_RES is a temporary way for architectures
		 * to signal that they simply return xtime in
		 * do_gettimeoffset(). In this case we want to round up by
		 * resolution when starting a relative timer, to avoid short
		 * timeouts. This will go away with the GTOD framework.
		 */
#ifdef CONFIG_TIME_LOW_RES
		tim = ktime_add_safe(tim, ktime_set(0, hrtimer_resolution));
#endif
	}

	tim = hrtimer_update_lowres(timer, tim, mode);

	hrtimer_set_expires_range_ns(timer, tim, delta_ns);

@@ -1074,19 +1081,23 @@ EXPORT_SYMBOL_GPL(hrtimer_cancel);
/**
 * hrtimer_get_remaining - get remaining time for the timer
 * @timer:	the timer to read
 * @adjust:	adjust relative timers when CONFIG_TIME_LOW_RES=y
 */
ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
ktime_t __hrtimer_get_remaining(const struct hrtimer *timer, bool adjust)
{
	unsigned long flags;
	ktime_t rem;

	lock_hrtimer_base(timer, &flags);
	if (IS_ENABLED(CONFIG_TIME_LOW_RES) && adjust)
		rem = hrtimer_expires_remaining_adjusted(timer);
	else
		rem = hrtimer_expires_remaining(timer);
	unlock_hrtimer_base(timer, &flags);

	return rem;
}
EXPORT_SYMBOL_GPL(hrtimer_get_remaining);
EXPORT_SYMBOL_GPL(__hrtimer_get_remaining);

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

	/*
	 * Clear the 'is relative' flag for the TIME_LOW_RES case. If the
	 * timer is restarted with a period then it becomes an absolute
	 * timer. If its not restarted it does not matter.
	 */
	if (IS_ENABLED(CONFIG_TIME_LOW_RES))
		timer->is_rel = false;

	/*
	 * Because we run timers from hardirq context, there is no chance
	 * they get migrated to another cpu, therefore its safe to unlock
Loading