[patch V3 10/11] timekeeping: Provide update for auxiliary timekeepers

Thomas Gleixner posted 11 patches 3 months, 2 weeks ago
[patch V3 10/11] timekeeping: Provide update for auxiliary timekeepers
Posted by Thomas Gleixner 3 months, 2 weeks ago
Update the auxiliary timekeepers periodically. For now this is tied to the system
timekeeper update from the tick. This might be revisited and moved out of the tick.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/time/timekeeping.c |   18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
---

--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -131,9 +131,11 @@ static struct tk_fast tk_fast_raw  ____c
 #ifdef CONFIG_POSIX_AUX_CLOCKS
 static __init void tk_aux_setup(void);
 static void tk_aux_update_clocksource(void);
+static void tk_aux_advance(void);
 #else
 static inline void tk_aux_setup(void) { }
 static inline void tk_aux_update_clocksource(void) { }
+static inline void tk_aux_advance(void) { }
 #endif
 
 unsigned long timekeeper_lock_irqsave(void)
@@ -2312,11 +2314,13 @@ static bool timekeeping_advance(enum tim
 /**
  * update_wall_time - Uses the current clocksource to increment the wall time
  *
+ * It also updates the enabled auxiliary clock timekeepers
  */
 void update_wall_time(void)
 {
 	if (timekeeping_advance(TK_ADV_TICK))
 		clock_was_set_delayed();
+	tk_aux_advance();
 }
 
 /**
@@ -2762,6 +2766,20 @@ static void tk_aux_update_clocksource(vo
 	}
 }
 
+static void tk_aux_advance(void)
+{
+	unsigned long active = READ_ONCE(aux_timekeepers);
+	unsigned int id;
+
+	for_each_set_bit(id, &active, BITS_PER_LONG) {
+		struct tk_data *tkd = &timekeeper_data[id + TIMEKEEPER_AUX_FIRST];
+
+		guard(raw_spinlock)(&tkd->lock);
+		if (tkd->shadow_timekeeper.clock_valid)
+			__timekeeping_advance(tkd, TK_ADV_TICK);
+	}
+}
+
 /**
  * ktime_get_aux - Get time for a AUX clock
  * @id:	ID of the clock to read (CLOCK_AUX...)
Re: [patch V3 10/11] timekeeping: Provide update for auxiliary timekeepers
Posted by John Stultz 3 months, 1 week ago
On Wed, Jun 25, 2025 at 11:38 AM Thomas Gleixner <tglx@linutronix.de> wrote:
>
> Update the auxiliary timekeepers periodically. For now this is tied to the system
> timekeeper update from the tick. This might be revisited and moved out of the tick.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
>  kernel/time/timekeeping.c |   18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> ---
>
> --- a/kernel/time/timekeeping.c
> +++ b/kernel/time/timekeeping.c
> @@ -2762,6 +2766,20 @@ static void tk_aux_update_clocksource(vo
>         }
>  }
>
> +static void tk_aux_advance(void)
> +{
> +       unsigned long active = READ_ONCE(aux_timekeepers);
> +       unsigned int id;
> +
> +       for_each_set_bit(id, &active, BITS_PER_LONG) {
> +               struct tk_data *tkd = &timekeeper_data[id + TIMEKEEPER_AUX_FIRST];

Again, a nit, but I'd use aux_tkd or something just to be super clear
we're using aux ones here.

> +
> +               guard(raw_spinlock)(&tkd->lock);
> +               if (tkd->shadow_timekeeper.clock_valid)
> +                       __timekeeping_advance(tkd, TK_ADV_TICK);
> +       }
> +}

Otherwise,
Acked-by: John Stultz <jstultz@google.com>
[tip: timers/ptp] timekeeping: Provide update for auxiliary timekeepers
Posted by tip-bot2 for Thomas Gleixner 3 months, 1 week ago
The following commit has been merged into the timers/ptp branch of tip:

Commit-ID:     e6d4c00719a6b1dda3fb358b4c973595f9dfd455
Gitweb:        https://git.kernel.org/tip/e6d4c00719a6b1dda3fb358b4c973595f9dfd455
Author:        Thomas Gleixner <tglx@linutronix.de>
AuthorDate:    Wed, 25 Jun 2025 20:38:47 +02:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 27 Jun 2025 20:13:13 +02:00

timekeeping: Provide update for auxiliary timekeepers

Update the auxiliary timekeepers periodically. For now this is tied to the system
timekeeper update from the tick. This might be revisited and moved out of the tick.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: John Stultz <jstultz@google.com>
Link: https://lore.kernel.org/all/20250625183758.382451331@linutronix.de

---
 kernel/time/timekeeping.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 523670e..568ba1f 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -131,9 +131,11 @@ static struct tk_fast tk_fast_raw  ____cacheline_aligned = {
 #ifdef CONFIG_POSIX_AUX_CLOCKS
 static __init void tk_aux_setup(void);
 static void tk_aux_update_clocksource(void);
+static void tk_aux_advance(void);
 #else
 static inline void tk_aux_setup(void) { }
 static inline void tk_aux_update_clocksource(void) { }
+static inline void tk_aux_advance(void) { }
 #endif
 
 unsigned long timekeeper_lock_irqsave(void)
@@ -2317,11 +2319,13 @@ static bool timekeeping_advance(enum timekeeping_adv_mode mode)
 /**
  * update_wall_time - Uses the current clocksource to increment the wall time
  *
+ * It also updates the enabled auxiliary clock timekeepers
  */
 void update_wall_time(void)
 {
 	if (timekeeping_advance(TK_ADV_TICK))
 		clock_was_set_delayed();
+	tk_aux_advance();
 }
 
 /**
@@ -2764,6 +2768,21 @@ static void tk_aux_update_clocksource(void)
 	}
 }
 
+static void tk_aux_advance(void)
+{
+	unsigned long active = READ_ONCE(aux_timekeepers);
+	unsigned int id;
+
+	/* Lockless quick check to avoid extra cache lines */
+	for_each_set_bit(id, &active, BITS_PER_LONG) {
+		struct tk_data *aux_tkd = &timekeeper_data[id + TIMEKEEPER_AUX_FIRST];
+
+		guard(raw_spinlock)(&aux_tkd->lock);
+		if (aux_tkd->shadow_timekeeper.clock_valid)
+			__timekeeping_advance(aux_tkd, TK_ADV_TICK);
+	}
+}
+
 /**
  * ktime_get_aux - Get time for a AUX clock
  * @id:	ID of the clock to read (CLOCK_AUX...)