Module Name: src Committed By: jmcneill Date: Sun Sep 20 11:25:36 UTC 2020
Modified Files: src/sys/dev/fdt: fdtbus.c Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.34 -r1.35 src/sys/dev/fdt/fdtbus.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/fdt/fdtbus.c diff -u src/sys/dev/fdt/fdtbus.c:1.34 src/sys/dev/fdt/fdtbus.c:1.35 --- src/sys/dev/fdt/fdtbus.c:1.34 Thu Jun 11 02:39:30 2020 +++ src/sys/dev/fdt/fdtbus.c Sun Sep 20 11:25:36 2020 @@ -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 <jmcne...@invisible.ca> @@ -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 @@ struct fdt_node { 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 int fdt_rescan(device_t, const ch 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 @@ fdt_rescan(device_t self, const char *if 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 @@ fdt_rescan(device_t self, const char *if 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 @@ fdt_add_child(device_t bus, const int ch 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 @@ fdt_scan_submatch(device_t parent, cfdat 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 @@ fdt_scan_best(struct fdt_softc *sc, stru 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 @@ fdt_scan(struct fdt_softc *sc, int pass) [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 @@ fdt_pre_attach(struct fdt_node *node) 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");