At the last hackathon I observed high elapsed time when the unhibernate
bsd.booted kernel attaches unneccessary drivers, and then detatches a
vast number of them when suspending to bounce to the old image.
This diff skips attaching those devices. The current list is all tape
and network devices (based upon DV_TAPE and DV_NET), plus vmm, azalia,
and usb sub-devices (based upon a new CD_SKIPHIBERNATE flag). The usb
sub-devices in particular make a big difference. Adding additional
devices to the list only requires putting CD_SKIPHIBERNATE into struct
cfdriver.
To test, upgrade the bootblocks -- which must pass a new boothowto flag
indicating the unhibernate operation -- previously the bsd.booted kernel
was unaware of the circumstances until inspecting swap for a unhib signature,
but this is too late (obviously it is after device configure):
cd /usr/src/sys/arch/amd64/stand
make && make install
installboot -v sd0 (or whatever)
Then install a new kernel, and perform an unhibernate cycle.
Surface go2 has a pretty fast BIOS and many iic + usb devices, so this
cuts unhibernate elapsed time by roughly a third. The other laptop I
trialed this on, x1nano, has fewer devices to skip so the speedup is
less dramatic.
I had some weird experiences developing this. Consider reverting the
sys/dev/usb subdirectory flagging before reporting a problem, because
I suspect my weird problems came from those drivers.
Index: kern/subr_autoconf.c
===================================================================
RCS file: /cvs/src/sys/kern/subr_autoconf.c,v
retrieving revision 1.94
diff -u -p -u -r1.94 subr_autoconf.c
--- kern/subr_autoconf.c 30 Dec 2019 23:56:26 -0000 1.94
+++ kern/subr_autoconf.c 23 Oct 2021 20:42:16 -0000
@@ -51,6 +51,7 @@
#include <sys/queue.h>
#include <sys/mutex.h>
#include <sys/atomic.h>
+#include <sys/reboot.h>
#include "hotplug.h"
#include "mpath.h"
@@ -188,7 +189,7 @@ config_search(cfmatch_t fn, struct devic
m.parent = parent;
m.match = NULL;
m.aux = aux;
- m.indirect = parent && parent->dv_cfdata->cf_driver->cd_indirect;
+ m.indirect = parent && (parent->dv_cfdata->cf_driver->cd_mode &
CD_INDIRECT);
m.pri = 0;
for (cf = cfdata; cf->cf_driver; cf++) {
@@ -202,6 +203,14 @@ config_search(cfmatch_t fn, struct devic
if (cf->cf_fstate == FSTATE_DNOTFOUND ||
cf->cf_fstate == FSTATE_DSTAR)
continue;
+ if (boothowto & RB_UNHIBERNATE) {
+ if (cf->cf_driver->cd_mode & CD_SKIPHIBERNATE)
+ continue;
+ if (cf->cf_driver->cd_class == DV_IFNET)
+ continue;
+ if (cf->cf_driver->cd_class == DV_TAPE)
+ continue;
+ }
for (p = cf->cf_parents; *p >= 0; p++)
if (parent->dv_cfdata == &cfdata[*p])
mapply(&m, cf);
@@ -237,7 +246,7 @@ config_scan(cfscan_t fn, struct device *
void *match;
int indirect;
- indirect = parent && parent->dv_cfdata->cf_driver->cd_indirect;
+ indirect = parent && (parent->dv_cfdata->cf_driver->cd_mode &
CD_INDIRECT);
for (cf = cfdata; cf->cf_driver; cf++) {
/*
@@ -348,7 +357,7 @@ config_attach(struct device *parent, voi
autoconf_attdet++;
mtx_leave(&autoconf_attdet_mtx);
- if (parent && parent->dv_cfdata->cf_driver->cd_indirect) {
+ if (parent && (parent->dv_cfdata->cf_driver->cd_mode & CD_INDIRECT)) {
dev = match;
cf = dev->dv_cfdata;
} else {
Index: sys/device.h
===================================================================
RCS file: /cvs/src/sys/sys/device.h,v
retrieving revision 1.55
diff -u -p -u -r1.55 device.h
--- sys/device.h 10 Sep 2018 16:18:34 -0000 1.55
+++ sys/device.h 23 Oct 2021 20:42:16 -0000
@@ -136,11 +136,15 @@ struct cfattach {
#define DETACH_FORCE 0x01 /* force detachment; hardware
gone */
#define DETACH_QUIET 0x02 /* don't print a notice */
+/* For cd_mode, below */
+#define CD_INDIRECT 1
+#define CD_SKIPHIBERNATE 2
+
struct cfdriver {
void **cd_devs; /* devices found */
char *cd_name; /* device name */
enum devclass cd_class; /* device classification */
- int cd_indirect; /* indirectly configure subdevices */
+ int cd_mode; /* device type subclassification */
int cd_ndevs; /* size of cd_devs array */
};
Index: sys/reboot.h
===================================================================
RCS file: /cvs/src/sys/sys/reboot.h,v
retrieving revision 1.19
diff -u -p -u -r1.19 reboot.h
--- sys/reboot.h 23 May 2020 00:40:53 -0000 1.19
+++ sys/reboot.h 23 Oct 2021 20:42:16 -0000
@@ -58,6 +58,7 @@
#define RB_USERREQ 0x04000 /* boot() called at user request (e.g.
ddb) */
#define RB_RESET 0x08000 /* just reset, no cleanup */
#define RB_GOODRANDOM 0x10000 /* excellent random seed loaded */
+#define RB_UNHIBERNATE 0x20000 /* unhibernate */
/*
* Constants for converting boot-style device number to type,
Index: stand/boot/boot.c
===================================================================
RCS file: /cvs/src/sys/stand/boot/boot.c,v
retrieving revision 1.54
diff -u -p -u -r1.54 boot.c
--- stand/boot/boot.c 15 Jun 2020 14:43:57 -0000 1.54
+++ stand/boot/boot.c 24 Oct 2021 09:15:05 -0000
@@ -92,6 +92,7 @@ boot(dev_t bootdev)
if (bootdev_has_hibernate()) {
strlcpy(cmd.image, "/bsd.booted", sizeof(cmd.image));
printf("unhibernate detected: switching to %s\n", cmd.image);
+ cmd.boothowto |= RB_UNHIBERNATE;
}
#endif
Index: arch/amd64/amd64/vmm.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/vmm.c,v
retrieving revision 1.293
diff -u -p -u -r1.293 vmm.c
--- arch/amd64/amd64/vmm.c 13 Sep 2021 22:16:27 -0000 1.293
+++ arch/amd64/amd64/vmm.c 23 Oct 2021 20:42:16 -0000
@@ -260,7 +260,7 @@ const struct kmem_pa_mode vmm_kp_contig
};
struct cfdriver vmm_cd = {
- NULL, "vmm", DV_DULL
+ NULL, "vmm", DV_DULL, CD_SKIPHIBERNATE
};
const struct cfattach vmm_ca = {
Index: dev/pci/azalia.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/azalia.c,v
retrieving revision 1.264
diff -u -p -u -r1.264 azalia.c
--- dev/pci/azalia.c 9 Aug 2021 12:59:53 -0000 1.264
+++ dev/pci/azalia.c 23 Oct 2021 20:42:16 -0000
@@ -286,7 +286,7 @@ struct cfattach azalia_ca = {
};
struct cfdriver azalia_cd = {
- NULL, "azalia", DV_DULL
+ NULL, "azalia", DV_DULL, CD_SKIPHIBERNATE
};
struct audio_hw_if azalia_hw_if = {
Index: dev/isa/isa.c
===================================================================
RCS file: /cvs/src/sys/dev/isa/isa.c,v
retrieving revision 1.48
diff -u -p -u -r1.48 isa.c
--- dev/isa/isa.c 7 Mar 2021 06:17:03 -0000 1.48
+++ dev/isa/isa.c 23 Oct 2021 20:42:16 -0000
@@ -77,7 +77,7 @@ struct cfattach isa_ca = {
};
struct cfdriver isa_cd = {
- NULL, "isa", DV_DULL, 1
+ NULL, "isa", DV_DULL, CD_INDIRECT
};
int
Index: dev/isa/isadma.c
===================================================================
RCS file: /cvs/src/sys/dev/isa/isadma.c,v
retrieving revision 1.35
diff -u -p -u -r1.35 isadma.c
--- dev/isa/isadma.c 7 Mar 2021 06:17:03 -0000 1.35
+++ dev/isa/isadma.c 23 Oct 2021 20:42:16 -0000
@@ -89,7 +89,7 @@ struct cfattach isadma_ca = {
};
struct cfdriver isadma_cd = {
- NULL, "isadma", DV_DULL, 1
+ NULL, "isadma", DV_DULL, CD_INDIRECT
};
int
Index: dev/i2c/i2c.c
===================================================================
RCS file: /cvs/src/sys/dev/i2c/i2c.c,v
retrieving revision 1.16
diff -u -p -u -r1.16 i2c.c
--- dev/i2c/i2c.c 14 Mar 2015 03:38:47 -0000 1.16
+++ dev/i2c/i2c.c 23 Oct 2021 20:42:16 -0000
@@ -63,7 +63,7 @@ struct cfattach iic_ca = {
};
struct cfdriver iic_cd = {
- NULL, "iic", DV_DULL
+ NULL, "iic", DV_DULL, CD_SKIPHIBERNATE
};
int
Index: dev/usb/ehci.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/ehci.c,v
retrieving revision 1.214
diff -u -p -u -r1.214 ehci.c
--- dev/usb/ehci.c 11 Jan 2021 14:41:12 -0000 1.214
+++ dev/usb/ehci.c 23 Oct 2021 20:42:16 -0000
@@ -78,7 +78,7 @@
#include <dev/usb/ehcivar.h>
struct cfdriver ehci_cd = {
- NULL, "ehci", DV_DULL
+ NULL, "ehci", DV_DULL, CD_SKIPHIBERNATE
};
#ifdef EHCI_DEBUG
Index: dev/usb/ohci.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/ohci.c,v
retrieving revision 1.161
diff -u -p -u -r1.161 ohci.c
--- dev/usb/ohci.c 3 Apr 2020 20:11:47 -0000 1.161
+++ dev/usb/ohci.c 23 Oct 2021 20:42:16 -0000
@@ -52,7 +52,7 @@
#include <dev/usb/ohcivar.h>
struct cfdriver ohci_cd = {
- NULL, "ohci", DV_DULL
+ NULL, "ohci", DV_DULL, CD_SKIPHIBERNATE
};
#ifdef OHCI_DEBUG
Index: dev/usb/uhci.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uhci.c,v
retrieving revision 1.152
diff -u -p -u -r1.152 uhci.c
--- dev/usb/uhci.c 3 Apr 2020 20:11:47 -0000 1.152
+++ dev/usb/uhci.c 23 Oct 2021 20:42:16 -0000
@@ -55,7 +55,7 @@
/*#define UHCI_CTL_LOOP */
struct cfdriver uhci_cd = {
- NULL, "uhci", DV_DULL
+ NULL, "uhci", DV_DULL, CD_SKIPHIBERNATE
};
#ifdef UHCI_DEBUG
Index: dev/usb/xhci.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/xhci.c,v
retrieving revision 1.121
diff -u -p -u -r1.121 xhci.c
--- dev/usb/xhci.c 24 Feb 2021 03:08:47 -0000 1.121
+++ dev/usb/xhci.c 23 Oct 2021 20:42:16 -0000
@@ -38,7 +38,7 @@
#include <dev/usb/xhcivar.h>
struct cfdriver xhci_cd = {
- NULL, "xhci", DV_DULL
+ NULL, "xhci", DV_DULL, CD_SKIPHIBERNATE
};
#ifdef XHCI_DEBUG