svn commit: r333994 - in head/sys: dev/acpica kern sys

Andriy Gapon avg at FreeBSD.org
Mon May 21 20:23:05 UTC 2018


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


More information about the svn-src-all mailing list