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

Reply via email to