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

Merge tag 'timers-core-2025-05-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull timer core updates from Thomas Gleixner:
 "Updates for the time/timer core code:

   - Rework the initialization of the posix-timer kmem_cache and move
     the cache pointer into the timer_data structure to prevent false
     sharing

   - Switch the alarmtimer code to lock guards

   - Improve the CPU selection criteria in the per CPU validation of the
     clocksource watchdog to avoid arbitrary selections (or omissions)
     on systems with a small number of CPUs

   - The usual cleanups and improvements"

* tag 'timers-core-2025-05-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  tick/nohz: Remove unused tick_nohz_full_add_cpus_to()
  clocksource: Fix the CPUs' choice in the watchdog per CPU verification
  alarmtimer: Switch spin_{lock,unlock}_irqsave() to guards
  alarmtimer: Remove dead return value in clock2alarm()
  time/jiffies: Change register_refined_jiffies() to void __init
  timers: Remove unused __round_jiffies(_up)
  posix-timers: Initialize cache early and move pointer into __timer_data
parents 6376c077 6c58d279
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@
/* LATCH is used in the interval timer and ftape setup. */
#define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ)	/* For divider */

extern int register_refined_jiffies(long clock_tick_rate);
extern void register_refined_jiffies(long clock_tick_rate);

/* TICK_USEC is the time between ticks in usec assuming SHIFTED_HZ */
#define TICK_USEC ((USEC_PER_SEC + HZ/2) / HZ)
+0 −7
Original line number Diff line number Diff line
@@ -195,12 +195,6 @@ static inline bool tick_nohz_full_enabled(void)
	__ret;								\
})

static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask)
{
	if (tick_nohz_full_enabled())
		cpumask_or(mask, mask, tick_nohz_full_mask);
}

extern void tick_nohz_dep_set(enum tick_dep_bits bit);
extern void tick_nohz_dep_clear(enum tick_dep_bits bit);
extern void tick_nohz_dep_set_cpu(int cpu, enum tick_dep_bits bit);
@@ -281,7 +275,6 @@ extern void __init tick_nohz_full_setup(cpumask_var_t cpumask);
#else
static inline bool tick_nohz_full_enabled(void) { return false; }
static inline bool tick_nohz_full_cpu(int cpu) { return false; }
static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask) { }

static inline void tick_nohz_dep_set_cpu(int cpu, enum tick_dep_bits bit) { }
static inline void tick_nohz_dep_clear_cpu(int cpu, enum tick_dep_bits bit) { }
+0 −2
Original line number Diff line number Diff line
@@ -172,12 +172,10 @@ extern void timers_init(void);
struct hrtimer;
extern enum hrtimer_restart it_real_fn(struct hrtimer *);

unsigned long __round_jiffies(unsigned long j, int cpu);
unsigned long __round_jiffies_relative(unsigned long j, int cpu);
unsigned long round_jiffies(unsigned long j);
unsigned long round_jiffies_relative(unsigned long j);

unsigned long __round_jiffies_up(unsigned long j, int cpu);
unsigned long __round_jiffies_up_relative(unsigned long j, int cpu);
unsigned long round_jiffies_up(unsigned long j);
unsigned long round_jiffies_up_relative(unsigned long j);
+33 −51
Original line number Diff line number Diff line
@@ -70,12 +70,10 @@ static DEFINE_SPINLOCK(rtcdev_lock);
 */
struct rtc_device *alarmtimer_get_rtcdev(void)
{
	unsigned long flags;
	struct rtc_device *ret;

	spin_lock_irqsave(&rtcdev_lock, flags);
	guard(spinlock_irqsave)(&rtcdev_lock);
	ret = rtcdev;
	spin_unlock_irqrestore(&rtcdev_lock, flags);

	return ret;
}
@@ -83,7 +81,6 @@ EXPORT_SYMBOL_GPL(alarmtimer_get_rtcdev);

