> 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
> 
> 

Reply via email to