Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+46 -121
+1 -1
include/linux/jiffies.h
··· 59 59 /* LATCH is used in the interval timer and ftape setup. */ 60 60 #define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */ 61 61 62 - extern int register_refined_jiffies(long clock_tick_rate); 62 + extern void register_refined_jiffies(long clock_tick_rate); 63 63 64 64 /* TICK_USEC is the time between ticks in usec assuming SHIFTED_HZ */ 65 65 #define TICK_USEC ((USEC_PER_SEC + HZ/2) / HZ)
-7
include/linux/tick.h
··· 195 195 __ret; \ 196 196 }) 197 197 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 - 204 198 extern void tick_nohz_dep_set(enum tick_dep_bits bit); 205 199 extern void tick_nohz_dep_clear(enum tick_dep_bits bit); 206 200 extern void tick_nohz_dep_set_cpu(int cpu, enum tick_dep_bits bit); ··· 275 281 #else 276 282 static inline bool tick_nohz_full_enabled(void) { return false; } 277 283 static inline bool tick_nohz_full_cpu(int cpu) { return false; } 278 - static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask) { } 279 284 280 285 static inline void tick_nohz_dep_set_cpu(int cpu, enum tick_dep_bits bit) { } 281 286 static inline void tick_nohz_dep_clear_cpu(int cpu, enum tick_dep_bits bit) { }
-2
include/linux/timer.h
··· 172 172 struct hrtimer; 173 173 extern enum hrtimer_restart it_real_fn(struct hrtimer *); 174 174 175 - unsigned long __round_jiffies(unsigned long j, int cpu); 176 175 unsigned long __round_jiffies_relative(unsigned long j, int cpu); 177 176 unsigned long round_jiffies(unsigned long j); 178 177 unsigned long round_jiffies_relative(unsigned long j); 179 178 180 - unsigned long __round_jiffies_up(unsigned long j, int cpu); 181 179 unsigned long __round_jiffies_up_relative(unsigned long j, int cpu); 182 180 unsigned long round_jiffies_up(unsigned long j); 183 181 unsigned long round_jiffies_up_relative(unsigned long j);
+33 -51
kernel/time/alarmtimer.c
··· 70 70 */ 71 71 struct rtc_device *alarmtimer_get_rtcdev(void) 72 72 { 73 - unsigned long flags; 74 73 struct rtc_device *ret; 75 74 76 - spin_lock_irqsave(&rtcdev_lock, flags); 75 + guard(spinlock_irqsave)(&rtcdev_lock); 77 76 ret = rtcdev; 78 - spin_unlock_irqrestore(&rtcdev_lock, flags); 79 77 80 78 return ret; 81 79 } ··· 81 83 82 84 static int alarmtimer_rtc_add_device(struct device *dev) 83 85 { 84 - unsigned long flags; 85 86 struct rtc_device *rtc = to_rtc_device(dev); 86 87 struct platform_device *pdev; 87 88 int ret = 0; ··· 98 101 if (!IS_ERR(pdev)) 99 102 device_init_wakeup(&pdev->dev, true); 100 103 101 - spin_lock_irqsave(&rtcdev_lock, flags); 102 - if (!IS_ERR(pdev) && !rtcdev) { 103 - if (!try_module_get(rtc->owner)) { 104 + scoped_guard(spinlock_irqsave, &rtcdev_lock) { 105 + if (!IS_ERR(pdev) && !rtcdev && try_module_get(rtc->owner)) { 106 + rtcdev = rtc; 107 + /* hold a reference so it doesn't go away */ 108 + get_device(dev); 109 + pdev = NULL; 110 + } else { 104 111 ret = -1; 105 - goto unlock; 106 112 } 107 - 108 - rtcdev = rtc; 109 - /* hold a reference so it doesn't go away */ 110 - get_device(dev); 111 - pdev = NULL; 112 - } else { 113 - ret = -1; 114 113 } 115 - unlock: 116 - spin_unlock_irqrestore(&rtcdev_lock, flags); 117 114 118 115 platform_device_unregister(pdev); 119 - 120 116 return ret; 121 117 } 122 118 ··· 188 198 struct alarm *alarm = container_of(timer, struct alarm, timer); 189 199 struct alarm_base *base = &alarm_bases[alarm->type]; 190 200 191 - scoped_guard (spinlock_irqsave, &base->lock) 201 + scoped_guard(spinlock_irqsave, &base->lock) 192 202 alarmtimer_dequeue(base, alarm); 193 203 194 204 if (alarm->function) ··· 218 228 static int alarmtimer_suspend(struct device *dev) 219 229 { 220 230 ktime_t min, now, expires; 221 - int i, ret, type; 222 231 struct rtc_device *rtc; 223 - unsigned long flags; 224 232 struct rtc_time tm; 233 + int i, ret, type; 225 234 226 - spin_lock_irqsave(&freezer_delta_lock, flags); 227 - min = freezer_delta; 228 - expires = freezer_expires; 229 - type = freezer_alarmtype; 230 - freezer_delta = 0; 231 - spin_unlock_irqrestore(&freezer_delta_lock, flags); 235 + scoped_guard(spinlock_irqsave, &freezer_delta_lock) { 236 + min = freezer_delta; 237 + expires = freezer_expires; 238 + type = freezer_alarmtype; 239 + freezer_delta = 0; 240 + } 232 241 233 242 rtc = alarmtimer_get_rtcdev(); 234 243 /* If we have no rtcdev, just return */ ··· 240 251 struct timerqueue_node *next; 241 252 ktime_t delta; 242 253 243 - spin_lock_irqsave(&base->lock, flags); 244 - next = timerqueue_getnext(&base->timerqueue); 245 - spin_unlock_irqrestore(&base->lock, flags); 254 + scoped_guard(spinlock_irqsave, &base->lock) 255 + next = timerqueue_getnext(&base->timerqueue); 246 256 if (!next) 247 257 continue; 248 258 delta = ktime_sub(next->expires, base->get_ktime()); ··· 340 352 void alarm_start(struct alarm *alarm, ktime_t start) 341 353 { 342 354 struct alarm_base *base = &alarm_bases[alarm->type]; 343 - unsigned long flags; 344 355 345 - spin_lock_irqsave(&base->lock, flags); 346 - alarm->node.expires = start; 347 - alarmtimer_enqueue(base, alarm); 348 - hrtimer_start(&alarm->timer, alarm->node.expires, HRTIMER_MODE_ABS); 349 - spin_unlock_irqrestore(&base->lock, flags); 356 + scoped_guard(spinlock_irqsave, &base->lock) { 357 + alarm->node.expires = start; 358 + alarmtimer_enqueue(base, alarm); 359 + hrtimer_start(&alarm->timer, alarm->node.expires, HRTIMER_MODE_ABS); 360 + } 350 361 351 362 trace_alarmtimer_start(alarm, base->get_ktime()); 352 363 } ··· 368 381 void alarm_restart(struct alarm *alarm) 369 382 { 370 383 struct alarm_base *base = &alarm_bases[alarm->type]; 371 - unsigned long flags; 372 384 373 - spin_lock_irqsave(&base->lock, flags); 385 + guard(spinlock_irqsave)(&base->lock); 374 386 hrtimer_set_expires(&alarm->timer, alarm->node.expires); 375 387 hrtimer_restart(&alarm->timer); 376 388 alarmtimer_enqueue(base, alarm); 377 - spin_unlock_irqrestore(&base->lock, flags); 378 389 } 379 390 EXPORT_SYMBOL_GPL(alarm_restart); 380 391 ··· 386 401 int alarm_try_to_cancel(struct alarm *alarm) 387 402 { 388 403 struct alarm_base *base = &alarm_bases[alarm->type]; 389 - unsigned long flags; 390 404 int ret; 391 405 392 - spin_lock_irqsave(&base->lock, flags); 393 - ret = hrtimer_try_to_cancel(&alarm->timer); 394 - if (ret >= 0) 395 - alarmtimer_dequeue(base, alarm); 396 - spin_unlock_irqrestore(&base->lock, flags); 406 + scoped_guard(spinlock_irqsave, &base->lock) { 407 + ret = hrtimer_try_to_cancel(&alarm->timer); 408 + if (ret >= 0) 409 + alarmtimer_dequeue(base, alarm); 410 + } 397 411 398 412 trace_alarmtimer_cancel(alarm, base->get_ktime()); 399 413 return ret; ··· 463 479 static void alarmtimer_freezerset(ktime_t absexp, enum alarmtimer_type type) 464 480 { 465 481 struct alarm_base *base; 466 - unsigned long flags; 467 482 ktime_t delta; 468 483 469 484 switch(type) { ··· 481 498 482 499 delta = ktime_sub(absexp, base->get_ktime()); 483 500 484 - spin_lock_irqsave(&freezer_delta_lock, flags); 501 + guard(spinlock_irqsave)(&freezer_delta_lock); 485 502 if (!freezer_delta || (delta < freezer_delta)) { 486 503 freezer_delta = delta; 487 504 freezer_expires = absexp; 488 505 freezer_alarmtype = type; 489 506 } 490 - spin_unlock_irqrestore(&freezer_delta_lock, flags); 491 507 } 492 508 493 509 /** ··· 497 515 { 498 516 if (clockid == CLOCK_REALTIME_ALARM) 499 517 return ALARM_REALTIME; 500 - if (clockid == CLOCK_BOOTTIME_ALARM) 501 - return ALARM_BOOTTIME; 502 - return -1; 518 + 519 + WARN_ON_ONCE(clockid != CLOCK_BOOTTIME_ALARM); 520 + return ALARM_BOOTTIME; 503 521 } 504 522 505 523 /**
+1 -1
kernel/time/clocksource.c
··· 310 310 { 311 311 int cpu, i, n = verify_n_cpus; 312 312 313 - if (n < 0) { 313 + if (n < 0 || n >= num_online_cpus()) { 314 314 /* Check all of the CPUs. */ 315 315 cpumask_copy(&cpus_chosen, cpu_online_mask); 316 316 cpumask_clear_cpu(smp_processor_id(), &cpus_chosen);
+1 -4
kernel/time/jiffies.c
··· 75 75 76 76 static struct clocksource refined_jiffies; 77 77 78 - int register_refined_jiffies(long cycles_per_second) 78 + void __init register_refined_jiffies(long cycles_per_second) 79 79 { 80 80 u64 nsec_per_tick, shift_hz; 81 81 long cycles_per_tick; 82 - 83 - 84 82 85 83 refined_jiffies = clocksource_jiffies; 86 84 refined_jiffies.name = "refined-jiffies"; ··· 98 100 refined_jiffies.mult = ((u32)nsec_per_tick) << JIFFIES_SHIFT; 99 101 100 102 __clocksource_register(&refined_jiffies); 101 - return 0; 102 103 }
+10 -13
kernel/time/posix-timers.c
··· 30 30 #include "timekeeping.h" 31 31 #include "posix-timers.h" 32 32 33 - static struct kmem_cache *posix_timers_cache; 34 - 35 33 /* 36 34 * Timers are managed in a hash table for lockless lookup. The hash key is 37 35 * constructed from current::signal and the timer ID and the timer is ··· 47 49 static struct { 48 50 struct timer_hash_bucket *buckets; 49 51 unsigned long mask; 50 - } __timer_data __ro_after_init __aligned(2*sizeof(long)); 52 + struct kmem_cache *cache; 53 + } __timer_data __ro_after_init __aligned(4*sizeof(long)); 51 54 52 - #define timer_buckets (__timer_data.buckets) 53 - #define timer_hashmask (__timer_data.mask) 55 + #define timer_buckets (__timer_data.buckets) 56 + #define timer_hashmask (__timer_data.mask) 57 + #define posix_timers_cache (__timer_data.cache) 54 58 55 59 static const struct k_clock * const posix_clocks[]; 56 60 static const struct k_clock *clockid_to_kclock(const clockid_t id); ··· 282 282 tp->tv_nsec = hrtimer_resolution; 283 283 return 0; 284 284 } 285 - 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 285 294 286 /* 295 287 * The siginfo si_overrun field and the return value of timer_getoverrun(2) ··· 1547 1555 { 1548 1556 unsigned long i, size; 1549 1557 unsigned int shift; 1558 + 1559 + posix_timers_cache = kmem_cache_create("posix_timers_cache", 1560 + sizeof(struct k_itimer), 1561 + __alignof__(struct k_itimer), 1562 + SLAB_ACCOUNT, NULL); 1550 1563 1551 1564 if (IS_ENABLED(CONFIG_BASE_SMALL)) 1552 1565 size = 512;
-42
kernel/time/timer.c
··· 386 386 } 387 387 388 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 - 414 - /** 415 389 * __round_jiffies_relative - function to round jiffies to a full second 416 390 * @j: the time in (relative) jiffies that should be rounded 417 391 * @cpu: the processor number on which the timeout will happen ··· 455 481 return __round_jiffies_relative(j, raw_smp_processor_id()); 456 482 } 457 483 EXPORT_SYMBOL_GPL(round_jiffies_relative); 458 - 459 - /** 460 - * __round_jiffies_up - function to round jiffies up to a full second 461 - * @j: the time in (absolute) jiffies that should be rounded 462 - * @cpu: the processor number on which the timeout will happen 463 - * 464 - * This is the same as __round_jiffies() except that it will never 465 - * round down. This is useful for timeouts for which the exact time 466 - * of firing does not matter too much, as long as they don't fire too 467 - * early. 468 - */ 469 - unsigned long __round_jiffies_up(unsigned long j, int cpu) 470 - { 471 - return round_jiffies_common(j, cpu, true); 472 - } 473 - EXPORT_SYMBOL_GPL(__round_jiffies_up); 474 484 475 485 /** 476 486 * __round_jiffies_up_relative - function to round jiffies up to a full second