summaryrefslogtreecommitdiff
path: root/kernel/time/timer.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-10-21 11:20:38 -1000
committerLinus Torvalds <torvalds@linux-foundation.org>2026-10-21 11:20:38 -1000
commitaaf3d47e530616ed0cf9110ba8c537ace455dd90 (patch)
treed1ef2d72acb7f64963c7051ad8540dccd5ee11e7 /kernel/time/timer.c
parentb4460f89a274240204038d559e8571f370d14327 (diff)
parent348f54c435bf3177baa78201952810b255d44b30 (diff)
Merge tag 'timers-core-2026-10-20' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer core updates from Thomas Gleixner: "Updates for the core timekeeping and timers subsystem: - Futher cleanups for the POSIX timer exit/exec related code to simplify the code flow and to make it more robust against future changes. - Prevent tearing of timekeeper::ktime_sec which can be accessed without the sequence count protection. The timekeeper is updated by memcpy() with an uneven sequence count to force readers into the retry path. On 64-bit machine the ktime_sec member can be accessed atomically without the sequence count protection. That is only correct when the update side memcpy() guarantees atomicity at the 64-bit granularity. That's not guaranteed due to debug options, compilers and instruction availability. If the memcpy() does not provide the atomicity then the unprotected readers can observe store tearing. To prevent this write the ktime_sec member before the memcpy() so that a non-atomic memcpy() will write the same data. A similar fix has been done for the xtime_sec member, but the ktime_sec equivalent was missed. - Prevent time64_to_tm() day truncation on 32-bit kernels The function receives a 64-bit seconds value but stores the quotient of the computation in a long, which truncates the result for large input values. Cure this by using div_s64_rem() which stores the quotient in s64 and only leaves the seconds-within-day reminder in a long, which is guaranteed to fit. This fix comes with a corresponding kunit test to prevent further mishaps. - Mark data-racy accesses to the hrtimer_sleeper::task member. The recent updates to KCSAN flagged these benign races. Annotate them with new helper functions, convert all existing usage sites and mark the task member private after that so that future users which fail to use the helpers can be detected automatically. - Address similar benign KCSAN flagged issues in the hrtimer, timer and timer migration code. - Fixes for a few selftest issues" * tag 'timers-core-2026-10-20' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (26 commits) selftests/timers: clocksource-switch: Fix unchecked open()/read() selftests: timers: Measure the CPU timers on the clock they count selftests: timers: Count what tick is worth in the drift estimate time/kunit: Add time64_to_tm() case beyond 32-bit day count time: Prevent time64_to_tm() day truncation on 32-bit timekeeping: Use READ_ONCE/WRITE_ONCE() for ktime_sec to prevent tearing timers/migration: Mark racy updates to tmigr_event::ignore field timers: Mark racy updates to hlist_node::pprev field hrtimer: Apply READ_ONCE() to lockless base->running loads hrtimer: Mark the hrtimer_sleeper structure's ->task field __private hrtimer: Update hrtimer_resolution only if value changes futex: Use accessor for hrtimer_sleeper ->task field in requeue rtmutex: Use accessor for hrtimer_sleeper ->task field net: pktgen: Use accessor for hrtimer_sleeper ->task field timers: Use accessor for hrtimer_sleeper ->task field in sleep_timeout.c futex: Use accessor for hrtimer_sleeper ->task field in waitwake.c io-uring/rw: Use accessor for hrtimer_sleeper ->task field wait: Use accessor for hrtimer_sleeper ->task field aio: Use accessor for hrtimer_sleeper ->task field hrtimer: Mark data-racy accesses to hrtimer_sleeper ->task field ...
Diffstat (limited to 'kernel/time/timer.c')
-rw-r--r--kernel/time/timer.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index ae9abf14688e..42afdcb229d8 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -890,7 +890,7 @@ static inline void detach_timer(struct timer_list *timer, bool clear_pending)
__hlist_del(entry);
if (clear_pending)
- entry->pprev = NULL;
+ WRITE_ONCE(entry->pprev, NULL);
entry->next = LIST_POISON2;
}