static int alarmtimer_rtc_add_device(struct device *dev)
{
	unsigned long flags;
	struct rtc_device *rtc = to_rtc_device(dev);
	struct platform_device *pdev;
	int ret = 0;
@@ -101,13 +98,8 @@ static int alarmtimer_rtc_add_device(struct device *dev)
	if (!IS_ERR(pdev))
		device_init_wakeup(&pdev->dev, true);

	spin_lock_irqsave(&rtcdev_lock, flags);
	if (!IS_ERR(pdev) && !rtcdev) {
		if (!try_module_get(rtc->owner)) {
			ret = -1;
			goto unlock;
		}

	scoped_guard(spinlock_irqsave, &rtcdev_lock) {
		if (!IS_ERR(pdev) && !rtcdev && try_module_get(rtc->owner)) {
			rtcdev = rtc;
			/* hold a reference so it doesn't go away */
			get_device(dev);
@@ -115,11 +107,9 @@ static int alarmtimer_rtc_add_device(struct device *dev)
		} else {
			ret = -1;
		}
unlock:
	spin_unlock_irqrestore(&rtcdev_lock, flags);
	}

	platform_device_unregister(pdev);

	return ret;
}

@@ -228,17 +218,16 @@ EXPORT_SYMBOL_GPL(alarm_expires_remaining);
static int alarmtimer_suspend(struct device *dev)
{
	ktime_t min, now, expires;
	int i, ret, type;
	struct rtc_device *rtc;
	unsigned long flags;
	struct rtc_time tm;
	int i, ret, type;

	spin_lock_irqsave(&freezer_delta_lock, flags);
	scoped_guard(spinlock_irqsave, &freezer_delta_lock) {
		min = freezer_delta;
		expires = freezer_expires;
		type = freezer_alarmtype;
		freezer_delta = 0;
	spin_unlock_irqrestore(&freezer_delta_lock, flags);
	}

	rtc = alarmtimer_get_rtcdev();
	/* If we have no rtcdev, just return */
@@ -251,9 +240,8 @@ static int alarmtimer_suspend(struct device *dev)
		struct timerqueue_node *next;
		ktime_t delta;

		spin_lock_irqsave(&base->lock, flags);
		scoped_guard(spinlock_irqsave, &base->lock)
			next = timerqueue_getnext(&base->timerqueue);
		spin_unlock_irqrestore(&base->lock, flags);
		if (!next)
			continue;
		delta = ktime_sub(next->expires, base->get_ktime());
@@ -352,13 +340,12 @@ EXPORT_SYMBOL_GPL(alarm_init);
void alarm_start(struct alarm *alarm, ktime_t start)
{
	struct alarm_base *base = &alarm_bases[alarm->type];
	unsigned long flags;

	spin_lock_irqsave(&base->lock, flags);
	scoped_guard(spinlock_irqsave, &base->lock) {
		alarm->node.expires = start;
		alarmtimer_enqueue(base, alarm);
		hrtimer_start(&alarm->timer, alarm->node.expires, HRTIMER_MODE_ABS);
	spin_unlock_irqrestore(&base->lock, flags);
	}

	trace_alarmtimer_start(alarm, base->get_ktime());
}
@@ -381,13 +368,11 @@ EXPORT_SYMBOL_GPL(alarm_start_relative);
void alarm_restart(struct alarm *alarm)
{
	struct alarm_base *base = &alarm_bases[alarm->type];
	unsigned long flags;

	spin_lock_irqsave(&base->lock, flags);
	guard(spinlock_irqsave)(&base->lock);
	hrtimer_set_expires(&alarm->timer, alarm->node.expires);
	hrtimer_restart(&alarm->timer);
	alarmtimer_enqueue(base, alarm);
	spin_unlock_irqrestore(&base->lock, flags);
}
EXPORT_SYMBOL_GPL(alarm_restart);

@@ -401,14 +386,13 @@ EXPORT_SYMBOL_GPL(alarm_restart);
int alarm_try_to_cancel(struct alarm *alarm)
{
	struct alarm_base *base = &alarm_bases[alarm->type];
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&base->lock, flags);
	scoped_guard(spinlock_irqsave, &base->lock) {
		ret = hrtimer_try_to_cancel(&alarm->timer);
		if (ret >= 0)
			alarmtimer_dequeue(base, alarm);
	spin_unlock_irqrestore(&base->lock, flags);
	}

	trace_alarmtimer_cancel(alarm, base->get_ktime());
	return ret;
@@ -479,7 +463,6 @@ EXPORT_SYMBOL_GPL(alarm_forward_now);
static void alarmtimer_freezerset(ktime_t absexp, enum alarmtimer_type type)
{
	struct alarm_base *base;
	unsigned long flags;
	ktime_t delta;

	switch(type) {
@@ -498,13 +481,12 @@ static void alarmtimer_freezerset(ktime_t absexp, enum alarmtimer_type type)

	delta = ktime_sub(absexp, base->get_ktime());

	spin_lock_irqsave(&freezer_delta_lock, flags);
	guard(spinlock_irqsave)(&freezer_delta_lock);
	if (!freezer_delta || (delta < freezer_delta)) {
		freezer_delta = delta;
		freezer_expires = absexp;
		freezer_alarmtype = type;
	}
	spin_unlock_irqrestore(&freezer_delta_lock, flags);
}

/**
@@ -515,9 +497,9 @@ static enum alarmtimer_type clock2alarm(clockid_t clockid)
{
	if (clockid == CLOCK_REALTIME_ALARM)
		return ALARM_REALTIME;
	if (clockid == CLOCK_BOOTTIME_ALARM)

	WARN_ON_ONCE(clockid != CLOCK_BOOTTIME_ALARM);
	return ALARM_BOOTTIME;
	return -1;
}

/**
+1 −1
Original line number Diff line number Diff line
@@ -310,7 +310,7 @@ static void clocksource_verify_choose_cpus(void)
{
	int cpu, i, n = verify_n_cpus;

	if (n < 0) {
	if (n < 0 || n >= num_online_cpus()) {
		/* Check all of the CPUs. */
		cpumask_copy(&cpus_chosen, cpu_online_mask);
		cpumask_clear_cpu(smp_processor_id(), &cpus_chosen);
Loading