Author: avg
Date: Mon May 21 20:23:04 2018
New Revision: 333994
URL: https://svnweb.freebsd.org/changeset/base/333994

Log:
  stop and restart kernel event timers in the suspend / resume cycle
  
  I have a system that is very unstable after resuming from suspend-to-RAM
  but only if HPET is used as the event timer.  The theory is that SMM
  code / firmware could be enabling HPET for its own uses and unexpected
  interrupts cause a trouble for it.  Originally I wanted to solve the
  problem in hpet_suspend() method, but that was insufficient as the event
  timer could get reprogrammed again.
  
  So, it's better, for my case and in general, to stop the event timer(s)
  before entering the hardware suspend.
  
  MFC after:    4 weeks
  Differential Revision: https://reviews.freebsd.org/D15413

Modified:
  head/sys/dev/acpica/acpi.c
  head/sys/kern/kern_clocksource.c
  head/sys/sys/systm.h

Modified: head/sys/dev/acpica/acpi.c
==============================================================================
--- head/sys/dev/acpica/acpi.c  Mon May 21 20:20:28 2018        (r333993)
+++ head/sys/dev/acpica/acpi.c  Mon May 21 20:23:04 2018        (r333994)
@@ -2958,6 +2958,7 @@ acpi_EnterSleepState(struct acpi_softc *sc, int state)
     if (sc->acpi_sleep_delay > 0)
        DELAY(sc->acpi_sleep_delay * 1000000);
 
+    suspendclock();
     intr = intr_disable();
     if (state != ACPI_STATE_S1) {
        sleep_result = acpi_sleep_machdep(sc, state);
@@ -3028,6 +3029,8 @@ acpi_EnterSleepState(struct acpi_softc *sc, int state)
      * process.  This handles both the error and success cases.
      */
 backout:
+    if (slp_state >= ACPI_SS_SLP_PREP)
+       resumeclock();
     if (slp_state >= ACPI_SS_GPE_SET) {
        acpi_wake_prep_walk(state);
        sc->acpi_sstate = ACPI_STATE_S0;

Modified: head/sys/kern/kern_clocksource.c
==============================================================================
--- head/sys/kern/kern_clocksource.c    Mon May 21 20:20:28 2018        
(r333993)
+++ head/sys/kern/kern_clocksource.c    Mon May 21 20:23:04 2018        
(r333994)
@@ -698,6 +698,22 @@ cpu_initclocks_ap(void)
        spinlock_exit();
 }
 
+void
+suspendclock(void)
+{
+       ET_LOCK();
+       configtimer(0);
+       ET_UNLOCK();
+}
+
+void
+resumeclock(void)
+{
+       ET_LOCK();
+       configtimer(1);
+       ET_UNLOCK();
+}
+
 /*
  * Switch to profiling clock rates.
  */

Modified: head/sys/sys/systm.h
==============================================================================
--- head/sys/sys/systm.h        Mon May 21 20:20:28 2018        (r333993)
+++ head/sys/sys/systm.h        Mon May 21 20:23:04 2018        (r333994)
@@ -333,6 +333,8 @@ void        startprofclock(struct proc *);
 void   stopprofclock(struct proc *);
 void   cpu_startprofclock(void);
 void   cpu_stopprofclock(void);
+void   suspendclock(void);
+void   resumeclock(void);
 sbintime_t     cpu_idleclock(void);
 void   cpu_activeclock(void);
 void   cpu_new_callout(int cpu, sbintime_t bt, sbintime_t bt_opt);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to