Skip to content

Commit b1456f6

Browse files
committed
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
2 parents 6376c07 + 6c58d27 commit b1456f6

File tree

8 files changed

+46
-121
lines changed

8 files changed

+46
-121
lines changed

include/linux/jiffies.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
/* LATCH is used in the interval timer and ftape setup. */
6060
#define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */
6161

62-
extern int register_refined_jiffies(long clock_tick_rate);
62+
extern void register_refined_jiffies(long clock_tick_rate);
6363

6464
/* TICK_USEC is the time between ticks in usec assuming SHIFTED_HZ */
6565
#define TICK_USEC ((USEC_PER_SEC + HZ/2) / HZ)

include/linux/tick.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,6 @@ static inline bool tick_nohz_full_enabled(void)
195195
__ret; \
196196
})
197197

198-
static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask)
199-
{
200-
if (tick_nohz_full_enabled())
201-
cpumask_or(mask, mask, tick_nohz_full_mask);
202-
}
203-
204198
extern void tick_nohz_dep_set(enum tick_dep_bits bit);
205199
extern void tick_nohz_dep_clear(enum tick_dep_bits bit);
206200
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);
281275
#else
282276
static inline bool tick_nohz_full_enabled(void) { return false; }
283277
static inline bool tick_nohz_full_cpu(int cpu) { return false; }
284-
static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask) { }
285278

286279
static inline void tick_nohz_dep_set_cpu(int cpu, enum tick_dep_bits bit) { }
287280
static inline void tick_nohz_dep_clear_cpu(int cpu, enum tick_dep_bits bit) { }

include/linux/timer.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,10 @@ extern void timers_init(void);
172172
struct hrtimer;
173173
extern enum hrtimer_restart it_real_fn(struct hrtimer *);
174174

175-
unsigned long __round_jiffies(unsigned long j, int cpu);
176175
unsigned long __round_jiffies_relative(unsigned long j, int cpu);
177176
unsigned long round_jiffies(unsigned long j);
178177
unsigned long round_jiffies_relative(unsigned long j);
179178

180-
unsigned long __round_jiffies_up(unsigned long j, int cpu);
181179
unsigned long __round_jiffies_up_relative(unsigned long j, int cpu);
182180
unsigned long round_jiffies_up(unsigned long j);
183181
unsigned long round_jiffies_up_relative(unsigned long j);

kernel/time/alarmtimer.c

Lines changed: 33 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -70,20 +70,17 @@ static DEFINE_SPINLOCK(rtcdev_lock);
7070
*/
7171
struct rtc_device *alarmtimer_get_rtcdev(void)
7272
{
73-
unsigned long flags;
7473
struct rtc_device *ret;
7574

76-
spin_lock_irqsave(&rtcdev_lock, flags);
75+
guard(spinlock_irqsave)(&rtcdev_lock);
7776
ret = rtcdev;
78-
spin_unlock_irqrestore(&rtcdev_lock, flags);
7977

8078
return ret;
8179
}
8280
EXPORT_SYMBOL_GPL(alarmtimer_get_rtcdev);
8381

