Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/fdt Adjust fdt_rescan to speed up booting by signifi...



details:   https://anonhg.NetBSD.org/src/rev/c1350175d94c
branches:  trunk
changeset: 938923:c1350175d94c
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sun Sep 20 11:25:36 2020 +0000

description:
Adjust fdt_rescan to speed up booting by significantly reducing the number
of times that we call config_match. Now we only call it 11 times per node.
Previously, each scan pass of an unconfigured device triggered 11 calls to
config_match, and adding a new simplebus causes the scan to restart, so
we are avoiding potentially hundreds of calls to config_match per node now.

diffstat:

 sys/dev/fdt/fdtbus.c |  73 ++++++++++++++++++++++++---------------------------
 1 files changed, 35 insertions(+), 38 deletions(-)

diffs (186 lines):

diff -r 6289de24bf1a -r c1350175d94c sys/dev/fdt/fdtbus.c
--- a/sys/dev/fdt/fdtbus.c      Sun Sep 20 10:30:05 2020 +0000
+++ b/sys/dev/fdt/fdtbus.c      Sun Sep 20 11:25:36 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fdtbus.c,v 1.34 2020/06/11 02:39:30 thorpej Exp $ */
+/* $NetBSD: fdtbus.c,v 1.35 2020/09/20 11:25:36 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdtbus.c,v 1.34 2020/06/11 02:39:30 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdtbus.c,v 1.35 2020/09/20 11:25:36 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -53,6 +53,8 @@
        int             n_phandle;
        const char      *n_name;
        struct fdt_attach_args n_faa;
+
+       int             n_cfpass;
        cfdata_t        n_cf;
 
        u_int           n_order;
@@ -78,7 +80,7 @@
 static void    fdt_childdet(device_t, device_t);
 
 static int     fdt_scan_submatch(device_t, cfdata_t, const int *, void *);
-static cfdata_t        fdt_scan_best(struct fdt_softc *, struct fdt_node *);
+static void    fdt_scan_best(struct fdt_softc *, struct fdt_node *);
 static void    fdt_scan(struct fdt_softc *, int);
 static void    fdt_add_node(struct fdt_node *);
 static u_int   fdt_get_order(int);
@@ -161,7 +163,7 @@
        int pass;
 
        TAILQ_FOREACH(node, &fdt_nodes, n_nodes)
-               node->n_cf = fdt_scan_best(sc, node);
+               fdt_scan_best(sc, node);
 
        pass = 0;
        fdt_need_rescan = false;
@@ -170,8 +172,8 @@
                if (fdt_need_rescan == true) {
                        pass = 0;
                        TAILQ_FOREACH(node, &fdt_nodes, n_nodes) {
-                               if (node->n_dev == NULL)
-                                       node->n_cf = fdt_scan_best(sc, node);
+                               if (node->n_cfpass == -1)
+                                       fdt_scan_best(sc, node);
                        }
                        fdt_need_rescan = false;
                } else {
@@ -298,11 +300,13 @@
        struct fdt_node *node;
 
        /* Add the node to our device list */
-       node = kmem_alloc(sizeof(*node), KM_SLEEP);
+       node = kmem_zalloc(sizeof(*node), KM_SLEEP);
        node->n_bus = bus;
        node->n_dev = NULL;
        node->n_phandle = child;
        node->n_name = fdtbus_get_string(child, "name");
+       node->n_cfpass = -1;
+       node->n_cf = NULL;
        node->n_order = order;
        node->n_faa = *faa;
        node->n_faa.faa_phandle = child;
@@ -323,15 +327,16 @@
        return config_stdsubmatch(parent, cf, locs, aux);
 }
 
-static cfdata_t
+static void
 fdt_scan_best(struct fdt_softc *sc, struct fdt_node *node)
 {
        struct fdt_attach_args faa;
        cfdata_t cf, best_cf;
-       int match, best_match;
+       int match, best_match, best_pass;
 
        best_cf = NULL;
        best_match = 0;
+       best_pass = FDTCF_PASS_DEFAULT;
 
        for (int pass = 0; pass <= FDTCF_PASS_DEFAULT; pass++) {
                const int locs[FDTCF_NLOCS] = {
@@ -345,10 +350,12 @@
                if (match > best_match) {
                        best_match = match;
                        best_cf = cf;
+                       best_pass = pass;
                }
        }
 
-       return best_cf;
+       node->n_cf = best_cf;
+       node->n_cfpass = best_pass;
 }
 
 static void
@@ -360,54 +367,38 @@
                [FDTCF_PASS] = pass
        };
        bool quiet = pass != FDTCF_PASS_DEFAULT;
-       prop_dictionary_t dict;
-       char buf[FDT_MAX_PATH];
 
        TAILQ_FOREACH(node, &fdt_nodes, n_nodes) {
-               if (node->n_dev != NULL)
+               if (node->n_cfpass != pass || node->n_dev != NULL)
                        continue;
 
                fdt_init_attach_args(&sc->sc_faa, node, quiet, &faa);
 
-               if (quiet) {
+               if (quiet && node->n_cf == NULL) {
                        /*
                         * No match for this device, skip it.
                         */
-                       if (node->n_cf == NULL)
-                               continue;
+                       continue;
+               }
 
-                       /*
-                        * Make sure we don't attach before a better match in a later pass.
-                        */
-                       cfdata_t cf_pass =
-                           config_search_loc(fdt_scan_submatch, node->n_bus, "fdt", locs, &faa);
-                       if (node->n_cf != cf_pass)
-                               continue;
+               /*
+                * Attach the device.
+                */
+               fdt_pre_attach(node);
 
-                       /*
-                        * Attach the device.
-                        */
-                       fdt_pre_attach(node);
-                       node->n_dev = config_attach_loc(node->n_bus, cf_pass, locs,
+               if (quiet) {
+                       node->n_dev = config_attach_loc(node->n_bus, node->n_cf, locs,
                            &faa, fdtbus_print);
-                       if (node->n_dev != NULL)
-                               fdt_post_attach(node);
                } else {
                        /*
                         * Default pass.
                         */
-                       fdt_pre_attach(node);
                        node->n_dev = config_found_sm_loc(node->n_bus, "fdt", locs,
                            &faa, fdtbus_print, fdt_scan_submatch);
-                       if (node->n_dev != NULL)
-                               fdt_post_attach(node);
                }
 
-               if (node->n_dev) {
-                       dict = device_properties(node->n_dev);
-                       if (fdtbus_get_path(node->n_phandle, buf, sizeof(buf)))
-                               prop_dictionary_set_string(dict, "fdt-path", buf);
-               }
+               if (node->n_dev != NULL)
+                       fdt_post_attach(node);
        }
 }
 
@@ -433,8 +424,14 @@
 static void
 fdt_post_attach(struct fdt_node *node)
 {
+       char buf[FDT_MAX_PATH];
+       prop_dictionary_t dict;
        int error;
 
+       dict = device_properties(node->n_dev);
+       if (fdtbus_get_path(node->n_phandle, buf, sizeof(buf)))
+               prop_dictionary_set_string(dict, "fdt-path", buf);
+
        if (node->n_pinctrl_init) {
                aprint_debug_dev(node->n_bus, "set default config for %s\n", node->n_name);
                error = fdtbus_pinctrl_set_config(node->n_phandle, "default");



Home | Main Index | Thread Index | Old Index