From nobody Wed Oct 8 17:31:54 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 7C58B2D540B; Wed, 25 Jun 2025 18:38:32 +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=1750876714; cv=none; b=LaaRh7+3nyWQKI1+yyFnuZCFfuXkHRrrGr1l4uNzMX93GvJqCdUrc6tsst2tLA8PRIor3dfAnUsHlV9tDfickhAI2LdcIBRPCthR/N3+Vvhev87M+VYUx1uW763Q+PQhgrg2O+kOyzdl7cn+DlwHByoMCM6jjE5O4uVy1Loldoo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750876714; c=relaxed/simple; bh=96e9cJKXFPDju4/QSz3RUdC00J74o8uGRyHcUOVWnN8=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=SRDg1B7NiGkA9kKgUY5CcdcP9nuHmvc/gKOcztiUUiiFqBsChD/HzjxlwsL4gj1pnrPl6gfv4GTL9Rzh9q3uRzDAWKh5QPmXiX5jFE4QmjnXKUmXo0q3EM6HR2E1RIn22/gXd/haVwpzfZOL4zXG/A9l62EZ+1ydGMpUxRQISmc= 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=fCdPmwJR; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=+Cyx31IM; 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="fCdPmwJR"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="+Cyx31IM" Message-ID: <20250625183757.803890875@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1750876710; 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: references:references; bh=SJrzO2St6DYrac8L0oTt1CLLzIVb9v9DvCiT5mXNVHY=; b=fCdPmwJRg7Ou2R4hHzMxhWnOPrZgDleYTMjSd/DcmB/d9Xu8+2O3QWSYF8QcI6OadknX3q 7FpyZWxmWLn5SymB+NVBqp3YQF68rUg+SATplPniamuvgNLTPrmza+9R5W/GMel0BnuVnq 4SVUbEJ58J/c2o9pguJCH+U7UaTnaiewkYJzW8T+1gzPdgb+77YZyRpEsp5hnipJqIuBs7 XtTzpDjH121XIy/w2Z0lSL1M/on2YuHeVAQfZ6eUiv+o1oXHbvs9ju81XO5AwssI18a+JE uMjjRlilLp0FllCUPDUUErgZvWz7gjEx4OjO4c4NMJc7ayuNbPC5bh80N/PQrQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1750876710; 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: references:references; bh=SJrzO2St6DYrac8L0oTt1CLLzIVb9v9DvCiT5mXNVHY=; b=+Cyx31IMUHC8B125ju7SNCfyAAxBtEY//FGD0F2HUgWll/CpH4QMghvxlfE0B3r5PmQ1MI ktxNhZx7bo2uejDA== From: Thomas Gleixner To: LKML Cc: netdev@vger.kernel.org, Richard Cochran , Christopher Hall , John Stultz , Frederic Weisbecker , Anna-Maria Behnsen , Miroslav Lichvar , Werner Abt , David Woodhouse , Stephen Boyd , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , Kurt Kanzenbach , Nam Cao , Antoine Tenart Subject: [patch V3 01/11] timekeeping: Update auxiliary timekeepers on clocksource change References: <20250625182951.587377878@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Wed, 25 Jun 2025 20:38:29 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Propagate a system clocksource change to the auxiliary timekeepers so that they can pick up the new clocksource. Signed-off-by: Thomas Gleixner --- kernel/time/timekeeping.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) --- --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -119,8 +119,10 @@ static struct tk_fast tk_fast_raw ____c =20 #ifdef CONFIG_POSIX_AUX_CLOCKS static __init void tk_aux_setup(void); +static void tk_aux_update_clocksource(void); #else static inline void tk_aux_setup(void) { } +static inline void tk_aux_update_clocksource(void) { } #endif =20 unsigned long timekeeper_lock_irqsave(void) @@ -1548,6 +1550,8 @@ static int change_clocksource(void *data timekeeping_update_from_shadow(&tk_core, TK_UPDATE_ALL); } =20 + tk_aux_update_clocksource(); + if (old) { if (old->disable) old->disable(old); @@ -2651,6 +2655,30 @@ EXPORT_SYMBOL(hardpps); #endif /* CONFIG_NTP_PPS */ =20 #ifdef CONFIG_POSIX_AUX_CLOCKS + +/* Bitmap for the activated auxiliary timekeepers */ +static unsigned long aux_timekeepers; + +/* Invoked from timekeeping after a clocksource change */ +static void tk_aux_update_clocksource(void) +{ + unsigned long active =3D READ_ONCE(aux_timekeepers); + unsigned int id; + + for_each_set_bit(id, &active, BITS_PER_LONG) { + struct tk_data *tkd =3D &timekeeper_data[id + TIMEKEEPER_AUX_FIRST]; + struct timekeeper *tks =3D &tkd->shadow_timekeeper; + + guard(raw_spinlock_irqsave)(&tkd->lock); + if (!tks->clock_valid) + continue; + + timekeeping_forward_now(tks); + tk_setup_internals(tks, tk_core.timekeeper.tkr_mono.clock); + timekeeping_update_from_shadow(tkd, TK_UPDATE_ALL); + } +} + static __init void tk_aux_setup(void) { for (int i =3D TIMEKEEPER_AUX_FIRST; i <=3D TIMEKEEPER_AUX_LAST; i++) From nobody Wed Oct 8 17:31:54 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 B88D42D8DBD; Wed, 25 Jun 2025 18:38:33 +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=1750876715; cv=none; b=aNBmSECL5NBMPlvZl94fjTgjmAEJOP/AtGrmmUEinGKOV3VbwftkdkwKbiHEw2QQEkqMjT9dl5ikhjgQLJi27H5ByxKOi2aj2fdMrKj7a4ID/YcxILO+E56VYxykUK/QR+AlhD0ggeEC05E0o4yVOeZ63tpaw/G/MiNpW3WpLF8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750876715; c=relaxed/simple; bh=D1P6//gGLnJK/BUkGyyzg8j12UrrtDCjbavWR9nLcig=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=F/ccX0EHyTB+RDu0gjKYrKIEXfeGnHpFblB4UCN5GfW3S/ZgLFWmmHA64gCt9Q8xhVPM0Ks1YL8szouHGki6e1AibxECUv1dQqDNYpR4bKt2G9ec3YIWlU+zlsVToG7qhfN2UcMM/add/GlO7vdUdYtT2tcqyMVZhNi5mJYx8V4= 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=Xi6jQYE/; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=e6qeYh+G; 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="Xi6jQYE/"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="e6qeYh+G" Message-ID: <20250625183757.868342628@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1750876711; 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: references:references; bh=gYeMVqE9QiE6MqwPDRadjXqz6IU75/CthgeCFNFFOMA=; b=Xi6jQYE/dZAcbkNiP5oRzWup9TqPo9WT/C488F77EnlXjQIuf1Uw9OjCJle/7TDnIQwIeA 02Ehzzji2TRrmqpYDE6DkjMp2Jap2rwvGevzDhkb83HpEGCJpo3Nd+wQgPAdqUSiILfFjX cvYaQdCMbuhnyc0zybonb7o/ZHqgnzPWKJZ1vr1TJie5qDaL2FxEa8Mee0ITGOMsmDBRjg gXYxhRf6W/SswZ0VhcNlTBK5BatXmKzt8MW7bsPeljVyxIKkD7zaf7NbVE0l19Uxcis/9f 2BdcwBTOdVfOmPPn7tiXz8vIIYlVktnnIxzZAK0blIexT5UJ6bowLZXCdSqsAw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1750876711; 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: references:references; bh=gYeMVqE9QiE6MqwPDRadjXqz6IU75/CthgeCFNFFOMA=; b=e6qeYh+GTsUclrushjwH6Kcu1pNUfzBbqY1df4VEozvyPhSfbDz35WQqz7kep6ZEPF7syp v3jDw0nygG1Bm6Cw== From: Thomas Gleixner To: LKML Cc: netdev@vger.kernel.org, Richard Cochran , Christopher Hall , John Stultz , Frederic Weisbecker , Anna-Maria Behnsen , Miroslav Lichvar , Werner Abt , David Woodhouse , Stephen Boyd , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , Kurt Kanzenbach , Nam Cao , Antoine Tenart Subject: [patch V3 02/11] timekeeping: Provide time getters for auxiliary clocks References: <20250625182951.587377878@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Wed, 25 Jun 2025 20:38:31 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Provide interfaces similar to the ktime_get*() family which provide access to the auxiliary clocks. These interfaces have a boolean return value, which indicates whether the accessed clock is valid or not. Signed-off-by: Thomas Gleixner Acked-by: John Stultz --- V3: Remove misleading TAI comment and use aux_tkd* for clarity - John --- include/linux/posix-timers.h | 5 +++ include/linux/timekeeping.h | 11 +++++++ kernel/time/timekeeping.c | 65 ++++++++++++++++++++++++++++++++++++++= +++++ 3 files changed, 81 insertions(+) --- --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -37,6 +37,11 @@ static inline int clockid_to_fd(const cl return ~(clk >> 3); } =20 +static inline bool clockid_aux_valid(clockid_t id) +{ + return IS_ENABLED(CONFIG_POSIX_AUX_CLOCKS) && id >=3D CLOCK_AUX && id <= =3D CLOCK_AUX_LAST; +} + #ifdef CONFIG_POSIX_TIMERS =20 #include --- a/include/linux/timekeeping.h +++ b/include/linux/timekeeping.h @@ -263,6 +263,17 @@ extern bool timekeeping_rtc_skipresume(v =20 extern void timekeeping_inject_sleeptime64(const struct timespec64 *delta); =20 +/* + * Auxiliary clock interfaces + */ +#ifdef CONFIG_POSIX_AUX_CLOCKS +extern bool ktime_get_aux(clockid_t id, ktime_t *kt); +extern bool ktime_get_aux_ts64(clockid_t id, struct timespec64 *kt); +#else +static inline bool ktime_get_aux(clockid_t id, ktime_t *kt) { return false= ; } +static inline bool ktime_get_aux_ts64(clockid_t id, struct timespec64 *kt)= { return false; } +#endif + /** * struct system_time_snapshot - simultaneous raw/real time capture with * counter value --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -2659,6 +2659,18 @@ EXPORT_SYMBOL(hardpps); /* Bitmap for the activated auxiliary timekeepers */ static unsigned long aux_timekeepers; =20 +static inline unsigned int clockid_to_tkid(unsigned int id) +{ + return TIMEKEEPER_AUX_FIRST + id - CLOCK_AUX; +} + +static inline struct tk_data *aux_get_tk_data(clockid_t id) +{ + if (!clockid_aux_valid(id)) + return NULL; + return &timekeeper_data[clockid_to_tkid(id)]; +} + /* Invoked from timekeeping after a clocksource change */ static void tk_aux_update_clocksource(void) { @@ -2679,6 +2691,59 @@ static void tk_aux_update_clocksource(vo } } =20 +/** + * ktime_get_aux - Get time for a AUX clock + * @id: ID of the clock to read (CLOCK_AUX...) + * @kt: Pointer to ktime_t to store the time stamp + * + * Returns: True if the timestamp is valid, false otherwise + */ +bool ktime_get_aux(clockid_t id, ktime_t *kt) +{ + struct tk_data *aux_tkd =3D aux_get_tk_data(id); + struct timekeeper *aux_tk; + unsigned int seq; + ktime_t base; + u64 nsecs; + + WARN_ON(timekeeping_suspended); + + if (!aux_tkd) + return false; + + aux_tk =3D &aux_tkd->timekeeper; + do { + seq =3D read_seqcount_begin(&aux_tkd->seq); + if (!aux_tk->clock_valid) + return false; + + base =3D ktime_add(aux_tk->tkr_mono.base, aux_tk->offs_aux); + nsecs =3D timekeeping_get_ns(&aux_tk->tkr_mono); + } while (read_seqcount_retry(&aux_tkd->seq, seq)); + + *kt =3D ktime_add_ns(base, nsecs); + return true; +} +EXPORT_SYMBOL_GPL(ktime_get_aux); + +/** + * ktime_get_aux_ts64 - Get time for a AUX clock + * @id: ID of the clock to read (CLOCK_AUX...) + * @ts: Pointer to timespec64 to store the time stamp + * + * Returns: True if the timestamp is valid, false otherwise + */ +bool ktime_get_aux_ts64(clockid_t id, struct timespec64 *ts) +{ + ktime_t now; + + if (!ktime_get_aux(id, &now)) + return false; + *ts =3D ktime_to_timespec64(now); + return true; +} +EXPORT_SYMBOL_GPL(ktime_get_aux_ts64); + static __init void tk_aux_setup(void) { for (int i =3D TIMEKEEPER_AUX_FIRST; i <=3D TIMEKEEPER_AUX_LAST; i++) From nobody Wed Oct 8 17:31:54 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 C10162DAFA0; Wed, 25 Jun 2025 18:38:34 +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=1750876716; cv=none; b=sNRRUOlMgavBUFJlh1Jf7JDFNNAfcp4dI4yEqv8ozleu94vxixF6g4cnDLGk0ubHW7uywnqDHOTgfMoSqOQvSQFUl3Msb6kwUzIg6TyJ2C5+pXAy5pqbVFFVxy5rH9rWa3/jdWspZi0jbMu7tN3Bt+nD3j0VEDAuZNWFbGksJSU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750876716; c=relaxed/simple; bh=ifhBYbyQoLoOEP0V/rScP3Lnd/vAGmiFG9RmYtS/9s0=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=JcJmNtRSiPALakepL0fcI80vuXCCQU5d4mCgxnO4no1ZCWdvcY/RlKAlG/fg9JtWmrhu0RxkBWNvvQXGngVfCOUpJVxosTGdhScZTYdaAyrci2Rp442ygoS7WN1FfSnC6npRschEE0f/3OL/B8LERdJLLVimDIlr0ai/Yzl4k8A= 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=4nbmGjiy; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=LTbbmOmu; 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="4nbmGjiy"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="LTbbmOmu" Message-ID: <20250625183757.932220594@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1750876713; 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: references:references; bh=2OZ/Wg7Ni70vaDwsYrtM9Y4qPN2qsvNLh+LjPX9FZhA=; b=4nbmGjiyWke1kyFWf0M8WDAf5Q8793rAXmt5X3p4MIRIhW5DQe+cFqfc/jScGS+anTUPfX vEr7ydwAu7OtWjewkiEbLA7sQXOt2eXuLavaDsE8Hm12usIMNlcrHLIWIQ+QqXHlnSaQkf jOdxbB/j4LnxNpvStNoCeNZ2oBhgtL8mtTJekbVBSW6+xkH+PYUiV61UfXpmpfNeixhgK1 4J6/+M4o8VrXZSP+CGb+faKnesSmGXlfbJ1VJPmxt4GkQ77cZ1PqQlHxW2sRFHLPqV7wFK 10TIqPYtr2uBup7k3cXeCSZJAdLjjh/2rzk7W7SrfHjniNrmSAE9Wj1d9SzNZQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1750876713; 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: references:references; bh=2OZ/Wg7Ni70vaDwsYrtM9Y4qPN2qsvNLh+LjPX9FZhA=; b=LTbbmOmuklm+pYexptYMrG+IDi+Bm58cMOUGXBmniz9SDTLUatQWOntLtUjm50W1NrGGRU 2kCXz3Iz0EkGjfCg== From: Thomas Gleixner To: LKML Cc: netdev@vger.kernel.org, Richard Cochran , Christopher Hall , John Stultz , Frederic Weisbecker , Anna-Maria Behnsen , Miroslav Lichvar , Werner Abt , David Woodhouse , Stephen Boyd , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , Kurt Kanzenbach , Nam Cao , Antoine Tenart Subject: [patch V3 03/11] timekeeping: Add minimal posix-timers support for auxiliary clocks References: <20250625182951.587377878@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Wed, 25 Jun 2025 20:38:32 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Provide clock_getres(2) and clock_gettime(2) for auxiliary clocks. Signed-off-by: Thomas Gleixner Acked-by: John Stultz --- kernel/time/posix-timers.c | 3 +++ kernel/time/posix-timers.h | 1 + kernel/time/timekeeping.c | 21 +++++++++++++++++++++ 3 files changed, 25 insertions(+) --- --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -1526,6 +1526,9 @@ static const struct k_clock * const posi [CLOCK_REALTIME_ALARM] =3D &alarm_clock, [CLOCK_BOOTTIME_ALARM] =3D &alarm_clock, [CLOCK_TAI] =3D &clock_tai, +#ifdef CONFIG_POSIX_AUX_CLOCKS + [CLOCK_AUX ... CLOCK_AUX_LAST] =3D &clock_aux, +#endif }; =20 static const struct k_clock *clockid_to_kclock(const clockid_t id) --- a/kernel/time/posix-timers.h +++ b/kernel/time/posix-timers.h @@ -41,6 +41,7 @@ extern const struct k_clock clock_posix_ extern const struct k_clock clock_process; extern const struct k_clock clock_thread; extern const struct k_clock alarm_clock; +extern const struct k_clock clock_aux; =20 void posix_timer_queue_signal(struct k_itimer *timr); =20 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -2655,6 +2655,7 @@ EXPORT_SYMBOL(hardpps); #endif /* CONFIG_NTP_PPS */ =20 #ifdef CONFIG_POSIX_AUX_CLOCKS +#include "posix-timers.h" =20 /* Bitmap for the activated auxiliary timekeepers */ static unsigned long aux_timekeepers; @@ -2744,6 +2745,26 @@ bool ktime_get_aux_ts64(clockid_t id, st } EXPORT_SYMBOL_GPL(ktime_get_aux_ts64); =20 +static int aux_get_res(clockid_t id, struct timespec64 *tp) +{ + if (!clockid_aux_valid(id)) + return -ENODEV; + + tp->tv_sec =3D 0; + tp->tv_nsec =3D 1; + return 0; +} + +static int aux_get_timespec(clockid_t id, struct timespec64 *tp) +{ + return ktime_get_aux_ts64(id, tp) ? 0 : -ENODEV; +} + +const struct k_clock clock_aux =3D { + .clock_getres =3D aux_get_res, + .clock_get_timespec =3D aux_get_timespec, +}; + static __init void tk_aux_setup(void) { for (int i =3D TIMEKEEPER_AUX_FIRST; i <=3D TIMEKEEPER_AUX_LAST; i++) From nobody Wed Oct 8 17:31:54 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 843B92DCC12; Wed, 25 Jun 2025 18:38:36 +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=1750876718; cv=none; b=kWL16rIflJeber8Lyy7cS+tDTATKoa+SvdrvBjxV278s/nLnHSy3nMxpkuMZy7lSsZdTo5+s/HOMkr+eaS/gTygylmmJ/KxP4tpf6KtkPMo8C8aB4Dx4qVVapcn16i+ATvNCxYlu9KHJeVPxKqhnLW6qM4pNKamtLdVfV4mlTbk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750876718; c=relaxed/simple; bh=P1gaIoRZW7JVP2+pj+bnWWNN0mZJt23YZ78CspdTUtA=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=rhv3WyOaVx/ZDBRdkT3wj2Ln/gKBHzz4y467OdUzrLQyHTMLaKVXQasw9fydhN3uHAn+ZMDWjpQkLhzA7Vm/74W+vj1b8tHD9Oe9h4TEe6efe301MtiiNjQeVSBmuMuq4IGls6ukwg7TRtRqCjSDHLcG7rTjRoBL0o2poU9Z8ow= 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=SS9nX4Oo; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=jGv6I14O; 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="SS9nX4Oo"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="jGv6I14O" Message-ID: <20250625183757.995688714@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1750876714; 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: references:references; bh=0vRDZIPNBxbAaM5DrnSkm/14tGEp0N2O3kxgSR8yJBk=; b=SS9nX4OonfLY5825F33wK4iGe8fu66uOu6Y8yMSc+nlKdtAnzf/XAu7yoHOhHVjAk5A/q7 gkpjNJnNd2GUsMpD8ZH5GyzrRH/304eLxlvL1pzRcRZKwRIQV7kcDXsdOFMq7SO1N6TZi1 QUQfgz0dyXob//s7z8GRywMKziAowASlc8l2+vY1IXCNn8C9/ClMLVDsp++CjqQBB6Cocz 31adtYou+vvP5/jBQft3PqBtqIVN3TTAXErWOga03TelyDSFJGxE5Ion7xrP4ThjR/K8S4 cYXVHvU0BK2iEhyZhALGMcIhK8bmwGSgQEO3OOrUmEEyqbLRUyVG3S4E9xMzQg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1750876714; 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: references:references; bh=0vRDZIPNBxbAaM5DrnSkm/14tGEp0N2O3kxgSR8yJBk=; b=jGv6I14OSdBlJAM8JUoespWckVAgPsR7o0BpJwVtaI2hRcCar0jbVtB4D+h8VmCY4zquPD pVpTWM8s6VOsbACg== From: Thomas Gleixner To: LKML Cc: netdev@vger.kernel.org, Richard Cochran , Christopher Hall , John Stultz , Frederic Weisbecker , Anna-Maria Behnsen , Miroslav Lichvar , Werner Abt , David Woodhouse , Stephen Boyd , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , Kurt Kanzenbach , Nam Cao , Antoine Tenart Subject: [patch V3 04/11] timekeeping: Provide time setter for auxiliary clocks References: <20250625182951.587377878@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Wed, 25 Jun 2025 20:38:34 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add clock_settime(2) support for auxiliary clocks. The function affects the AUX offset which is added to the "monotonic" clock readout of these clocks. Signed-off-by: Thomas Gleixner Acked-by: John Stultz --- kernel/time/timekeeping.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) --- --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -2757,9 +2757,48 @@ static int aux_get_timespec(clockid_t id return ktime_get_aux_ts64(id, tp) ? 0 : -ENODEV; } =20 +static int aux_clock_set(const clockid_t id, const struct timespec64 *tnew) +{ + struct tk_data *tkd =3D aux_get_tk_data(id); + struct timekeeper *tks; + ktime_t tnow, nsecs; + + if (!timespec64_valid_settod(tnew)) + return -EINVAL; + if (!tkd) + return -ENODEV; + + tks =3D &tkd->shadow_timekeeper; + + guard(raw_spinlock_irq)(&tkd->lock); + if (!tks->clock_valid) + return -ENODEV; + + /* Forward the timekeeper base time */ + timekeeping_forward_now(tks); + /* + * Get the updated base time. tkr_mono.base has not been + * updated yet, so do that first. That makes the update + * in timekeeping_update_from_shadow() redundant, but + * that's harmless. After that @tnow can be calculated + * by using tkr_mono::cycle_last, which has been set + * by timekeeping_forward_now(). + */ + tk_update_ktime_data(tks); + nsecs =3D timekeeping_cycles_to_ns(&tks->tkr_mono, tks->tkr_mono.cycle_la= st); + tnow =3D ktime_add(tks->tkr_mono.base, nsecs); + + /* Calculate the new AUX offset */ + tks->offs_aux =3D ktime_sub(timespec64_to_ktime(*tnew), tnow); + + timekeeping_update_from_shadow(tkd, TK_UPDATE_ALL); + return 0; +} + const struct k_clock clock_aux =3D { .clock_getres =3D aux_get_res, .clock_get_timespec =3D aux_get_timespec, + .clock_set =3D aux_clock_set, }; =20 static __init void tk_aux_setup(void) From nobody Wed Oct 8 17:31:54 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 25CE6263889; Wed, 25 Jun 2025 18:38:42 +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=1750876724; cv=none; b=do2hqGKBcneeO2UYO8tjlgehMCmktbqs6O2Qpt1f1+Q3uB5geYoRa9LqJ9mh8h1bMnKsxYyEeHHH+UAa1GV5hV+8Y93UMDCcKh8yanS+UvYh9dI01/Hy9vp8lO713nzODkWLphHPv46PxE33Qd0a+PKgX0Y7MvH55Mxvca39s7U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750876724; c=relaxed/simple; bh=uc/es1ZExZmmNTi/6NY7u44lqcvt7olusCfueDOrSGA=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=EQB00jGmnwMMM/aoIf77+zvPvQzQcp9KmcEJnA5m7ntflUTssbCW6G5FURAovJNWJ76Dy2tipQOreYZiaxklcAya9FYetyCvtcKj+Em9Jw4B3lGpMx6Po05tpylaS2fRpzJiKftSY2xwIghlLFKM0NconAeBaVmnxW9SNQB7920= 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=xG23n/tD; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=jV5A39Rd; 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="xG23n/tD"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="jV5A39Rd" Message-ID: <20250625183758.059934561@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1750876721; 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: references:references; bh=Sq8Ufr+ws3zucsMPNRZpVePba89PPVYTDnPp1nXRvF4=; b=xG23n/tDuHfN9PzShnK5fqlP8eSLhNnnSawdy+IH2EfYSAb063+zddr5ezNlt1vBjdMguE je4U4bXwVCetdXXw/acsPult3Sx0BJ1gSK/shaSALEy9ed67ywcDiBE5Cfla20GTq1jRKD xZnAFbGJN0AXlfeo4UVSisMzTwn/xEKO3E6+X5I0K2WwdIfwmBRkFkT4z/X+uhKA22Ayqb X5gQ6zovrm/Cw7PpieiwhXu6SeKu1RAJ/1chIRQFhKbweXn3gI5ukQZp0uLePUy+tmRhU9 GmFI93oK3R1WTVKjfNqsfL8pk4DD5mkV4UjQWgBOGgalp0yNdw/CX2WFhj0Idw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1750876721; 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: references:references; bh=Sq8Ufr+ws3zucsMPNRZpVePba89PPVYTDnPp1nXRvF4=; b=jV5A39RdSAGNCjXKT1rcKo9vyRAGTNmhcN9Uj8WkUF+0QEDw8GrcbXu/EDyj7jLeFhge6L SFmHncpNAFliS8Dg== From: Thomas Gleixner To: LKML Cc: netdev@vger.kernel.org, Richard Cochran , Christopher Hall , John Stultz , Frederic Weisbecker , Anna-Maria Behnsen , Miroslav Lichvar , Werner Abt , David Woodhouse , Stephen Boyd , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , Kurt Kanzenbach , Nam Cao , Antoine Tenart Subject: [patch V3 05/11] timekeeping: Make timekeeping_inject_offset() reusable References: <20250625182951.587377878@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Wed, 25 Jun 2025 20:38:40 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Split out the inner workings for auxiliary clock support and feed the core = time keeper into it. Signed-off-by: Thomas Gleixner Acked-by: John Stultz --- kernel/time/timekeeping.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) --- --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1433,32 +1433,32 @@ EXPORT_SYMBOL(do_settimeofday64); =20 /** * __timekeeping_inject_offset - Adds or subtracts from the current time. + * @tkd: Pointer to the timekeeper to modify * @ts: Pointer to the timespec variable containing the offset * * Adds or subtracts an offset value from the current time. */ -static int __timekeeping_inject_offset(const struct timespec64 *ts) +static int __timekeeping_inject_offset(struct tk_data *tkd, const struct t= imespec64 *ts) { - struct timekeeper *tks =3D &tk_core.shadow_timekeeper; + struct timekeeper *tks =3D &tkd->shadow_timekeeper; struct timespec64 tmp; =20 if (ts->tv_nsec < 0 || ts->tv_nsec >=3D NSEC_PER_SEC) return -EINVAL; =20 - timekeeping_forward_now(tks); =20 /* Make sure the proposed value is valid */ tmp =3D timespec64_add(tk_xtime(tks), *ts); if (timespec64_compare(&tks->wall_to_monotonic, ts) > 0 || !timespec64_valid_settod(&tmp)) { - timekeeping_restore_shadow(&tk_core); + timekeeping_restore_shadow(tkd); return -EINVAL; } =20 tk_xtime_add(tks, ts); tk_set_wall_to_mono(tks, timespec64_sub(tks->wall_to_monotonic, *ts)); - timekeeping_update_from_shadow(&tk_core, TK_UPDATE_ALL); + timekeeping_update_from_shadow(tkd, TK_UPDATE_ALL); return 0; } =20 @@ -1467,7 +1467,7 @@ static int timekeeping_inject_offset(con int ret; =20 scoped_guard (raw_spinlock_irqsave, &tk_core.lock) - ret =3D __timekeeping_inject_offset(ts); + ret =3D __timekeeping_inject_offset(&tk_core, ts); =20 /* Signal hrtimers about time change */ if (!ret) @@ -2568,6 +2568,7 @@ EXPORT_SYMBOL_GPL(random_get_entropy_fal */ int do_adjtimex(struct __kernel_timex *txc) { + struct tk_data *tkd =3D &tk_core; struct timespec64 delta, ts; struct audit_ntp_data ad; bool offset_set =3D false; @@ -2585,16 +2586,19 @@ int do_adjtimex(struct __kernel_timex *t ktime_get_real_ts64(&ts); add_device_randomness(&ts, sizeof(ts)); =20 - scoped_guard (raw_spinlock_irqsave, &tk_core.lock) { - struct timekeeper *tks =3D &tk_core.shadow_timekeeper; + scoped_guard (raw_spinlock_irqsave, &tkd->lock) { + struct timekeeper *tks =3D &tkd->shadow_timekeeper; s32 orig_tai, tai; =20 + if (!tks->clock_valid) + return -ENODEV; + if (txc->modes & ADJ_SETOFFSET) { delta.tv_sec =3D txc->time.tv_sec; delta.tv_nsec =3D txc->time.tv_usec; if (!(txc->modes & ADJ_NANO)) delta.tv_nsec *=3D 1000; - ret =3D __timekeeping_inject_offset(&delta); + ret =3D __timekeeping_inject_offset(tkd, &delta); if (ret) return ret; =20 @@ -2607,7 +2611,7 @@ int do_adjtimex(struct __kernel_timex *t =20 if (tai !=3D orig_tai) { __timekeeping_set_tai_offset(tks, tai); - timekeeping_update_from_shadow(&tk_core, TK_CLOCK_WAS_SET); + timekeeping_update_from_shadow(tkd, TK_CLOCK_WAS_SET); clock_set =3D true; } else { tk_update_leap_state_all(&tk_core); @@ -2615,7 +2619,7 @@ int do_adjtimex(struct __kernel_timex *t =20 /* Update the multiplier immediately if frequency was set directly */ if (txc->modes & (ADJ_FREQUENCY | ADJ_TICK)) - clock_set |=3D __timekeeping_advance(&tk_core, TK_ADV_FREQ); + clock_set |=3D __timekeeping_advance(tkd, TK_ADV_FREQ); } =20 if (txc->modes & ADJ_SETOFFSET) From nobody Wed Oct 8 17:31:54 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 855232D9EC8; Wed, 25 Jun 2025 18:38:44 +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=1750876726; cv=none; b=o4E/qIm3jQgSVuGnRTN5KTNwC2rRyOr/41OFubucK2Jfa9as8bOi5y8mbnj/yLhVDGLGBLgOPO6MmtbHZwbTAcEaFgLs3hV+u+OUaGteRuaoan06oIaGxGe5Gy6HDUiNW4o0iHQq7a3iKrEV8gVQxZAOLJjMP1kSXQNblMQnv00= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750876726; c=relaxed/simple; bh=rB/EnRxu0imXWgJA4w5Gjj1lvQ8UbNidQsMiPmpllUs=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=PoaLGIUJQGSNInmoYGu4x2PX9DcPmptRhuK66ikLKzyha8xfrzw7LToSoIbH6eSilwS8Gci7Y2jM+YX33c0fLtGrahQ0+0nZOk5swl2mxntj9gq+786DLFo2S9e/h1Jf+XFxk8d7Q0Ge4r6W6HVC9W5xcPb9JqZb55GDaOb7u3U= 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=SLiwMDXN; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=XKye40fo; 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="SLiwMDXN"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="XKye40fo" Message-ID: <20250625183758.124057787@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1750876722; 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: references:references; bh=YIM8V9tSBfvx2tx7O5vH1ndpneATAeuGOg9AVw4OPCY=; b=SLiwMDXNYxOSbLg3LTR1W6VGgeWl07lp2xbixAQDEfiP0yzIKwcEfkoPAYlabAg4X1SB4H +hCP82/SXUysVe/pcJikTa7Jb3ZQY46R26dRE6qCCEYIwNYzFjSezJ5eW0k+E71jP6uZ56 3ZaYAWKAzG774kvPj1szKapjCMd/znDcTnFpJ4vD6K2wjvkFyTZ8sRpJr5UwdhzZzUX5nW XlCN8Yu2DgMX3UO7FlB8B4lIyt5fk/07kyuBl/MaDSzfHu/8mSMrbTN222YD2ZAE3hY1vc 8m6bM/mFs+sybrCXUTFoDOD/iJKd+c8XC/s7rTCpCQPvrOIcVw0APUjJBmC/JQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1750876722; 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: references:references; bh=YIM8V9tSBfvx2tx7O5vH1ndpneATAeuGOg9AVw4OPCY=; b=XKye40fo0BAtIXJHCtw83SIPTg/qPIKugqQfj40FvHx0i5mUROzXYTzedXO4GrOvmIdmTV pSnZMUl/1So7p7Dw== From: Thomas Gleixner To: LKML Cc: netdev@vger.kernel.org, Richard Cochran , Christopher Hall , John Stultz , Frederic Weisbecker , Anna-Maria Behnsen , Miroslav Lichvar , Werner Abt , David Woodhouse , Stephen Boyd , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , Kurt Kanzenbach , Nam Cao , Antoine Tenart Subject: [patch V3 06/11] timekeeping: Add auxiliary clock support to __timekeeping_inject_offset() References: <20250625182951.587377878@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Wed, 25 Jun 2025 20:38:42 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Redirect the relative offset adjustment to the auxiliary clock offset instead of modifying CLOCK_REALTIME, which has no meaning in context of these clocks. Signed-off-by: Thomas Gleixner --- kernel/time/timekeeping.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) --- --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1448,16 +1448,34 @@ static int __timekeeping_inject_offset(s =20 timekeeping_forward_now(tks); =20 - /* Make sure the proposed value is valid */ - tmp =3D timespec64_add(tk_xtime(tks), *ts); - if (timespec64_compare(&tks->wall_to_monotonic, ts) > 0 || - !timespec64_valid_settod(&tmp)) { - timekeeping_restore_shadow(tkd); - return -EINVAL; + if (!IS_ENABLED(CONFIG_POSIX_AUX_CLOCKS) || tks->id =3D=3D TIMEKEEPER_COR= E) { + /* Make sure the proposed value is valid */ + tmp =3D timespec64_add(tk_xtime(tks), *ts); + if (timespec64_compare(&tks->wall_to_monotonic, ts) > 0 || + !timespec64_valid_settod(&tmp)) { + timekeeping_restore_shadow(tkd); + return -EINVAL; + } + + tk_xtime_add(tks, ts); + tk_set_wall_to_mono(tks, timespec64_sub(tks->wall_to_monotonic, *ts)); + } else { + struct tk_read_base *tkr_mono =3D &tks->tkr_mono; + ktime_t now, offs; + + /* Get the current time */ + now =3D ktime_add_ns(tkr_mono->base, timekeeping_get_ns(tkr_mono)); + /* Add the relative offset change */ + offs =3D ktime_add(tks->offs_aux, timespec64_to_ktime(*ts)); + + /* Prevent that the resulting time becomes negative */ + if (ktime_add(now, offs) < 0) { + timekeeping_restore_shadow(tkd); + return -EINVAL; + } + tks->offs_aux =3D offs; } =20 - tk_xtime_add(tks, ts); - tk_set_wall_to_mono(tks, timespec64_sub(tks->wall_to_monotonic, *ts)); timekeeping_update_from_shadow(tkd, TK_UPDATE_ALL); return 0; } From nobody Wed Oct 8 17:31:54 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 D76072E0B4C; Wed, 25 Jun 2025 18:38:45 +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=1750876727; cv=none; b=AdwScsItISSHVeO3wqrHqaBWIDL3u3dJ8ny6yBkyaNPwWkKvwuFIdnVu7pcINTFUDspQa7kckGP4SdxvvEk54b2B0pHjuG8OD/iFH7pnBoLySl9xH42TYOE0euzpCIFzoQRcYfikgh5YcQgqWW3MOYEjV9Hed0ftasKoJOfvmsk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750876727; c=relaxed/simple; bh=b5T8Jbp5iX0f1kT4SzSqHy+BudfP0PzjLAc2zVZJTyg=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=pGxYSb25zSpVxEtMoga0c5zWOne764B6vyCBSsIYWX6C9FpfQkl89DuplQxk3uYgRfllZ5u90PVhU1i47caBAzdDGTIeAlycyTylkfENTJXBAkZfM7s293+6kCZvqfMI7+XRDcuewcJb+1S/BperTDNQ+Oln7lN6apKCMagJEI4= 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=L5RSX64P; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Tqd4mPhY; 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="L5RSX64P"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Tqd4mPhY" Message-ID: <20250625183758.187322876@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1750876724; 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: references:references; bh=tqZxEcAjH2Q08zl9VMf10qBSNpG/vqmret2ndMqGbDE=; b=L5RSX64Prg4HapU8RlAQ2FxFmVhB65blPKS0sPBVvPuKUAo9MtXP5Jef35GMX+nNU0iwzI tvo+upDXGctmyphuMIiBvAE3LMlOXT+0avV4phlNXKXO5akupmADJld579wKTsNMcs2wHB UrXqJGU58ApTSjF5Z7yVD8z0GGU7qUWC418MQ02RuA03GkGrTFlHQXwfwc1A34voNrYjSf A8cnIkh0ttxtybj1dahWyFGkNtC0rKbgPhfoXkh1XVPK5VCpypdB/cc3e8hJ3DMNF+Yr4a tc4EErwZE6wABPwbJk71Rm0L93NIewwB4ZKe5tmBJ+utWejSuPHwhRZixdBM4A== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1750876724; 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: references:references; bh=tqZxEcAjH2Q08zl9VMf10qBSNpG/vqmret2ndMqGbDE=; b=Tqd4mPhYKI8K6QQ8jAbrjfXcJB/oTY7HQij6oM5KMRusnbeS9VX61giJ8GwxVlJY4wjM1F /ggJCiY3xduuKrAA== From: Thomas Gleixner To: LKML Cc: netdev@vger.kernel.org, Richard Cochran , Christopher Hall , John Stultz , Frederic Weisbecker , Anna-Maria Behnsen , Miroslav Lichvar , Werner Abt , David Woodhouse , Stephen Boyd , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , Kurt Kanzenbach , Nam Cao , Antoine Tenart Subject: [patch V3 07/11] timekeeping: Make do_adjtimex() reusable References: <20250625182951.587377878@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Wed, 25 Jun 2025 20:38:43 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Split out the actual functionality of adjtimex() and make do_adjtimex() a wrapper which feeds the core timekeeper into it and handles the result including audit at the call site. This allows to reuse the actual functionality for auxiliary clocks. Signed-off-by: Thomas Gleixner Acked-by: John Stultz --- kernel/time/timekeeping.c | 110 +++++++++++++++++++++++++----------------= ----- 1 file changed, 60 insertions(+), 50 deletions(-) --- --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -2580,17 +2580,18 @@ unsigned long random_get_entropy_fallbac } EXPORT_SYMBOL_GPL(random_get_entropy_fallback); =20 -/** - * do_adjtimex() - Accessor function to NTP __do_adjtimex function - * @txc: Pointer to kernel_timex structure containing NTP parameters - */ -int do_adjtimex(struct __kernel_timex *txc) +struct adjtimex_result { + struct audit_ntp_data ad; + struct timespec64 delta; + bool clock_set; +}; + +static int __do_adjtimex(struct tk_data *tkd, struct __kernel_timex *txc, + struct adjtimex_result *result) { - struct tk_data *tkd =3D &tk_core; - struct timespec64 delta, ts; - struct audit_ntp_data ad; - bool offset_set =3D false; - bool clock_set =3D false; + struct timekeeper *tks =3D &tkd->shadow_timekeeper; + struct timespec64 ts; + s32 orig_tai, tai; int ret; =20 /* Validate the data before disabling interrupts */ @@ -2599,56 +2600,65 @@ int do_adjtimex(struct __kernel_timex *t return ret; add_device_randomness(txc, sizeof(*txc)); =20 - audit_ntp_init(&ad); - ktime_get_real_ts64(&ts); add_device_randomness(&ts, sizeof(ts)); =20 - scoped_guard (raw_spinlock_irqsave, &tkd->lock) { - struct timekeeper *tks =3D &tkd->shadow_timekeeper; - s32 orig_tai, tai; - - if (!tks->clock_valid) - return -ENODEV; - - if (txc->modes & ADJ_SETOFFSET) { - delta.tv_sec =3D txc->time.tv_sec; - delta.tv_nsec =3D txc->time.tv_usec; - if (!(txc->modes & ADJ_NANO)) - delta.tv_nsec *=3D 1000; - ret =3D __timekeeping_inject_offset(tkd, &delta); - if (ret) - return ret; - - offset_set =3D delta.tv_sec !=3D 0; - clock_set =3D true; - } - - orig_tai =3D tai =3D tks->tai_offset; - ret =3D ntp_adjtimex(tks->id, txc, &ts, &tai, &ad); - - if (tai !=3D orig_tai) { - __timekeeping_set_tai_offset(tks, tai); - timekeeping_update_from_shadow(tkd, TK_CLOCK_WAS_SET); - clock_set =3D true; - } else { - tk_update_leap_state_all(&tk_core); - } - - /* Update the multiplier immediately if frequency was set directly */ - if (txc->modes & (ADJ_FREQUENCY | ADJ_TICK)) - clock_set |=3D __timekeeping_advance(tkd, TK_ADV_FREQ); + guard(raw_spinlock_irqsave)(&tkd->lock); + + if (!tks->clock_valid) + return -ENODEV; + + if (txc->modes & ADJ_SETOFFSET) { + result->delta.tv_sec =3D txc->time.tv_sec; + result->delta.tv_nsec =3D txc->time.tv_usec; + if (!(txc->modes & ADJ_NANO)) + result->delta.tv_nsec *=3D 1000; + ret =3D __timekeeping_inject_offset(tkd, &result->delta); + if (ret) + return ret; + result->clock_set =3D true; + } + + orig_tai =3D tai =3D tks->tai_offset; + ret =3D ntp_adjtimex(tks->id, txc, &ts, &tai, &result->ad); + + if (tai !=3D orig_tai) { + __timekeeping_set_tai_offset(tks, tai); + timekeeping_update_from_shadow(tkd, TK_CLOCK_WAS_SET); + result->clock_set =3D true; + } else { + tk_update_leap_state_all(&tk_core); } =20 + /* Update the multiplier immediately if frequency was set directly */ + if (txc->modes & (ADJ_FREQUENCY | ADJ_TICK)) + result->clock_set |=3D __timekeeping_advance(tkd, TK_ADV_FREQ); + + return ret; +} + +/** + * do_adjtimex() - Accessor function to NTP __do_adjtimex function + * @txc: Pointer to kernel_timex structure containing NTP parameters + */ +int do_adjtimex(struct __kernel_timex *txc) +{ + struct adjtimex_result result =3D { }; + int ret; + + ret =3D __do_adjtimex(&tk_core, txc, &result); + if (ret < 0) + return ret; + if (txc->modes & ADJ_SETOFFSET) - audit_tk_injoffset(delta); + audit_tk_injoffset(result.delta); =20 - audit_ntp_log(&ad); + audit_ntp_log(&result.ad); =20 - if (clock_set) + if (result.clock_set) clock_was_set(CLOCK_SET_WALL); =20 - ntp_notify_cmos_timer(offset_set); + ntp_notify_cmos_timer(result.delta.tv_sec !=3D 0); =20 return ret; } From nobody Wed Oct 8 17:31:54 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 AF4F62E11D2; Wed, 25 Jun 2025 18:38:47 +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=1750876730; cv=none; b=fOwiwOWGtXsvatXM2pmfZNsvi8HuMSqutMIVts4J/QZi/++OPKAtXjTrsiadLR6WQQhC+OamgdRzyXmls8yLW22gRf8epUBwWqUpOjGjX5W2KtbOdOIOTjpZi0H8ZXSFXDehNd6so+iyPsDjg2pmuYIKGiudpKIgB0lJ/2zMtFs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750876730; c=relaxed/simple; bh=XToOVm2FXAXySjWBpSyRSFYblYGvxnRlaBYG/+Er27k=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=MQUg0OdmRFNNRRVvzADpltuGYXn42/c3ZN3ZeAPFVE19OOhlpcLzZbiandYw4iFgXgh1JzIhj020x/0IIgqGf447SmlqIbYE/KNY7nj1r/i1haHL7VzuQxswzsEogamxA7eqhIJhVNn+LaILeSJ77mbs00KULVwtIKBs8oNOu8s= 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=tH+Tl64z; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=uLir9uiA; 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="tH+Tl64z"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="uLir9uiA" Message-ID: <20250625183758.253203783@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1750876725; 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: references:references; bh=HmYulIT89IwzdBVQfLuVPcreFHp/8ZApSW/Ds8aJxgk=; b=tH+Tl64z3P9o/hzlt+NAUVQUoqKDQ37iPUwn4N5x8FCErETNpOENoCMQSVoNpfqO9kKqM5 uDiKJFfW6YSVssH4XKg+0nzYiXL36aVkLGqX9tR/n8gFQiv2uWPCDBzbTzc98i9Vyg8cvC z3zBT03sWbwhAHKbAj+AOLcRh0K76zu4z7UrF05CExCUsgTdOR3F9VcvbfZjazebG53SbI Zv9vbeFk1UW3GL9q1Cgw6aIZHZfEBEPvbb21RFXOzSJGcwPJWXo2PPUAolKG8Hb5PvtFZr qXO9hO1eR3+jCXRT9gXR/VXoDnJDqKborpf5ZKJj7Ah7pgS76MoMC+lhxZlpHQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1750876725; 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: references:references; bh=HmYulIT89IwzdBVQfLuVPcreFHp/8ZApSW/Ds8aJxgk=; b=uLir9uiA1lV2SY9GBp9jeLETysd3hyuf/mQ9uUPg1DsE/7wubc0T2+ShE+RyzbNugUT1HI V5ROBtoPR//CAZBQ== From: Thomas Gleixner To: LKML Cc: netdev@vger.kernel.org, Richard Cochran , Christopher Hall , John Stultz , Frederic Weisbecker , Anna-Maria Behnsen , Miroslav Lichvar , Werner Abt , David Woodhouse , Stephen Boyd , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , Kurt Kanzenbach , Nam Cao , Antoine Tenart Subject: [patch V3 08/11] timekeeping: Prepare do_adtimex() for auxiliary clocks References: <20250625182951.587377878@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Wed, 25 Jun 2025 20:38:45 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Exclude ADJ_TAI, leap seconds and PPS functionality as they make no sense in the context of auxiliary clocks and provide a time stamp based on the actual clock. Signed-off-by: Thomas Gleixner Acked-by: John Stultz --- kernel/time/timekeeping.c | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) --- --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -58,6 +58,17 @@ static struct tk_data timekeeper_data[TI /* The core timekeeper */ #define tk_core (timekeeper_data[TIMEKEEPER_CORE]) =20 +#ifdef CONFIG_POSIX_AUX_CLOCKS +static inline bool tk_get_aux_ts64(unsigned int tkid, struct timespec64 *t= s) +{ + return ktime_get_aux_ts64(CLOCK_AUX + tkid - TIMEKEEPER_AUX_FIRST, ts); +} +#else +static inline bool tk_get_aux_ts64(unsigned int tkid, struct timespec64 *t= s) +{ + return false; +} +#endif =20 /* flag for if timekeeping is suspended */ int __read_mostly timekeeping_suspended; @@ -2503,7 +2514,7 @@ ktime_t ktime_get_update_offsets_now(uns /* * timekeeping_validate_timex - Ensures the timex is ok for use in do_adjt= imex */ -static int timekeeping_validate_timex(const struct __kernel_timex *txc) +static int timekeeping_validate_timex(const struct __kernel_timex *txc, bo= ol aux_clock) { if (txc->modes & ADJ_ADJTIME) { /* singleshot must not be used with any other mode bits */ @@ -2562,6 +2573,21 @@ static int timekeeping_validate_timex(co return -EINVAL; } =20 + if (!aux_clock) + return 0; + + /* Auxiliary clocks are similar to TAI and do not have leap seconds */ + if (txc->status & (STA_INS | STA_DEL)) + return -EINVAL; + + /* No TAI offset setting */ + if (txc->modes & ADJ_TAI) + return -EINVAL; + + /* No PPS support either */ + if (txc->status & (STA_PPSFREQ | STA_PPSTIME)) + return -EINVAL; + return 0; } =20 @@ -2592,15 +2618,22 @@ static int __do_adjtimex(struct tk_data struct timekeeper *tks =3D &tkd->shadow_timekeeper; struct timespec64 ts; s32 orig_tai, tai; + bool aux_clock; int ret; =20 + aux_clock =3D IS_ENABLED(CONFIG_POSIX_AUX_CLOCKS) && tkd->timekeeper.id != =3D TIMEKEEPER_CORE; + /* Validate the data before disabling interrupts */ - ret =3D timekeeping_validate_timex(txc); + ret =3D timekeeping_validate_timex(txc, aux_clock); if (ret) return ret; add_device_randomness(txc, sizeof(*txc)); =20 - ktime_get_real_ts64(&ts); + if (!aux_clock) + ktime_get_real_ts64(&ts); + else + tk_get_aux_ts64(tkd->timekeeper.id, &ts); + add_device_randomness(&ts, sizeof(ts)); =20 guard(raw_spinlock_irqsave)(&tkd->lock); From nobody Wed Oct 8 17:31:54 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 AF4792E11D1; Wed, 25 Jun 2025 18:38:48 +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=1750876730; cv=none; b=quQwpu6yhusF9opyBR1HSEhSkzerrqlpMnrR1Y3cHKj7gJYYHGEDRbLH5Op+qMgVYwhjiucvfAALrZi+Ajh3vw4jnIdeWwjMmKvDZSsXBrqI/Q1qG5lJIPH/BifsdJuCIdOiJZvZMCSHgBIGGGiFwJeuQoH+upFeuQ7+JV7l4hs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750876730; c=relaxed/simple; bh=zVJf+MmEC3btYGKcyJeAPT+oFJj0a7vjbezGTwNcPH0=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=vA/Yrrxj+HQOWSHkKIrubTVdeFlwUgpd0kiG+F2+ajEXMs84Gk8YAACWJ60r3TCqinSO6KMqt89opDH01+jGOaop9Rn7t4RELZV+9fBF7rWiWyfDFdsF1UncXSeMmxBlqUNASQqERkUYDZGjb5V/T5vTks7QNajHyzV/v/eh4OM= 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=h+RFuY3I; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=/+u3PQoh; 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="h+RFuY3I"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="/+u3PQoh" Message-ID: <20250625183758.317946543@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1750876727; 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: references:references; bh=8ViF+rrLWVVG0MZcV0fafeyznX+ujEDD9BAyqdiPByg=; b=h+RFuY3IPFntsBRJwpsBt3oclBiNNWduh3GRIsa3lTE3OAJUwkw/pTqA+pOtIe4jZkTNZo JxwIDBKWpwbbrEJD9x6NP+gGFsBh5AwNegtJaNtqHaWbFU/+8Uync6EFNzZLnp8Uodpj5Y eoBdS+L2Sn0Z3308opRcKL//94Ae4HImcD3e5yCC3bLA0P7mdtixKhhaYVj1BLjuuwS4sy tKMTQ983Uq3IdJWyfI52oDkkAm4E7Etiv+yw+ULnCERe5/O1zaUNo/ICN82PXBcYZnRaR0 LYJh5WgCjakzmlJhmoCvvURaSn7YbDZ5hhW2J40vEFN4Zy1+6i715BLsgnmYmA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1750876727; 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: references:references; bh=8ViF+rrLWVVG0MZcV0fafeyznX+ujEDD9BAyqdiPByg=; b=/+u3PQoh5dlc7OOWzjTMReCdVQDGqzeNG7dqERO2V90MCWGtYHl0k6ZWVbm96n0wAU6pEf QR1UysI9NI/vitDg== From: Thomas Gleixner To: LKML Cc: netdev@vger.kernel.org, Richard Cochran , Christopher Hall , John Stultz , Frederic Weisbecker , Anna-Maria Behnsen , Miroslav Lichvar , Werner Abt , David Woodhouse , Stephen Boyd , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , Kurt Kanzenbach , Nam Cao , Antoine Tenart Subject: [patch V3 09/11] timekeeping: Provide adjtimex() for auxiliary clocks References: <20250625182951.587377878@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Wed, 25 Jun 2025 20:38:46 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The behaviour is close to clock_adtime(CLOCK_REALTIME) with the following differences: 1) ADJ_SETOFFSET adjusts the auxiliary clock offset =20 2) ADJ_TAI is not supported 3) Leap seconds are not supported 4) PPS is not supported Signed-off-by: Thomas Gleixner Acked-by: John Stultz --- kernel/time/timekeeping.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) --- --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -2860,10 +2860,26 @@ static int aux_clock_set(const clockid_t return 0; } =20 +static int aux_clock_adj(const clockid_t id, struct __kernel_timex *txc) +{ + struct tk_data *tkd =3D aux_get_tk_data(id); + struct adjtimex_result result =3D { }; + + if (!tkd) + return -ENODEV; + + /* + * @result is ignored for now as there are neither hrtimers nor a + * RTC related to auxiliary clocks for now. + */ + return __do_adjtimex(tkd, txc, &result); +} + const struct k_clock clock_aux =3D { .clock_getres =3D aux_get_res, .clock_get_timespec =3D aux_get_timespec, .clock_set =3D aux_clock_set, + .clock_adj =3D aux_clock_adj, }; =20 static __init void tk_aux_setup(void) From nobody Wed Oct 8 17:31:54 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 2FF0D2E173C; Wed, 25 Jun 2025 18:38:49 +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=1750876731; cv=none; b=XdR55Mg/vnSLCpZOr/iuB/ONYrWk+sDR+b6/2Adj6yV1N/L98E+KSbWv8iw6F6jmHkfRVggn2lYGlaBKtulgfiaGze5twVHz7DHnpEtQL0wNMWiWMKeHkkAHtUO3YVr1AMYJKQU1p2IP4j1CrfGMHqu2DW8awUpByfdTcJ0jdoo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750876731; c=relaxed/simple; bh=dlw8KDSGu+ehPJAe+navRVPjiPuj28L8LmFkc1hGo6U=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=FPkiJ3nes3nmcsXFLAFzh1ORaC4U2BP/ew/0H7cCH5TtnFcyhQoFWie0L1jCcm6+Pnm27Zx0S+kPegqkejox5qwFcKCw7M6QjxsJsvqhgK4cMy80ZcKNY6Ev4FhtODGfAjxukL56D5Tsn7amU8t2cof3wdbqE0hWGsmPejuwneU= 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=1gLUyO0W; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=azNXTnOV; 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="1gLUyO0W"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="azNXTnOV" Message-ID: <20250625183758.382451331@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1750876728; 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: references:references; bh=rgazCkd3u3F5i4CrLdkq+/PjRiwjzzoSmk6V32qkK3I=; b=1gLUyO0W1GJamInYQ2FeJDYwutkPTRLou2YJcNFHXCXJKBlEEO6K7HoQzL3qdoNzl9qV2P j7/iPeSyM/0c2wV2KUcc7mCYx4drBGhB9paoRLI//gMxjLxAZaZrXcmjrIUIzubSA17zna f0dqi2H9tQG3bcC4tI2WwnvL9yyrmxvAIv5TK96PHJV3gGNGtsEH7tCGHN0LOKvjGAYYXr CqzJooFRLbcyLGuHHgLqpSD1EUlK92S5v2PGOMv4YcopeUOIv5Jxm8GvJnl6oEAdEVQsa1 5fJg6aZsfbrB3+BAYzJSfnFX+1eW5GyRUIok28YW+h8pVcv5h7yz7WcThPJKVw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1750876728; 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: references:references; bh=rgazCkd3u3F5i4CrLdkq+/PjRiwjzzoSmk6V32qkK3I=; b=azNXTnOV9H7Fx2+NFomVcQD0LzodKYeFxbrd8WBXpqpAWI1XVJrPEwRTwBME1GD7dZaI4E Ctr0D6DRh0T8OHAA== From: Thomas Gleixner To: LKML Cc: netdev@vger.kernel.org, Richard Cochran , Christopher Hall , John Stultz , Frederic Weisbecker , Anna-Maria Behnsen , Miroslav Lichvar , Werner Abt , David Woodhouse , Stephen Boyd , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , Kurt Kanzenbach , Nam Cao , Antoine Tenart Subject: [patch V3 10/11] timekeeping: Provide update for auxiliary timekeepers References: <20250625182951.587377878@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Wed, 25 Jun 2025 20:38:47 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 t= he tick. Signed-off-by: Thomas Gleixner Acked-by: John Stultz --- 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 =20 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 t= ime * + * 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(); } =20 /** @@ -2762,6 +2766,20 @@ static void tk_aux_update_clocksource(vo } } =20 +static void tk_aux_advance(void) +{ + unsigned long active =3D READ_ONCE(aux_timekeepers); + unsigned int id; + + for_each_set_bit(id, &active, BITS_PER_LONG) { + struct tk_data *tkd =3D &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...) From nobody Wed Oct 8 17:31:54 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 836552E3388; Wed, 25 Jun 2025 18:38:51 +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=1750876733; cv=none; b=XkDHtyZB4qZKhI2zcuQLZfEL11+Bjs3nxTosmfne34tVZ8QjqPw2bKHWIPInrgSwmOvutLEuyx9qUpDO+vmHFP6y/j/+VFTyTJwauT7Vf3X+vj7wnrGiU6H9lfN4po0uPWPrW11Qlqn91RXeLJaJEAcZayh56q2ddZiQYy/AiXY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750876733; c=relaxed/simple; bh=NMUMEIPyHxhekNIC8s3B1N0LZPU2VVuPf954wipIkD0=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=JPeUYibI79mrDIHbeffAOLB14JPJVhpv/adO89W9hL5YKc4pvrPLNQGJKCPlMQc95mxdviXmRnbLS7JjLdXlLDjXegY4UHF3+YqFtTF6YfZ5DOEGNZC5M3XGjh1DY6u1jeQlkU/G+YOooQdvuyZ1Xm52S1dGjh81xcpcrHmB2GQ= 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=mxx0I5CV; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=RK72PhBQ; 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="mxx0I5CV"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="RK72PhBQ" Message-ID: <20250625183758.444626478@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1750876729; 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: references:references; bh=axrrptkM5cruK2olPk9Gk1fVUzCj5KYtyRuWYLFYvKQ=; b=mxx0I5CVfeoVVNk9fVWTtn4P3rh9PgOkLRKcy+7vlXPqs27TvzI2gO8me9rk42I6mLdtFm 8Cwxtw/AOCs/hFR8JS1z1ilJdtQHNxFRekZi6dt1gWXRK7B7CZV8PE+QYWfdZ83fSTi6Il iTQx1KTjFdW9yDWoxYnwFla2RwVgIpskQU3VAIvcpZMU3fdsQ01Og7eLzfQNi7fjCtAzpQ WiFLaUCF8XrM72y90v7hSwtTT28GADH8FIWXGBmGY9Koa5Vn0qjfrIq4lA/NiheLGN3c0q Xlz/bUyZgCwb8xtuonJJ59uzcNZxSDuiVUUQDjsGvnLUQEUUqghouSLcR4F+1A== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1750876729; 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: references:references; bh=axrrptkM5cruK2olPk9Gk1fVUzCj5KYtyRuWYLFYvKQ=; b=RK72PhBQNXBtURVlOhWZ2ndQ+Hbg/Bi5BAtTuYLbud3nZvU1PrXx/ejYR6LQXLNzkDSwdz mw/QRAqCxx9zyqDA== From: Thomas Gleixner To: LKML Cc: netdev@vger.kernel.org, Richard Cochran , Christopher Hall , John Stultz , Frederic Weisbecker , Anna-Maria Behnsen , Miroslav Lichvar , Werner Abt , David Woodhouse , Stephen Boyd , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , Kurt Kanzenbach , Nam Cao , Antoine Tenart Subject: [patch V3 11/11] timekeeping: Provide interface to control auxiliary clocks References: <20250625182951.587377878@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Wed, 25 Jun 2025 20:38:49 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Auxiliary clocks are disabled by default and attempts to access them fail. Provide an interface to enable/disable them at run-time. Signed-off-by: Thomas Gleixner Acked-by: John Stultz --- V3: Use kobject.h, clockid_t and cleanup the sysfs init - Thomas W. Use aux_tkd, aux_tks for clarity - John --- Documentation/ABI/stable/sysfs-kernel-time-aux-clocks | 5=20 kernel/time/timekeeping.c | 116 +++++++++++++= +++++ 2 files changed, 121 insertions(+) --- /dev/null +++ b/Documentation/ABI/stable/sysfs-kernel-time-aux-clocks @@ -0,0 +1,5 @@ +What: /sys/kernel/time/aux_clocks//enable +Date: May 2025 +Contact: Thomas Gleixner +Description: + Controls the enablement of auxiliary clock timekeepers. --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -2903,6 +2904,121 @@ const struct k_clock clock_aux =3D { .clock_adj =3D aux_clock_adj, }; =20 +static void aux_clock_enable(clockid_t id) +{ + struct tk_read_base *tkr_raw =3D &tk_core.timekeeper.tkr_raw; + struct tk_data *aux_tkd =3D aux_get_tk_data(id); + struct timekeeper *aux_tks =3D &aux_tkd->shadow_timekeeper; + + /* Prevent the core timekeeper from changing. */ + guard(raw_spinlock_irq)(&tk_core.lock); + + /* + * Setup the auxiliary clock assuming that the raw core timekeeper + * clock frequency conversion is close enough. Userspace has to + * adjust for the deviation via clock_adjtime(2). + */ + guard(raw_spinlock_nested)(&aux_tkd->lock); + + /* Remove leftovers of a previous registration */ + memset(aux_tks, 0, sizeof(*aux_tks)); + /* Restore the timekeeper id */ + aux_tks->id =3D aux_tkd->timekeeper.id; + /* Setup the timekeeper based on the current system clocksource */ + tk_setup_internals(aux_tks, tkr_raw->clock); + + /* Mark it valid and set it live */ + aux_tks->clock_valid =3D true; + timekeeping_update_from_shadow(aux_tkd, TK_UPDATE_ALL); +} + +static void aux_clock_disable(clockid_t id) +{ + struct tk_data *aux_tkd =3D aux_get_tk_data(id); + + guard(raw_spinlock_irq)(&aux_tkd->lock); + aux_tkd->shadow_timekeeper.clock_valid =3D false; + timekeeping_update_from_shadow(aux_tkd, TK_UPDATE_ALL); +} + +static DEFINE_MUTEX(aux_clock_mutex); + +static ssize_t aux_clock_enable_store(struct kobject *kobj, struct kobj_at= tribute *attr, + const char *buf, size_t count) +{ + /* Lazy atoi() as name is "0..7" */ + int id =3D kobj->name[0] & 0x7; + bool enable; + + if (!capable(CAP_SYS_TIME)) + return -EPERM; + + if (kstrtobool(buf, &enable) < 0) + return -EINVAL; + + guard(mutex)(&aux_clock_mutex); + if (enable =3D=3D test_bit(id, &aux_timekeepers)) + return count; + + if (enable) { + aux_clock_enable(CLOCK_AUX + id); + set_bit(id, &aux_timekeepers); + } else { + aux_clock_disable(CLOCK_AUX + id); + clear_bit(id, &aux_timekeepers); + } + return count; +} + +static ssize_t aux_clock_enable_show(struct kobject *kobj, struct kobj_att= ribute *attr, char *buf) +{ + unsigned long active =3D READ_ONCE(aux_timekeepers); + /* Lazy atoi() as name is "0..7" */ + int id =3D kobj->name[0] & 0x7; + + return sysfs_emit(buf, "%d\n", test_bit(id, &active)); +} + +static struct kobj_attribute aux_clock_enable_attr =3D __ATTR_RW(aux_clock= _enable); + +static struct attribute *aux_clock_enable_attrs[] =3D { + &aux_clock_enable_attr.attr, + NULL +}; + +static const struct attribute_group aux_clock_enable_attr_group =3D { + .attrs =3D aux_clock_enable_attrs, +}; + +static int __init tk_aux_sysfs_init(void) +{ + struct kobject *auxo, *tko =3D kobject_create_and_add("time", kernel_kobj= ); + + if (!tko) + return -ENOMEM; + + auxo =3D kobject_create_and_add("aux_clocks", tko); + if (!auxo) { + kobject_put(tko); + return -ENOMEM; + } + + for (int i =3D 0; i <=3D MAX_AUX_CLOCKS; i++) { + char id[2] =3D { [0] =3D '0' + i, }; + struct kobject *clk =3D kobject_create_and_add(id, auxo); + + if (!clk) + return -ENOMEM; + + int ret =3D sysfs_create_group(clk, &aux_clock_enable_attr_group); + + if (ret) + return ret; + } + return 0; +} +late_initcall(tk_aux_sysfs_init); + static __init void tk_aux_setup(void) { for (int i =3D TIMEKEEPER_AUX_FIRST; i <=3D TIMEKEEPER_AUX_LAST; i++)