svn commit: r277796 - in head/sys: dev/acpica dev/syscons dev/vt sys
Andriy Gapon
avg at FreeBSD.org
Tue Jan 27 17:33:20 UTC 2015
Author: avg
Date: Tue Jan 27 17:33:18 2015
New Revision: 277796
URL: https://svnweb.freebsd.org/changeset/base/277796
Log:
hook userland threads suspend + resume into acpi suspend code
Also, split power_suspend into power_suspend and power_suspend_early.
power_suspend_early is called before the userland is frozen.
power_suspend is called after the userland is frozen.
Currently only VT switching is hooked to power_suspend_early.
This is needed because switching away from X server requires its
cooperation, so obviously X server must not be frozen when that happens.
Freezing userland during ACPI suspend is useful because not all drivers
correctly handle suspension concurrent with other activity. This is
especially applicable to drivers ported from other operating systems
that suspend all software activity between placing drivers and hardware
into suspended state.
In particular drm2/radeon (radeonkms) depends on the described
procedure. The driver does not have any internal synchronization
between suspension activities and processing of userland requests.
Many thanks to kib for the code that allows to freeze and thaw all
userland threads.
Note that ideally we also need to park / inhibit (non-special) kernel
threads as well to ensure that they do not call into drivers.
MFC after: 17 days
Modified:
head/sys/dev/acpica/acpi.c
head/sys/dev/syscons/syscons.c
head/sys/dev/vt/vt_core.c
head/sys/sys/eventhandler.h
Modified: head/sys/dev/acpica/acpi.c
==============================================================================
--- head/sys/dev/acpica/acpi.c Tue Jan 27 15:28:46 2015 (r277795)
+++ head/sys/dev/acpica/acpi.c Tue Jan 27 17:33:18 2015 (r277796)
@@ -2749,6 +2749,8 @@ acpi_EnterSleepState(struct acpi_softc *
return_ACPI_STATUS (AE_OK);
}
+ EVENTHANDLER_INVOKE(power_suspend_early);
+ stop_all_proc();
EVENTHANDLER_INVOKE(power_suspend);
if (smp_started) {
@@ -2892,6 +2894,8 @@ backout:
thread_unlock(curthread);
}
+ resume_all_proc();
+
EVENTHANDLER_INVOKE(power_resume);
/* Allow another sleep request after a while. */
Modified: head/sys/dev/syscons/syscons.c
==============================================================================
--- head/sys/dev/syscons/syscons.c Tue Jan 27 15:28:46 2015 (r277795)
+++ head/sys/dev/syscons/syscons.c Tue Jan 27 17:33:18 2015 (r277796)
@@ -549,7 +549,7 @@ sc_attach_unit(int unit, int flags)
/* Register suspend/resume/shutdown callbacks for the kernel console. */
if (sc_console_unit == unit) {
- EVENTHANDLER_REGISTER(power_suspend, scsuspend, NULL,
+ EVENTHANDLER_REGISTER(power_suspend_early, scsuspend, NULL,
EVENTHANDLER_PRI_ANY);
EVENTHANDLER_REGISTER(power_resume, scresume, NULL,
EVENTHANDLER_PRI_ANY);
Modified: head/sys/dev/vt/vt_core.c
==============================================================================
--- head/sys/dev/vt/vt_core.c Tue Jan 27 15:28:46 2015 (r277795)
+++ head/sys/dev/vt/vt_core.c Tue Jan 27 17:33:18 2015 (r277796)
@@ -2556,8 +2556,8 @@ vt_upgrade(struct vt_device *vd)
vd->vd_timer_armed = 1;
/* Register suspend/resume handlers. */
- EVENTHANDLER_REGISTER(power_suspend, vt_suspend_handler, vd,
- EVENTHANDLER_PRI_ANY);
+ EVENTHANDLER_REGISTER(power_suspend_early, vt_suspend_handler,
+ vd, EVENTHANDLER_PRI_ANY);
EVENTHANDLER_REGISTER(power_resume, vt_resume_handler, vd,
EVENTHANDLER_PRI_ANY);
}
Modified: head/sys/sys/eventhandler.h
==============================================================================
--- head/sys/sys/eventhandler.h Tue Jan 27 15:28:46 2015 (r277795)
+++ head/sys/sys/eventhandler.h Tue Jan 27 17:33:18 2015 (r277796)
@@ -182,6 +182,7 @@ EVENTHANDLER_DECLARE(shutdown_final, shu
typedef void (*power_change_fn)(void *);
EVENTHANDLER_DECLARE(power_resume, power_change_fn);
EVENTHANDLER_DECLARE(power_suspend, power_change_fn);
+EVENTHANDLER_DECLARE(power_suspend_early, power_change_fn);
/* Low memory event */
typedef void (*vm_lowmem_handler_t)(void *, int);
More information about the svn-src-head
mailing list