Re: [PATCH] rtc: adapt allowed RTC update error

From: Jason Gunthorpe
Date: Wed Dec 02 2020 - 15:55:39 EST


On Wed, Dec 02, 2020 at 08:21:00PM +0100, Thomas Gleixner wrote:
> On Wed, Dec 02 2020 at 12:27, Jason Gunthorpe wrote:
> > On Wed, Dec 02, 2020 at 02:44:53PM +0100, Thomas Gleixner wrote:
> >> if (IS_ENABLED(CONFIG_GENERIC_CMOS_UPDATE) ||
> >> IS_ENABLED(CONFIG_RTC_SYSTOHC))
> >> - queue_delayed_work(system_power_efficient_wq, &sync_work, 0);
> >> + queue_work(system_power_efficient_wq, &sync_work);
> >
> > As Miroslav noted, probably the right thing to do here is to reset the
> > hrtimer and remove the sync_work? I think this code was to expedite an
> > RTC sync when NTP fixes the clock on boot.
>
> This has two purposes:
>
> 1) Initiating the update on boot once ntp is synced.
>
> 2) Reinitiating the sync after ntp lost sync and the work did not
> reschedule itself because it observed !ntp_synced().
>
> In both cases it's highly unlikely that the write actually happens when
> the work is queued because do_adjtimex() would have to be exactly around
> the valid update window.

Yes

> So it will not write immediately. It will run through at least one
> retry.

Right, bascially this is scheduling a WQ to do sched_sync_hw_clock()
which will only call hrtimer_start() - seems like jsut calling
hrtimer_start instead of queue_work above would be equivilant

> I don't think the timer should be canceled if the ntp_synced() state did
> not change. Otherwise every do_adtimex() call will cancel/restart
> it, which does not make sense. Lemme stare at it some more.

That makes sense, being conditional on the STA_UNSYNC prior to doing
any hrtimer_start seems OK?

> > Also x86 needs a touch, it already has RTC lib, no idea why it also
> > provides this old path too
>
> Because nobody had the stomach and/or cycles to touch it :)

Hahaha yes.. I vaugely remember looking at this once..

Lets see:

arch/x86/kernel/kvmclock.c: x86_platform.set_wallclock = kvm_set_wallclock;
arch/x86/kernel/x86_init.c: x86_platform.set_wallclock = set_rtc_noop;
arch/x86/xen/time.c: x86_platform.set_wallclock = xen_set_wallclock;
arch/x86/xen/time.c: x86_platform.set_wallclock = xen_set_wallclock;
All returns -ENODEV/EINVAL

arch/x86/kernel/x86_init.c: .set_wallclock = mach_set_rtc_mmss,
This is already rtclib under drivers/rtc/rtc-mc146818-lib.c

I suppose the issue here is the rtclib driver only binds via PNP and
very old x86 systems won't have the PNP tables? It seems doable to
check for a PNP device after late init and manually create a
platform_device for the RTC

arch/x86/platform/intel-mid/intel_mid_vrtc.c: x86_platform.set_wallclock = vrtc_set_mmss;
This is also already in rtclib under rtc-mrst.c, and this is already
wired to create the rtc platform device during init

So it is very close now to be able to delete all this for x86. Do you
know of something I've missed?

> > I wonder if the cmos path could be killed off under the dead HW
> > principle?
>
> Unfortunately that code path is not that dead on x86. You need to fix
> all the (ab)users first. :)

Assuming x86 can be resolved as above, that leaves two 20 year old MIPS
platforms and the PPC list from before. ARM is gone compared to last
time I looked! Progress :)

Thanks,
Jason