8482
static int alarmtimer_rtc_add_device(struct device *dev)
8583
{
86-
unsigned long flags;
8784
struct rtc_device *rtc = to_rtc_device(dev);
8885
struct platform_device *pdev;
8986
int ret = 0;
@@ -101,25 +98,18 @@ static int alarmtimer_rtc_add_device(struct device *dev)
10198
if (!IS_ERR(pdev))
10299
device_init_wakeup(&pdev->dev, true);
103100

104-
spin_lock_irqsave(&rtcdev_lock, flags);
105-
if (!IS_ERR(pdev) && !rtcdev) {
106-
if (!try_module_get(rtc->owner)) {
101+
scoped_guard(spinlock_irqsave, &rtcdev_lock) {
102+
if (!IS_ERR(pdev) && !rtcdev && try_module_get(rtc->owner)) {
103+
rtcdev = rtc;
104+
/* hold a reference so it doesn't go away */
105+
get_device(dev);
106+
pdev = NULL;
107+
} else {
107108
ret = -1;
108-
goto unlock;
109109
}
110-
111-
rtcdev = rtc;
112-
/* hold a reference so it doesn't go away */
113-
get_device(dev);
114-
pdev = NULL;
115-
} else {
116-
ret = -1;
117110
}
118-
unlock:
119-
spin_unlock_irqrestore(&rtcdev_lock, flags);
120111

121112
platform_device_unregister(pdev);
122-
123113
return ret;
124114
}
125115

@@ -198,7 +188,7 @@ static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer)
198188
struct alarm *alarm = container_of(timer, struct alarm, timer);
199189
struct alarm_base *base = &alarm_bases[alarm->type];
200190

201-
scoped_guard (spinlock_irqsave, &base->lock)
191+
scoped_guard(spinlock_irqsave, &base->lock)
202192
alarmtimer_dequeue(base, alarm);
203193

204194
if (alarm->function)
@@ -228,17 +218,16 @@ EXPORT_SYMBOL_GPL(alarm_expires_remaining);
228218
static int alarmtimer_suspend(struct device *dev)
229219
{
230220
ktime_t min, now, expires;
231-
int i, ret, type;
232221
struct rtc_device *rtc;
233-
unsigned long flags;
234222
struct rtc_time tm;
223+
int i, ret, type;
235224

236-
spin_lock_irqsave(&freezer_delta_lock, flags);
237-
min = freezer_delta;
238-
expires = freezer_expires;
239-
type = freezer_alarmtype;
240-
freezer_delta = 0;
241-
spin_unlock_irqrestore(&freezer_delta_lock, flags);
225+
scoped_guard(spinlock_irqsave, &freezer_delta_lock) {
226+
min = freezer_delta;
227+
expires = freezer_expires;
228+
type = freezer_alarmtype;
229+
freezer_delta = 0;
230+
}
242231

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

254-
spin_lock_irqsave(&base->lock, flags);
255-
next = timerqueue_getnext(&base->timerqueue);
256-
spin_unlock_irqrestore(&base->lock, flags);
243+
scoped_guard(spinlock_irqsave, &base->lock)
244+
next = timerqueue_getnext(&base->timerqueue);
257245
if (!next)
258246
continue;
259247
delta = ktime_sub(next->expires, base->get_ktime());
@@ -352,13 +340,12 @@ EXPORT_SYMBOL_GPL(alarm_init);
352340
void alarm_start(struct alarm *alarm, ktime_t start)
353341
{
354342
struct alarm_base *base = &alarm_bases[alarm->type];
355-
unsigned long flags;
356343

357-
spin_lock_irqsave(&base->lock, flags);
358-
alarm->node.expires = start;
359-
alarmtimer_enqueue(base, alarm);
360-
hrtimer_start(&alarm->timer, alarm->node.expires, HRTIMER_MODE_ABS);
361-
spin_unlock_irqrestore(&base->lock, flags);
344+
scoped_guard(spinlock_irqsave, &base->lock) {
345+
alarm->node.expires = start;
346+
alarmtimer_enqueue(base, alarm);
347+
hrtimer_start(&alarm->timer, alarm->node.expires, HRTIMER_MODE_ABS);
348+
}
362349

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

386-
spin_lock_irqsave(&base->lock, flags);
372+
guard(spinlock_irqsave)(&base->lock);
387373
hrtimer_set_expires(&alarm->timer, alarm->node.expires);
388374
hrtimer_restart(&alarm->timer);
389375
alarmtimer_enqueue(base, alarm);
390-
spin_unlock_irqrestore(&base->lock, flags);
391376
}
392377
EXPORT_SYMBOL_GPL(alarm_restart);
393378

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

407-
spin_lock_irqsave(&base->lock, flags);
408-
ret = hrtimer_try_to_cancel(&alarm->timer);
409-
if (ret >= 0)
410-
alarmtimer_dequeue(base, alarm);
411-
spin_unlock_irqrestore(&base->lock, flags);
391+
scoped_guard(spinlock_irqsave, &base->lock) {
392+
ret = hrtimer_try_to_cancel(&alarm->timer);
393+
if (ret >= 0)
394+
alarmtimer_dequeue(base, alarm);
395+
}
412396

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

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

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

501-
spin_lock_irqsave(&freezer_delta_lock, flags);
484+
guard(spinlock_irqsave)(&freezer_delta_lock);
502485
if (!freezer_delta || (delta < freezer_delta)) {
503486
freezer_delta = delta;
504487
freezer_expires = absexp;
505488
freezer_alarmtype = type;
506489
}
507-
spin_unlock_irqrestore(&freezer_delta_lock, flags);
508490
}
509491

510492
/**
@@ -515,9 +497,9 @@ static enum alarmtimer_type clock2alarm(clockid_t clockid)
515497
{
516498
if (clockid == CLOCK_REALTIME_ALARM)
517499
return ALARM_REALTIME;
518-
if (clockid == CLOCK_BOOTTIME_ALARM)
519-
return ALARM_BOOTTIME;
520-
return -1;
500+
501+
WARN_ON_ONCE(clockid != CLOCK_BOOTTIME_ALARM);
502+
return ALARM_BOOTTIME;
521503
}
522504

523505
/**

kernel/time/clocksource.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ static void clocksource_verify_choose_cpus(void)
310310
{
311311
int cpu, i, n = verify_n_cpus;
312312

313-
if (n < 0) {
313+
if (n < 0 || n >= num_online_cpus()) {
314314
/* Check all of the CPUs. */
315315
cpumask_copy(&cpus_chosen, cpu_online_mask);
316316
cpumask_clear_cpu(smp_processor_id(), &cpus_chosen);

kernel/time/jiffies.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,11 @@ struct clocksource * __init __weak clocksource_default_clock(void)
7575

7676
static struct clocksource refined_jiffies;
7777

78-
int register_refined_jiffies(long cycles_per_second)
78+
void __init register_refined_jiffies(long cycles_per_second)
7979
{
8080
u64 nsec_per_tick, shift_hz;
8181
long cycles_per_tick;
8282

83-
84-
8583
refined_jiffies = clocksource_jiffies;
8684
refined_jiffies.name = "refined-jiffies";
8785
refined_jiffies.rating++;
@@ -100,5 +98,4 @@ int register_refined_jiffies(long cycles_per_second)
10098
refined_jiffies.mult = ((u32)nsec_per_tick) << JIFFIES_SHIFT;
10199

102100
__clocksource_register(&refined_jiffies);
103-
return 0;
104101
}

kernel/time/posix-timers.c

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030
#include "timekeeping.h"
3131
#include "posix-timers.h"
3232

33-
static struct kmem_cache *posix_timers_cache;
34-
3533
/*
3634
* Timers are managed in a hash table for lockless lookup. The hash key is
3735
* constructed from current::signal and the timer ID and the timer is
@@ -49,10 +47,12 @@ struct timer_hash_bucket {
4947
static struct {
5048
struct timer_hash_bucket *buckets;
5149
unsigned long mask;
52-
} __timer_data __ro_after_init __aligned(2*sizeof(long));
50+
struct kmem_cache *cache;
51+
} __timer_data __ro_after_init __aligned(4*sizeof(long));
5352

54-
#define timer_buckets (__timer_data.buckets)
55-
#define timer_hashmask (__timer_data.mask)
53+
#define timer_buckets (__timer_data.buckets)
54+
#define timer_hashmask (__timer_data.mask)
55+
#define posix_timers_cache (__timer_data.cache)
5656

5757
static const struct k_clock * const posix_clocks[];
5858
static const struct k_clock *clockid_to_kclock(const clockid_t id);
@@ -283,14 +283,6 @@ static int posix_get_hrtimer_res(clockid_t which_clock, struct timespec64 *tp)
283283
return 0;
284284
}
285285

286-
static __init int init_posix_timers(void)
287-
{
288-
posix_timers_cache = kmem_cache_create("posix_timers_cache", sizeof(struct k_itimer),
289-
__alignof__(struct k_itimer), SLAB_ACCOUNT, NULL);
290-
return 0;
291-
}
292-
__initcall(init_posix_timers);
293-
294286
/*
295287
* The siginfo si_overrun field and the return value of timer_getoverrun(2)
296288
* are of type int. Clamp the overrun value to INT_MAX
@@ -1556,6 +1548,11 @@ static int __init posixtimer_init(void)
15561548
unsigned long i, size;
15571549
unsigned int shift;
15581550

1551+
posix_timers_cache = kmem_cache_create("posix_timers_cache",
1552+
sizeof(struct k_itimer),
1553+
__alignof__(struct k_itimer),
1554+
SLAB_ACCOUNT, NULL);
1555+
15591556
if (IS_ENABLED(CONFIG_BASE_SMALL))
15601557
size = 512;
15611558
else

kernel/time/timer.c

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -385,32 +385,6 @@ static unsigned long round_jiffies_common(unsigned long j, int cpu,
385385
return time_is_after_jiffies(j) ? j : original;
386386
}
387387

388-
/**
389-
* __round_jiffies - function to round jiffies to a full second
390-
* @j: the time in (absolute) jiffies that should be rounded
391-
* @cpu: the processor number on which the timeout will happen
392-
*
393-
* __round_jiffies() rounds an absolute time in the future (in jiffies)
394-
* up or down to (approximately) full seconds. This is useful for timers
395-
* for which the exact time they fire does not matter too much, as long as
396-
* they fire approximately every X seconds.
397-
*
398-
* By rounding these timers to whole seconds, all such timers will fire
399-
* at the same time, rather than at various times spread out. The goal
400-
* of this is to have the CPU wake up less, which saves power.
401-
*
402-
* The exact rounding is skewed for each processor to avoid all
403-
* processors firing at the exact same time, which could lead
404-
* to lock contention or spurious cache line bouncing.
405-
*
406-
* The return value is the rounded version of the @j parameter.
407-
*/
408-
unsigned long __round_jiffies(unsigned long j, int cpu)
409-
{
410-
return round_jiffies_common(j, cpu, false);
411-
}
412-
EXPORT_SYMBOL_GPL(__round_jiffies);
413-
414388
/**
415389
* __round_jiffies_relative - function to round jiffies to a full second
416390
* @j: the time in (relative) jiffies that should be rounded
@@ -482,22 +456,6 @@ unsigned long round_jiffies_relative(unsigned long j)
482456
}
483457
EXPORT_SYMBOL_GPL(round_jiffies_relative);
484458

485-
/**
486-
* __round_jiffies_up - function to round jiffies up to a full second
487-
* @j: the time in (absolute) jiffies that should be rounded
488-
* @cpu: the processor number on which the timeout will happen
489-
*
490-
* This is the same as __round_jiffies() except that it will never
491-
* round down. This is useful for timeouts for which the exact time
492-
* of firing does not matter too much, as long as they don't fire too
493-
* early.
494-
*/
495-
unsigned long __round_jiffies_up(unsigned long j, int cpu)
496-
{
497-
return round_jiffies_common(j, cpu, true);
498-
}
499-
EXPORT_SYMBOL_GPL(__round_jiffies_up);
500-
501459
/**
502460
* __round_jiffies_up_relative - function to round jiffies up to a full second
503461
* @j: the time in (relative) jiffies that should be rounded

0 commit comments

Comments
 (0)