From owner-freebsd-acpi@freebsd.org Sat Sep 19 15:16:54 2015 Return-Path: Delivered-To: freebsd-acpi@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 0AB84A051EB for ; Sat, 19 Sep 2015 15:16:54 +0000 (UTC) (envelope-from smithi@nimnet.asn.au) Received: from sola.nimnet.asn.au (paqi.nimnet.asn.au [115.70.110.159]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1AD86118E; Sat, 19 Sep 2015 15:16:52 +0000 (UTC) (envelope-from smithi@nimnet.asn.au) Received: from localhost (localhost [127.0.0.1]) by sola.nimnet.asn.au (8.14.2/8.14.2) with ESMTP id t8JFGhjp041078; Sun, 20 Sep 2015 01:16:43 +1000 (EST) (envelope-from smithi@nimnet.asn.au) Date: Sun, 20 Sep 2015 01:16:43 +1000 (EST) From: Ian Smith To: Jung-uk Kim cc: Colin Percival , "freebsd-acpi@freebsd.org" Subject: Re: disabling sleep when shutting down In-Reply-To: <55FC4F13.3090603@FreeBSD.org> Message-ID: <20150920004041.J29510@sola.nimnet.asn.au> References: <55FA3848.7090802@freebsd.org> <55FB233D.2080000@FreeBSD.org> <55FB48E3.20401@freebsd.org> <55FC4F13.3090603@FreeBSD.org> MIME-Version: 1.0 Content-Type: MULTIPART/Mixed; BOUNDARY=------------080505010706070807030101 Content-ID: <20150920004041.U29510@sola.nimnet.asn.au> X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 19 Sep 2015 15:16:54 -0000 This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. --------------080505010706070807030101 Content-Type: TEXT/PLAIN; CHARSET=US-ASCII Content-ID: <20150920004041.B29510@sola.nimnet.asn.au> On Fri, 18 Sep 2015 13:51:15 -0400, Jung-uk Kim wrote: > On 09/17/2015 19:12, Colin Percival wrote: > > On 09/17/15 13:31, Jung-uk Kim wrote: > >> On 09/16/2015 23:49, Colin Percival wrote: > >>> I ran into an interesting glitch recently: I told my laptop to > >>> shut down, then closed the lid... and it promptly went into S3. > >>> When I opened the lid a couple days later, it resumed... and > >>> then finished the shutdown which it had started 2 days > >>> earlier. > >> > >> Please try the attached patch. > > > > No, this doesn't do what I wanted. It might be a good idea anyway, > > but your patch only disables suspend once the kernel is trying to > > reboot; what I want is to disable suspend a bit earlier -- once > > rc.shutdown is running and the userland is trying to shut down, > > because at that point unless something breaks horribly we're *about > > to* tell the kernel to shut down even though we haven't gotten > > there quite yet. > > Okay. The attached patch is a quick-and-dirty & untested hack for you. That looks .. comprehensive, given that it's run when rc.shutdown is called by init(8), if I'm correctly following the train of events from shutdown through init (unless -o) and then halt(8) or reboot(8). Am I right assuming that if one ran say 'shutdown -p +2 [message]' then suspending would only be blocked after that interval has elapsed? And with 'shutdown [-p|-h|-r] now' is there any appreciable delay (like waiting on anything) before launching rc.shutdown? i.e. anything that aforesaid fast lid-slammer might beat? "Five minutes before shutdown, or immediately if shutdown is in less than 5 minutes, logins are disabled by creating /var/run/nologin and copying the warning message there." Guess I'm still wondering if blocking suspend from shutdown, perhaps in a similar timeframe, might better prevent suspend-during-shutdown? Aside perhaps, a point about acpiconf(8) I discovered tonight: every version of the man page since at least 5.5 states that S5 (soft off) is an option for -s. That was true at 5.5, however acpiconf.c at least from 8.2 through 9.3 to HEAD (checked just now) allows only S1 to S4. Noticed that because I was trying to find what else apart from shutdown, halt -p and the power button could initiate a poweroff halt. Are there other ways, apart from doing it like acpiconf does? cheers, Ian --------------080505010706070807030101 Content-Type: TEXT/X-PATCH; NAME=acpi.diff Content-ID: <20150920004041.P29510@sola.nimnet.asn.au> Content-Description: Content-Disposition: ATTACHMENT; FILENAME=acpi.diff Index: etc/rc.shutdown =================================================================== --- etc/rc.shutdown (revision 287937) +++ etc/rc.shutdown (working copy) @@ -43,6 +43,9 @@ HOME=/ PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin export HOME PATH +# Temporarily block any suspend requests. +acpiconf -b 1 >/dev/null 2>&1 + . /etc/rc.subr load_rc_config 'XXX' @@ -109,5 +112,8 @@ fi # Insert other shutdown procedures here +# Unblock suspend requests. +acpiconf -b 0 >/dev/null 2>&1 + echo '.' exit 0 Index: sys/dev/acpica/acpi.c =================================================================== --- sys/dev/acpica/acpi.c (revision 287937) +++ sys/dev/acpica/acpi.c (working copy) @@ -98,6 +98,9 @@ struct callout acpi_sleep_timer; /* Bitmap of device quirks. */ int acpi_quirks; +/* Block suspend requests. */ +static int acpi_sleep_blocked; + /* Supported sleep states. */ static BOOLEAN acpi_sleep_states[ACPI_S_STATE_COUNT]; @@ -2574,10 +2577,12 @@ acpi_ReqSleepState(struct acpi_softc *sc, int stat 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 explicitly disabled, just return. + */ + if (rebooting || sc->acpi_next_sstate != 0 || acpi_sleep_blocked) return (0); - } /* Wait until sleep is enabled. */ while (sc->acpi_sleep_disabled) { @@ -3568,6 +3573,9 @@ acpiioctl(struct cdev *dev, u_long cmd, caddr_t ad error = *(int *)addr; error = acpi_AckSleepState(sc->acpi_clone, error); break; + case ACPIIO_BLKSLPSTATE: + acpi_sleep_blocked = *(int *)addr; + break; case ACPIIO_SETSLPSTATE: /* DEPRECATED */ state = *(int *)addr; if (state < ACPI_STATE_S0 || state > ACPI_S_STATES_MAX) Index: sys/dev/acpica/acpiio.h =================================================================== --- sys/dev/acpica/acpiio.h (revision 287937) +++ sys/dev/acpica/acpiio.h (working copy) @@ -41,6 +41,9 @@ /* Allow suspend to continue (0) or abort it (errno). */ #define ACPIIO_ACKSLPSTATE _IOW('P', 5, int) +/* Allow suspend request (0) or block it. */ +#define ACPIIO_BLKSLPSTATE _IOW('P', 6, int) + struct acpi_battinfo { int cap; /* percent */ int min; /* remaining time (in minutes) */ Index: usr.sbin/acpi/acpiconf/acpiconf.8 =================================================================== --- usr.sbin/acpi/acpiconf/acpiconf.8 (revision 287937) +++ usr.sbin/acpi/acpiconf/acpiconf.8 (working copy) @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 10, 2014 +.Dd September 18, 2015 .Dt ACPICONF 8 .Os .Sh NAME @@ -35,6 +35,7 @@ .Nd control ACPI power management .Sh SYNOPSIS .Nm +.Op Fl b Ar block .Op Fl h .Op Fl i Ar batt .Op Fl k Ar ack @@ -45,7 +46,10 @@ The utility allows the user control of the ACPI power management functions. The following command-line options are recognized: -.Bl -tag -width ".Fl s Ar type" +.Bl -tag -width ".Fl b Ar block" +.It Fl b Ar block +Block or unblock suspend requests using the argument provided. +.Sy Most users should not use this option directly. .It Fl h Displays a summary of available options. .It Fl i Ar batt Index: usr.sbin/acpi/acpiconf/acpiconf.c =================================================================== --- usr.sbin/acpi/acpiconf/acpiconf.c (revision 287937) +++ usr.sbin/acpi/acpiconf/acpiconf.c (working copy) @@ -77,6 +77,17 @@ acpi_sleep_ack(int err_val) err(EX_IOERR, "ack sleep type failed"); } +/* Block or unblock suspend requests. */ +static void +acpi_sleep_block(int block) +{ + int ret; + + ret = ioctl(acpifd, ACPIIO_BLKSLPSTATE, &block); + if (ret != 0) + err(EX_IOERR, "%sblock sleep failed", block ? "" : "un"); +} + /* should be a acpi define, but doesn't appear to be */ #define UNKNOWN_CAP 0xffffffff #define UNKNOWN_VOLTAGE 0xffffffff @@ -213,8 +224,11 @@ main(int argc, char *argv[]) sleep_type = -1; acpi_init(); - while ((c = getopt(argc, argv, "hi:k:s:")) != -1) { + while ((c = getopt(argc, argv, "b:hi:k:s:")) != -1) { switch (c) { + case 'b': + acpi_sleep_block(atoi(optarg)); + break; case 'i': acpi_battinfo(atoi(optarg)); break; --------------080505010706070807030101 Content-Type: TEXT/PLAIN; CHARSET=us-ascii Content-ID: <20150920004041.U29510@sola.nimnet.asn.au> Content-Description: Content-Disposition: INLINE _______________________________________________ freebsd-acpi@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-acpi To unsubscribe, send any mail to "freebsd-acpi-unsubscribe@freebsd.org" --------------080505010706070807030101--