From nobody Fri Dec 19 21:52:13 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BE8471B21B5 for ; Tue, 21 Jan 2025 12:32:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737462754; cv=none; b=nZbJa+/CnT4wSLcbIjx4eBhMv/3A4BrD55tM8oKqwVJVRz0OFWiKORgdRVhzrSRguQ7JUgwZFa+MdUzevvfZerpJnfx852wjB43X7wQwIVEokFf46FErkQ6rsxlJynnZMxaEYLf6QspIq3FodEmM/1N8GIIzVTiWATrvXaJzhFA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737462754; c=relaxed/simple; bh=MJDnCOEMTKbsC+N8HZ+62y3ER6R0Ri5LwhFgZdygnpE=; h=From:To:Cc:Subject:References:Message-ID:Content-Type: MIME-Version:Date; b=LNh79kB4mmCnyCvfcNYNvcniNJ6HkFjB+6RnPqn+lN19tHSfW5LVLF56mQCLB6nyhl+ae1YsIc1CDlbCvsjsv3+Ib5/k/kNF9Atpb5EyNRSZD44W5niHietmUVdmeFNAhM9I6umsN6/h8BshDLpM89n6MboNjO47FDikrsZ7Mqk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Y6Xt3M7c; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=j/6Fs2GL; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Y6Xt3M7c"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="j/6Fs2GL" From: Thomas Gleixner DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1737462749; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: references:references; bh=G/stl9vyU5yrr24ROmhX+YwvzDLDwnKOV1xoCQ+0Ze4=; b=Y6Xt3M7c/zhDuAtDypiH7EZHdvxVtKGwjLWrlK5PlHKJkw/zm698jDy2/GqhPGu5wRFSYr AChio325VlARW1a/zbhnm9vh4SvdHJ0SEddMuTkMZ4AaOAOMe8/cbkg/8hITsuRtoQ/BDy SsBbAHbdoyYT9z3X5bGH/B5p5IiCEPHuR0tqLg7Ixfqb0pZRB/SXT0E3zHlLAwzAqdLKlT NPO2BadfjMzhQwL/zh2/vMWUKNHYqihmrr8vOWrkXhQhE1kC9+U/kPYMNCZb6V15V7Nnb2 IwcKdcZuZ+ruXQT2ugUQScuN16YAxfwp5gsWP7/Jfqy76GJJpVwy2B8S083snw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1737462749; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: references:references; bh=G/stl9vyU5yrr24ROmhX+YwvzDLDwnKOV1xoCQ+0Ze4=; b=j/6Fs2GLSfF8UzFtCtGoULT8kvQhKTK4uQBe7erjzpGOiYNZgo7r92e9xtq70yRos0ItTt hsVXEET/p/8VeqAg== To: Linus Torvalds Cc: linux-kernel@vger.kernel.org, x86@kernel.org Subject: [GIT pull] timers/core for 6.14-rc1 References: <173746273046.1271204.14447383010262377272.tglx@xen13> Message-ID: <173746273180.1271204.13997769287296636421.tglx@xen13> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Tue, 21 Jan 2025 13:32:29 +0100 (CET) Linus, please pull the latest timers/core branch from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-core-20= 25-01-21 up to: dcf6230555dc: timers/migration: Simplify top level detection on gro= up setup Updates for timers and timekeeping: - Just boring cleanups, typo and comment fixes and trivial optimizations Thanks, tglx ------------------> Dr. David Alan Gilbert (1): timekeeping: Remove unused ktime_get_fast_timestamps() Frederic Weisbecker (1): timers/migration: Simplify top level detection on group setup Haiyue Wang (1): vdso: Correct typo in PAGE_SHIFT comment Paul E. McKenney (1): clocksource/wdtest: Print time values for short udelay(1) Randy Dunlap (2): tick/broadcast: Add kernel-doc for function parameters timer/migration: Fix kernel-doc warnings for union tmigr_state Richard Clark (1): hrtimers: Update the return type of enqueue_hrtimer() Zhongqiu Han (1): timers: Optimize get_timer_[this_]cpu_base() Zhu Jun (1): posix-timers: Fix typo in __lock_timer() include/linux/timekeeping.h | 15 -------- include/vdso/page.h | 2 +- kernel/time/clocksource-wdtest.c | 3 +- kernel/time/hrtimer.c | 7 ++-- kernel/time/posix-timers.c | 2 +- kernel/time/tick-broadcast.c | 2 ++ kernel/time/timekeeping.c | 77 +++++-------------------------------= ---- kernel/time/timer.c | 16 ++++----- kernel/time/timer_migration.c | 4 +-- kernel/time/timer_migration.h | 21 +++++------ 10 files changed, 33 insertions(+), 116 deletions(-) diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h index 0e035f675efe..542773650200 100644 --- a/include/linux/timekeeping.h +++ b/include/linux/timekeeping.h @@ -263,18 +263,6 @@ extern bool timekeeping_rtc_skipresume(void); =20 extern void timekeeping_inject_sleeptime64(const struct timespec64 *delta); =20 -/** - * struct ktime_timestamps - Simultaneous mono/boot/real timestamps - * @mono: Monotonic timestamp - * @boot: Boottime timestamp - * @real: Realtime timestamp - */ -struct ktime_timestamps { - u64 mono; - u64 boot; - u64 real; -}; - /** * struct system_time_snapshot - simultaneous raw/real time capture with * counter value @@ -345,9 +333,6 @@ extern int get_device_system_crosststamp( */ extern void ktime_get_snapshot(struct system_time_snapshot *systime_snapsh= ot); =20 -/* NMI safe mono/boot/realtime timestamps */ -extern void ktime_get_fast_timestamps(struct ktime_timestamps *snap); - /* * Persistent clock related interfaces */ diff --git a/include/vdso/page.h b/include/vdso/page.h index 710ae2414e68..bc47186c07fc 100644 --- a/include/vdso/page.h +++ b/include/vdso/page.h @@ -8,7 +8,7 @@ * PAGE_SHIFT determines the page size. * * Note: This definition is required because PAGE_SHIFT is used - * in several places throuout the codebase. + * in several places throughout the codebase. */ #define PAGE_SHIFT CONFIG_PAGE_SHIFT =20 diff --git a/kernel/time/clocksource-wdtest.c b/kernel/time/clocksource-wdt= est.c index 62e73444ffe4..38dae590b29f 100644 --- a/kernel/time/clocksource-wdtest.c +++ b/kernel/time/clocksource-wdtest.c @@ -137,7 +137,8 @@ static int wdtest_func(void *arg) udelay(1); j2 =3D clocksource_wdtest_ktime.read(&clocksource_wdtest_ktime); pr_info("--- tsc-like times: %lu - %lu =3D %lu.\n", j2, j1, j2 - j1); - WARN_ON_ONCE(time_before(j2, j1 + NSEC_PER_USEC)); + WARN_ONCE(time_before(j2, j1 + NSEC_PER_USEC), + "Expected at least 1000ns, got %lu.\n", j2 - j1); =20 /* Verify tsc-like stability with various numbers of errors injected. */ max_retries =3D clocksource_get_max_watchdog_retry(); diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 80fe3749d2db..b026fd481dce 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -1067,11 +1067,10 @@ EXPORT_SYMBOL_GPL(hrtimer_forward); * The timer is inserted in expiry order. Insertion into the * red black tree is O(log(n)). Must hold the base lock. * - * Returns 1 when the new timer is the leftmost timer in the tree. + * Returns true when the new timer is the leftmost timer in the tree. */ -static int enqueue_hrtimer(struct hrtimer *timer, - struct hrtimer_clock_base *base, - enum hrtimer_mode mode) +static bool enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_clock_ba= se *base, + enum hrtimer_mode mode) { debug_activate(timer, mode); WARN_ON_ONCE(!base->cpu_base->online); diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 881a9ce96af7..1b675aee99a9 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -538,7 +538,7 @@ static struct k_itimer *__lock_timer(timer_t timer_id, = unsigned long *flags) * When the reference count reaches zero, the timer is scheduled * for RCU removal after the grace period. * - * Holding rcu_read_lock() accross the lookup ensures that + * Holding rcu_read_lock() across the lookup ensures that * the timer cannot be freed. * * The lookup validates locklessly that timr::it_signal =3D=3D diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index ed58eebb4e8f..0207868c8b4d 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c @@ -1020,6 +1020,8 @@ static inline ktime_t tick_get_next_period(void) =20 /** * tick_broadcast_setup_oneshot - setup the broadcast device + * @bc: the broadcast device + * @from_periodic: true if called from periodic mode */ static void tick_broadcast_setup_oneshot(struct clock_event_device *bc, bool from_periodic) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 3d128825d343..1e67d076f195 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -485,90 +485,29 @@ u64 notrace ktime_get_tai_fast_ns(void) } EXPORT_SYMBOL_GPL(ktime_get_tai_fast_ns); =20 -static __always_inline u64 __ktime_get_real_fast(struct tk_fast *tkf, u64 = *mono) +/** + * ktime_get_real_fast_ns: - NMI safe and fast access to clock realtime. + * + * See ktime_get_mono_fast_ns() for documentation of the time stamp orderi= ng. + */ +u64 ktime_get_real_fast_ns(void) { + struct tk_fast *tkf =3D &tk_fast_mono; struct tk_read_base *tkr; - u64 basem, baser, delta; + u64 baser, delta; unsigned int seq; =20 do { seq =3D raw_read_seqcount_latch(&tkf->seq); tkr =3D tkf->base + (seq & 0x01); - basem =3D ktime_to_ns(tkr->base); baser =3D ktime_to_ns(tkr->base_real); delta =3D timekeeping_get_ns(tkr); } while (raw_read_seqcount_latch_retry(&tkf->seq, seq)); =20 - if (mono) - *mono =3D basem + delta; return baser + delta; } - -/** - * ktime_get_real_fast_ns: - NMI safe and fast access to clock realtime. - * - * See ktime_get_mono_fast_ns() for documentation of the time stamp orderi= ng. - */ -u64 ktime_get_real_fast_ns(void) -{ - return __ktime_get_real_fast(&tk_fast_mono, NULL); -} EXPORT_SYMBOL_GPL(ktime_get_real_fast_ns); =20 -/** - * ktime_get_fast_timestamps: - NMI safe timestamps - * @snapshot: Pointer to timestamp storage - * - * Stores clock monotonic, boottime and realtime timestamps. - * - * Boot time is a racy access on 32bit systems if the sleep time injection - * happens late during resume and not in timekeeping_resume(). That could - * be avoided by expanding struct tk_read_base with boot offset for 32bit - * and adding more overhead to the update. As this is a hard to observe - * once per resume event which can be filtered with reasonable effort using - * the accurate mono/real timestamps, it's probably not worth the trouble. - * - * Aside of that it might be possible on 32 and 64 bit to observe the - * following when the sleep time injection happens late: - * - * CPU 0 CPU 1 - * timekeeping_resume() - * ktime_get_fast_timestamps() - * mono, real =3D __ktime_get_real_fast() - * inject_sleep_time() - * update boot offset - * boot =3D mono + bootoffset; - * - * That means that boot time already has the sleep time adjustment, but - * real time does not. On the next readout both are in sync again. - * - * Preventing this for 64bit is not really feasible without destroying the - * careful cache layout of the timekeeper because the sequence count and - * struct tk_read_base would then need two cache lines instead of one. - * - * Access to the time keeper clock source is disabled across the innermost - * steps of suspend/resume. The accessors still work, but the timestamps - * are frozen until time keeping is resumed which happens very early. - * - * For regular suspend/resume there is no observable difference vs. sched - * clock, but it might affect some of the nasty low level debug printks. - * - * OTOH, access to sched clock is not guaranteed across suspend/resume on - * all systems either so it depends on the hardware in use. - * - * If that turns out to be a real problem then this could be mitigated by - * using sched clock in a similar way as during early boot. But it's not as - * trivial as on early boot because it needs some careful protection - * against the clock monotonic timestamp jumping backwards on resume. - */ -void ktime_get_fast_timestamps(struct ktime_timestamps *snapshot) -{ - struct timekeeper *tk =3D &tk_core.timekeeper; - - snapshot->real =3D __ktime_get_real_fast(&tk_fast_mono, &snapshot->mono); - snapshot->boot =3D snapshot->mono + ktime_to_ns(data_race(tk->offs_boot)); -} - /** * halt_fast_timekeeper - Prevent fast timekeeper from accessing clocksour= ce. * @tk: Timekeeper to snapshot. diff --git a/kernel/time/timer.c b/kernel/time/timer.c index a5860bf6d16f..40706cb36920 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -956,33 +956,29 @@ static int detach_if_pending(struct timer_list *timer= , struct timer_base *base, static inline struct timer_base *get_timer_cpu_base(u32 tflags, u32 cpu) { int index =3D tflags & TIMER_PINNED ? BASE_LOCAL : BASE_GLOBAL; - struct timer_base *base; - - base =3D per_cpu_ptr(&timer_bases[index], cpu); =20 /* * If the timer is deferrable and NO_HZ_COMMON is set then we need * to use the deferrable base. */ if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && (tflags & TIMER_DEFERRABLE)) - base =3D per_cpu_ptr(&timer_bases[BASE_DEF], cpu); - return base; + index =3D BASE_DEF; + + return per_cpu_ptr(&timer_bases[index], cpu); } =20 static inline struct timer_base *get_timer_this_cpu_base(u32 tflags) { int index =3D tflags & TIMER_PINNED ? BASE_LOCAL : BASE_GLOBAL; - struct timer_base *base; - - base =3D this_cpu_ptr(&timer_bases[index]); =20 /* * If the timer is deferrable and NO_HZ_COMMON is set then we need * to use the deferrable base. */ if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && (tflags & TIMER_DEFERRABLE)) - base =3D this_cpu_ptr(&timer_bases[BASE_DEF]); - return base; + index =3D BASE_DEF; + + return this_cpu_ptr(&timer_bases[index]); } =20 static inline struct timer_base *get_timer_base(u32 tflags) diff --git a/kernel/time/timer_migration.c b/kernel/time/timer_migration.c index 8d57f7686bb0..61633762f6bf 100644 --- a/kernel/time/timer_migration.c +++ b/kernel/time/timer_migration.c @@ -1624,9 +1624,7 @@ static int tmigr_setup_groups(unsigned int cpu, unsig= ned int node) * be different from tmigr_hierarchy_levels, contains only a * single group. */ - if (group->parent || i =3D=3D tmigr_hierarchy_levels || - (list_empty(&tmigr_level_list[i]) && - list_is_singular(&tmigr_level_list[i - 1]))) + if (group->parent || list_is_singular(&tmigr_level_list[i - 1])) break; =20 } while (i < tmigr_hierarchy_levels); diff --git a/kernel/time/timer_migration.h b/kernel/time/timer_migration.h index 154accc7a543..ae19f70f8170 100644 --- a/kernel/time/timer_migration.h +++ b/kernel/time/timer_migration.h @@ -110,22 +110,19 @@ struct tmigr_cpu { * union tmigr_state - state of tmigr_group * @state: Combined version of the state - only used for atomic * read/cmpxchg function - * @struct: Split version of the state - only use the struct members to + * &anon struct: Split version of the state - only use the struct members = to * update information to stay independent of endianness + * @active: Contains each mask bit of the active children + * @migrator: Contains mask of the child which is migrator + * @seq: Sequence counter needs to be increased when an update + * to the tmigr_state is done. It prevents a race when + * updates in the child groups are propagated in changed + * order. Detailed information about the scenario is + * given in the documentation at the begin of + * timer_migration.c. */ union tmigr_state { u32 state; - /** - * struct - split state of tmigr_group - * @active: Contains each mask bit of the active children - * @migrator: Contains mask of the child which is migrator - * @seq: Sequence counter needs to be increased when an update - * to the tmigr_state is done. It prevents a race when - * updates in the child groups are propagated in changed - * order. Detailed information about the scenario is - * given in the documentation at the begin of - * timer_migration.c. - */ struct { u8 active; u8 migrator;