Re: [PATCH 3/4] rtc: Add support for configuring the UIP timeout for RTC reads

From: Mateusz Jończyk
Date: Sat Nov 18 2023 - 14:07:14 EST


Hello,

W dniu 17.11.2023 o 07:32, Mario Limonciello pisze:
> The UIP timeout is hardcoded to 10ms for all RTC reads, but in some
> contexts this might not be enough time. Add a timeout parameter to
> mc146818_get_time() and mc146818_get_time_callback().
> Make all callers use 10ms to ensure no functional changes.
>
> Signed-off-by: Mario Limonciello <mario.limonciello@xxxxxxx>

Fixes: ec5895c0f2d8 ("rtc: mc146818-lib: extract mc146818_avoid_UIP")

If you would like to Cc: stable this patch,

commit d2a632a8a117 ("rtc: mc146818-lib: reduce RTC_UIP polling period")

is a prerequisite.

> ---
> arch/alpha/kernel/rtc.c | 2 +-
> arch/x86/kernel/hpet.c | 2 +-
> arch/x86/kernel/rtc.c | 2 +-
> drivers/base/power/trace.c | 2 +-
> drivers/rtc/rtc-cmos.c | 6 +++---
> drivers/rtc/rtc-mc146818-lib.c | 31 +++++++++++++++++++++++--------
> include/linux/mc146818rtc.h | 3 ++-
> 7 files changed, 32 insertions(+), 16 deletions(-)
>
[snip]
> --- a/drivers/rtc/rtc-mc146818-lib.c
> +++ b/drivers/rtc/rtc-mc146818-lib.c
> @@ -8,26 +8,29 @@
> #include <linux/acpi.h>
> #endif
>
> +#define UIP_RECHECK_DELAY 100 /* usec */
> +
> /*
> * Execute a function while the UIP (Update-in-progress) bit of the RTC is
> - * unset.
> + * unset. The timeout is configurable by the caller in ms.
> *
> * Warning: callback may be executed more then once.
> */
> bool mc146818_avoid_UIP(void (*callback)(unsigned char seconds, void *param),
> + int timeout,
> void *param)
> {
> int i;
> unsigned long flags;
> unsigned char seconds;
>
> - for (i = 0; i < 100; i++) {
> + for (i = 0; i < USEC_PER_MSEC / UIP_RECHECK_DELAY * timeout; i++) {
> spin_lock_irqsave(&rtc_lock, flags);
>
> /*
> * Check whether there is an update in progress during which the
> * readout is unspecified. The maximum update time is ~2ms. Poll
> - * every 100 usec for completion.
> + * for completion.
> *
> * Store the second value before checking UIP so a long lasting
> * NMI which happens to hit after the UIP check cannot make
> @@ -37,7 +40,7 @@ bool mc146818_avoid_UIP(void (*callback)(unsigned char seconds, void *param),
>
> if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) {
> spin_unlock_irqrestore(&rtc_lock, flags);
> - udelay(100);
> + udelay(UIP_RECHECK_DELAY);
> continue;
> }
>
> @@ -56,7 +59,7 @@ bool mc146818_avoid_UIP(void (*callback)(unsigned char seconds, void *param),
> */
> if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) {
> spin_unlock_irqrestore(&rtc_lock, flags);
> - udelay(100);
> + udelay(UIP_RECHECK_DELAY);
> continue;
> }
>

I think that when reading the RTC is not finished in 100ms or so
(irrespective of the timeout parameter), the code should log
a warning / an error message.

Greetings,

Mateusz