Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 1 Oct 2015 10:52:27 +0000 (UTC)
From:      Colin Percival <cperciva@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r288446 - in head: sbin/init sys/dev/acpica sys/kern sys/sys
Message-ID:  <201510011052.t91AqR38036244@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cperciva
Date: Thu Oct  1 10:52:26 2015
New Revision: 288446
URL: https://svnweb.freebsd.org/changeset/base/288446

Log:
  Disable suspend when we're shutting down.  This solves the "tell FreeBSD
  to shut down; close laptop lid" scenario which otherwise tended to end
  with a laptop overheating or the battery dying.
  
  The implementation uses a new sysctl, kern.suspend_blocked; init(8) sets
  this while rc.suspend runs, and the ACPI sleep code ignores requests while
  the sysctl is set.
  
  Discussed on:	freebsd-acpi (35 emails)
  MFC after:	1 week

Modified:
  head/sbin/init/init.c
  head/sys/dev/acpica/acpi.c
  head/sys/kern/kern_shutdown.c
  head/sys/sys/systm.h

Modified: head/sbin/init/init.c
==============================================================================
--- head/sbin/init/init.c	Thu Oct  1 10:43:40 2015	(r288445)
+++ head/sbin/init/init.c	Thu Oct  1 10:52:26 2015	(r288446)
@@ -1487,6 +1487,15 @@ static state_func_t
 death(void)
 {
 	session_t *sp;
+	int block, blocked;
+	size_t len;
+
+	/* Temporarily block suspend. */
+	len = sizeof(blocked);
+	block = 1;
+	if (sysctlbyname("kern.suspend_blocked", &blocked, &len,
+	    &block, sizeof(block)) == -1)
+		blocked = 0;
 
 	/*
 	 * Also revoke the TTY here.  Because runshutdown() may reopen
@@ -1503,6 +1512,11 @@ death(void)
 	/* Try to run the rc.shutdown script within a period of time */
 	runshutdown();
 
+	/* Unblock suspend if we blocked it. */
+	if (!blocked)
+		sysctlbyname("kern.suspend_blocked", NULL, NULL,
+		    &blocked, sizeof(blocked));
+
 	return (state_func_t) death_single;
 }
 

Modified: head/sys/dev/acpica/acpi.c
==============================================================================
--- head/sys/dev/acpica/acpi.c	Thu Oct  1 10:43:40 2015	(r288445)
+++ head/sys/dev/acpica/acpi.c	Thu Oct  1 10:52:26 2015	(r288446)
@@ -2574,8 +2574,11 @@ acpi_ReqSleepState(struct acpi_softc *sc
     if (!acpi_sleep_states[state])
 	return (EOPNOTSUPP);
 
-    /* If a suspend request is already in progress, just return. */
-    if (sc->acpi_next_sstate != 0) {
+    /*
+     * If a reboot/shutdown/suspend request is already in progress or
+     * suspend is blocked due to an upcoming shutdown, just return.
+     */
+    if (rebooting || sc->acpi_next_sstate != 0 || suspend_blocked) {
 	return (0);
     }
 

Modified: head/sys/kern/kern_shutdown.c
==============================================================================
--- head/sys/kern/kern_shutdown.c	Thu Oct  1 10:43:40 2015	(r288445)
+++ head/sys/kern/kern_shutdown.c	Thu Oct  1 10:52:26 2015	(r288446)
@@ -137,6 +137,10 @@ static int show_busybufs = 1;
 SYSCTL_INT(_kern_shutdown, OID_AUTO, show_busybufs, CTLFLAG_RW,
 	&show_busybufs, 0, "");
 
+int suspend_blocked = 0;
+SYSCTL_INT(_kern, OID_AUTO, suspend_blocked, CTLFLAG_RW,
+	&suspend_blocked, 0, "Block suspend due to a pending shutdown");
+
 /*
  * Variable panicstr contains argument to first call to panic; used as flag
  * to indicate that the kernel has already called panic.

Modified: head/sys/sys/systm.h
==============================================================================
--- head/sys/sys/systm.h	Thu Oct  1 10:43:40 2015	(r288445)
+++ head/sys/sys/systm.h	Thu Oct  1 10:52:26 2015	(r288446)
@@ -46,6 +46,7 @@
 #include <sys/stdint.h>		/* for people using printf mainly */
 
 extern int cold;		/* nonzero if we are doing a cold boot */
+extern int suspend_blocked;	/* block suspend due to pending shutdown */
 extern int rebooting;		/* kern_reboot() has been called. */
 extern const char *panicstr;	/* panic message */
 extern char version[];		/* system version */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201510011052.t91AqR38036244>