From: Emil Velikov Date: Sun, 20 Oct 2024 12:39:02 +0000 (+0100) Subject: tools/depmod: use separate arrays for alias,xxxdep values X-Git-Tag: v34~186 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=823849a05aa611cbf82fce1587c97129c4e20a2c;p=thirdparty%2Fkmod.git tools/depmod: use separate arrays for alias,xxxdep values Currently, we walk the info list multiples times each time filtering all but one key. Just create a few arrays to avoid that, saving 2-3% cycles at the cost of extra ~500bytes per module. Signed-off-by: Emil Velikov Link: https://github.com/kmod-project/kmod/pull/197 Signed-off-by: Lucas De Marchi --- diff --git a/tools/depmod.c b/tools/depmod.c index 42cc0a21..a33b38a1 100644 --- a/tools/depmod.c +++ b/tools/depmod.c @@ -898,6 +898,9 @@ struct mod { char *uncrelpath; /* same as relpath but ending in .ko */ struct kmod_list *info_list; struct kmod_list *dep_sym_list; + struct array alias_values; + struct array softdep_values; + struct array weakdep_values; struct array deps; /* struct symbol */ size_t baselen; /* points to start of basename/filename */ size_t modnamesz; @@ -929,6 +932,9 @@ static void mod_free(struct mod *mod) { DBG("free %p kmod=%p, path=%s\n", mod, mod->kmod, mod->path); array_free_array(&mod->deps); + array_free_array(&mod->weakdep_values); + array_free_array(&mod->softdep_values); + array_free_array(&mod->alias_values); kmod_module_unref(mod->kmod); kmod_module_info_free_list(mod->info_list); kmod_module_dependency_symbols_free_list(mod->dep_sym_list); @@ -1044,6 +1050,10 @@ static int depmod_module_add(struct depmod *depmod, struct kmod_module *kmod) memcpy(mod->modname, modname, modnamesz); mod->modnamesz = modnamesz; + array_init(&mod->alias_values, 32); // fits ~80%, ~5% are in the xxx+ + array_init(&mod->softdep_values, 8); // fits ~95%, the rest are sub 16 + array_init(&mod->weakdep_values, 4); // fits 100% + array_init(&mod->deps, 4); mod->path = strdup(kmod_module_get_path(kmod)); @@ -1575,6 +1585,31 @@ static int depmod_load_modules(struct depmod *depmod) load_info: kmod_module_get_info(mod->kmod, &mod->info_list); + kmod_list_foreach(l, mod->info_list) { + const char *key = kmod_module_info_get_key(l); + + if (streq(key, "alias")) { + const char *value = kmod_module_info_get_value(l); + + if (array_append(&mod->alias_values, value) < 0) + return 0; + continue; + } + if (streq(key, "softdep")) { + const char *value = kmod_module_info_get_value(l); + + if (array_append(&mod->softdep_values, value) < 0) + return 0; + continue; + } + if (streq(key, "weakdep")) { + const char *value = kmod_module_info_get_value(l); + + if (array_append(&mod->weakdep_values, value) < 0) + return 0; + continue; + } + } kmod_module_get_dependency_symbols(mod->kmod, &mod->dep_sym_list); kmod_module_unref(mod->kmod); mod->kmod = NULL; @@ -2141,15 +2176,10 @@ static int output_aliases(struct depmod *depmod, FILE *out) for (i = 0; i < depmod->modules.count; i++) { const struct mod *mod = depmod->modules.array[i]; - struct kmod_list *l; - - kmod_list_foreach(l, mod->info_list) { - const char *key = kmod_module_info_get_key(l); - const char *value = kmod_module_info_get_value(l); - - if (!streq(key, "alias")) - continue; + const struct array *values = &mod->alias_values; + for (size_t j = 0; j < values->count; j++) { + const char *value = values->array[j]; fprintf(out, "alias %s %s\n", value, mod->modname); } } @@ -2171,18 +2201,14 @@ static int output_aliases_bin(struct depmod *depmod, FILE *out) for (i = 0; i < depmod->modules.count; i++) { const struct mod *mod = depmod->modules.array[i]; - struct kmod_list *l; + const struct array *values = &mod->alias_values; - kmod_list_foreach(l, mod->info_list) { - const char *key = kmod_module_info_get_key(l); - const char *value = kmod_module_info_get_value(l); + for (size_t j = 0; j < values->count; j++) { + const char *value = values->array[j]; char buf[PATH_MAX]; const char *alias; int duplicate; - if (!streq(key, "alias")) - continue; - if (alias_normalize(value, buf, NULL) < 0) { WRN("Unmatched bracket in %s\n", value); continue; @@ -2210,15 +2236,10 @@ static int output_softdeps(struct depmod *depmod, FILE *out) for (i = 0; i < depmod->modules.count; i++) { const struct mod *mod = depmod->modules.array[i]; - struct kmod_list *l; - - kmod_list_foreach(l, mod->info_list) { - const char *key = kmod_module_info_get_key(l); - const char *value = kmod_module_info_get_value(l); - - if (!streq(key, "softdep")) - continue; + const struct array *values = &mod->softdep_values; + for (size_t j = 0; j < values->count; j++) { + const char *value = values->array[j]; fprintf(out, "softdep %s %s\n", mod->modname, value); } } @@ -2234,15 +2255,10 @@ static int output_weakdeps(struct depmod *depmod, FILE *out) for (i = 0; i < depmod->modules.count; i++) { const struct mod *mod = depmod->modules.array[i]; - struct kmod_list *l; - - kmod_list_foreach(l, mod->info_list) { - const char *key = kmod_module_info_get_key(l); - const char *value = kmod_module_info_get_value(l); - - if (!streq(key, "weakdep")) - continue; + const struct array *values = &mod->weakdep_values; + for (size_t j = 0; j < values->count; j++) { + const char *value = values->array[j]; fprintf(out, "weakdep %s %s\n", mod->modname, value); } } @@ -2461,19 +2477,15 @@ static int output_devname(struct depmod *depmod, FILE *out) for (i = 0; i < depmod->modules.count; i++) { const struct mod *mod = depmod->modules.array[i]; - struct kmod_list *l; + const struct array *values = &mod->alias_values; const char *devname = NULL; char type = '\0'; unsigned int major = 0, minor = 0; - kmod_list_foreach(l, mod->info_list) { - const char *key = kmod_module_info_get_key(l); - const char *value = kmod_module_info_get_value(l); + for (size_t j = 0; j < values->count; j++) { + const char *value = values->array[j]; unsigned int maj, min; - if (!streq(key, "alias")) - continue; - if (strstartswith(value, "devname:")) devname = value + sizeof("devname:") - 1; else if (sscanf(value, "char-major-%u-%u", &maj, &min) == 2) {