> Date: Fri, 2 Sep 2016 19:45:39 +0200 > From: Christian Weisgerber <na...@mips.inka.de> > > I would like to sync the system time periodically back to the RTC. > > Currently we update the RTC > (1) when the time is set with clock_settime() or settimeofday(), which > never happens for a typical ntpd setup; > (2) before suspend; > (3) when the system is properly shut down. > > This means if a machine has been running for a few months and it > loses power, it may come back up with the time way off, leading to > all sorts of problems. > > Patch below, originally inspired by FreeBSD, and incorporating various > suggestions from kettenis@ when I first proposed this: > > * A timeout schedules a task that actually calls resettodr(). > * The RTC is synced back every 30 minutes. > * The timeout and task are removed before shutdown and suspend; > the timeout is started up again on resume. > * Suspend/resume paths: acpi, i386 apm, loongson "apm". > > Comments?
looks good to me > Index: arch/i386/i386/apm.c > =================================================================== > RCS file: /cvs/src/sys/arch/i386/i386/apm.c,v > retrieving revision 1.114 > diff -u -p -r1.114 apm.c > --- arch/i386/i386/apm.c 28 Sep 2015 18:36:36 -0000 1.114 > +++ arch/i386/i386/apm.c 2 Sep 2016 17:28:23 -0000 > @@ -248,6 +248,7 @@ apm_suspend(int state) > #if NWSDISPLAY > 0 > wsdisplay_suspend(); > #endif /* NWSDISPLAY > 0 */ > + stop_periodic_resettodr(); > config_suspend_all(DVACT_QUIESCE); > bufq_quiesce(); > > @@ -284,6 +285,7 @@ apm_suspend(int state) > bufq_restart(); > > config_suspend_all(DVACT_WAKEUP); > + start_periodic_resettodr(); > > #if NWSDISPLAY > 0 > wsdisplay_resume(); > Index: arch/loongson/dev/apm.c > =================================================================== > RCS file: /cvs/src/sys/arch/loongson/dev/apm.c,v > retrieving revision 1.29 > diff -u -p -r1.29 apm.c > --- arch/loongson/dev/apm.c 28 Sep 2015 18:36:36 -0000 1.29 > +++ arch/loongson/dev/apm.c 2 Sep 2016 17:28:23 -0000 > @@ -373,6 +373,7 @@ apm_suspend(int state) > wsdisplay_suspend(); > #endif > > + stop_periodic_resettodr(); > resettodr(); > > config_suspend_all(DVACT_QUIESCE); > @@ -422,6 +423,8 @@ apm_suspend(int state) > bufq_restart(); > > config_suspend_all(DVACT_WAKEUP); > + > + start_periodic_resettodr(); > > #if NWSDISPLAY > 0 > wsdisplay_resume(); > Index: dev/acpi/acpi.c > =================================================================== > RCS file: /cvs/src/sys/dev/acpi/acpi.c,v > retrieving revision 1.314 > diff -u -p -r1.314 acpi.c > --- dev/acpi/acpi.c 31 Aug 2016 15:40:42 -0000 1.314 > +++ dev/acpi/acpi.c 2 Sep 2016 17:28:23 -0000 > @@ -2383,6 +2383,8 @@ acpi_sleep_state(struct acpi_softc *sc, > rw_enter_write(&sc->sc_lck); > #endif /* NWSDISPLAY > 0 */ > > + stop_periodic_resettodr(); > + > #ifdef HIBERNATE > if (state == ACPI_STATE_S4) { > uvmpd_hibernate(); > @@ -2482,6 +2484,8 @@ fail_alloc: > hibernate_resume_bufcache(); > } > #endif /* HIBERNATE */ > + > + start_periodic_resettodr(); > > #if NWSDISPLAY > 0 > rw_exit_write(&sc->sc_lck); > Index: kern/init_main.c > =================================================================== > RCS file: /cvs/src/sys/kern/init_main.c,v > retrieving revision 1.254 > diff -u -p -r1.254 init_main.c > --- kern/init_main.c 2 Sep 2016 12:17:33 -0000 1.254 > +++ kern/init_main.c 2 Sep 2016 17:28:23 -0000 > @@ -551,6 +551,8 @@ main(void *framep) > pool_gc_pages(NULL); > #endif > > + start_periodic_resettodr(); > + > /* > * proc0: nothing to do, back to sleep > */ > Index: kern/kern_time.c > =================================================================== > RCS file: /cvs/src/sys/kern/kern_time.c,v > retrieving revision 1.97 > diff -u -p -r1.97 kern_time.c > --- kern/kern_time.c 28 Apr 2016 20:11:20 -0000 1.97 > +++ kern/kern_time.c 2 Sep 2016 17:28:24 -0000 > @@ -41,6 +41,8 @@ > #include <sys/vnode.h> > #include <sys/signalvar.h> > #include <sys/pledge.h> > +#include <sys/task.h> > +#include <sys/timeout.h> > #include <sys/timetc.h> > > #include <sys/mount.h> > @@ -785,3 +787,37 @@ ppsratecheck(struct timeval *lasttime, i > return (rv); > } > > + > +#define RESETTODR_PERIOD 1800 > + > +void periodic_resettodr(void *); > +void perform_resettodr(void *); > + > +struct timeout resettodr_to = TIMEOUT_INITIALIZER(periodic_resettodr, NULL); > +struct task resettodr_task = TASK_INITIALIZER(perform_resettodr, NULL); > + > +void > +periodic_resettodr(void *arg __unused) > +{ > + task_add(systq, &resettodr_task); > +} > + > +void > +perform_resettodr(void *arg __unused) > +{ > + resettodr(); > + timeout_add_sec(&resettodr_to, RESETTODR_PERIOD); > +} > + > +void > +start_periodic_resettodr(void) > +{ > + timeout_add_sec(&resettodr_to, RESETTODR_PERIOD); > +} > + > +void > +stop_periodic_resettodr(void) > +{ > + timeout_del(&resettodr_to); > + task_del(systq, &resettodr_task); > +} > Index: kern/kern_xxx.c > =================================================================== > RCS file: /cvs/src/sys/kern/kern_xxx.c,v > retrieving revision 1.29 > diff -u -p -r1.29 kern_xxx.c > --- kern/kern_xxx.c 5 Dec 2015 10:11:53 -0000 1.29 > +++ kern/kern_xxx.c 2 Sep 2016 17:28:24 -0000 > @@ -65,6 +65,8 @@ reboot(int howto) > { > KASSERT((howto & RB_NOSYNC) || curproc != NULL); > > + stop_periodic_resettodr(); > + > boot(howto); > /* NOTREACHED */ > } > Index: sys/systm.h > =================================================================== > RCS file: /cvs/src/sys/sys/systm.h,v > retrieving revision 1.114 > diff -u -p -r1.114 systm.h > --- sys/systm.h 1 Sep 2016 12:50:53 -0000 1.114 > +++ sys/systm.h 2 Sep 2016 17:28:24 -0000 > @@ -232,6 +232,9 @@ void startprofclock(struct process *); > void stopprofclock(struct process *); > void setstatclockrate(int); > > +void start_periodic_resettodr(void); > +void stop_periodic_resettodr(void); > + > struct sleep_state; > void sleep_setup(struct sleep_state *, const volatile void *, int, > const char *); > -- > Christian "naddy" Weisgerber na...@mips.inka.de > >