Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

modpost: dump missing namespaces into a single modules.nsdeps file

The modpost, with the -d option given, generates per-module .ns_deps
files.

Kbuild generates per-module .mod files to carry module information.
This is convenient because Make handles multiple jobs in parallel
when the -j option is given.

On the other hand, the modpost always runs as a single thread.
I do not see a strong reason to produce separate .ns_deps files.

This commit changes the modpost to generate just one file,
modules.nsdeps, each line of which has the following format:

<module_name>: <list of missing namespaces>

Please note it contains *missing* namespaces instead of required ones.
So, modules.nsdeps is empty if the namespace dependency is all good.

This will work more efficiently because spatch will no longer process
already imported namespaces. I removed the '(if needed)' from the
nsdeps log since spatch is invoked only when needed.

This also solves the stale .ns_deps problem reported by Jessica Yu:

https://lkml.org/lkml/2019/10/28/467

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Tested-by: Jessica Yu <jeyu@kernel.org>
Acked-by: Jessica Yu <jeyu@kernel.org>
Reviewed-by: Matthias Maennich <maennich@google.com>
Tested-by: Matthias Maennich <maennich@google.com>

+34 -42
+1 -1
.gitignore
··· 32 32 *.lzo 33 33 *.mod 34 34 *.mod.c 35 - *.ns_deps 36 35 *.o 37 36 *.o.* 38 37 *.patch ··· 60 61 /System.map 61 62 /Module.markers 62 63 /modules.builtin.modinfo 64 + /modules.nsdeps 63 65 64 66 # 65 67 # RPM spec file (make rpm-pkg)
+1
Documentation/dontdiff
··· 179 179 modpost 180 180 modules.builtin 181 181 modules.builtin.modinfo 182 + modules.nsdeps 182 183 modules.order 183 184 modversions.h* 184 185 nconf
+2 -2
Makefile
··· 1357 1357 1358 1358 # Directories & files removed with 'make clean' 1359 1359 CLEAN_DIRS += include/ksym 1360 - CLEAN_FILES += modules.builtin.modinfo 1360 + CLEAN_FILES += modules.builtin.modinfo modules.nsdeps 1361 1361 1362 1362 # Directories & files removed with 'make mrproper' 1363 1363 MRPROPER_DIRS += include/config include/generated \ ··· 1662 1662 -o -name '*.ko.*' \ 1663 1663 -o -name '*.dtb' -o -name '*.dtb.S' -o -name '*.dt.yaml' \ 1664 1664 -o -name '*.dwo' -o -name '*.lst' \ 1665 - -o -name '*.su' -o -name '*.mod' -o -name '*.ns_deps' \ 1665 + -o -name '*.su' -o -name '*.mod' \ 1666 1666 -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ 1667 1667 -o -name '*.lex.c' -o -name '*.tab.[ch]' \ 1668 1668 -o -name '*.asn1.[ch]' \
+1 -1
scripts/Makefile.modpost
··· 66 66 else 67 67 68 68 MODPOST += $(subst -i,-n,$(filter -i,$(MAKEFLAGS))) -s -T - \ 69 - $(if $(KBUILD_NSDEPS),-d) 69 + $(if $(KBUILD_NSDEPS),-d modules.nsdeps) 70 70 71 71 ifeq ($(KBUILD_EXTMOD),) 72 72 MODPOST += $(wildcard vmlinux)
+17 -25
scripts/mod/modpost.c
··· 38 38 static int sec_mismatch_fatal = 0; 39 39 /* ignore missing files */ 40 40 static int ignore_missing_files; 41 - /* write namespace dependencies */ 42 - static int write_namespace_deps; 43 41 44 42 enum export { 45 43 export_plain, export_unused, export_gpl, ··· 2215 2217 else 2216 2218 basename = mod->name; 2217 2219 2218 - if (exp->namespace) { 2219 - add_namespace(&mod->required_namespaces, 2220 - exp->namespace); 2221 - 2222 - if (!module_imports_namespace(mod, exp->namespace)) { 2223 - warn("module %s uses symbol %s from namespace %s, but does not import it.\n", 2224 - basename, exp->name, exp->namespace); 2225 - } 2220 + if (exp->namespace && 2221 + !module_imports_namespace(mod, exp->namespace)) { 2222 + warn("module %s uses symbol %s from namespace %s, but does not import it.\n", 2223 + basename, exp->name, exp->namespace); 2224 + add_namespace(&mod->missing_namespaces, exp->namespace); 2226 2225 } 2227 2226 2228 2227 if (!mod->gpl_compatible) ··· 2521 2526 free(buf.p); 2522 2527 } 2523 2528 2524 - static void write_namespace_deps_files(void) 2529 + static void write_namespace_deps_files(const char *fname) 2525 2530 { 2526 2531 struct module *mod; 2527 2532 struct namespace_list *ns; 2528 2533 struct buffer ns_deps_buf = {}; 2529 2534 2530 2535 for (mod = modules; mod; mod = mod->next) { 2531 - char fname[PATH_MAX]; 2532 2536 2533 - if (mod->skip) 2537 + if (mod->skip || !mod->missing_namespaces) 2534 2538 continue; 2535 2539 2536 - ns_deps_buf.pos = 0; 2540 + buf_printf(&ns_deps_buf, "%s.ko:", mod->name); 2537 2541 2538 - for (ns = mod->required_namespaces; ns; ns = ns->next) 2539 - buf_printf(&ns_deps_buf, "%s\n", ns->namespace); 2542 + for (ns = mod->missing_namespaces; ns; ns = ns->next) 2543 + buf_printf(&ns_deps_buf, " %s", ns->namespace); 2540 2544 2541 - if (ns_deps_buf.pos == 0) 2542 - continue; 2543 - 2544 - sprintf(fname, "%s.ns_deps", mod->name); 2545 - write_if_changed(&ns_deps_buf, fname); 2545 + buf_printf(&ns_deps_buf, "\n"); 2546 2546 } 2547 2547 2548 + write_if_changed(&ns_deps_buf, fname); 2548 2549 free(ns_deps_buf.p); 2549 2550 } 2550 2551 ··· 2554 2563 struct module *mod; 2555 2564 struct buffer buf = { }; 2556 2565 char *kernel_read = NULL; 2566 + char *missing_namespace_deps = NULL; 2557 2567 char *dump_write = NULL, *files_source = NULL; 2558 2568 int opt; 2559 2569 int err; ··· 2562 2570 struct ext_sym_list *extsym_iter; 2563 2571 struct ext_sym_list *extsym_start = NULL; 2564 2572 2565 - while ((opt = getopt(argc, argv, "i:e:mnsT:o:awEd")) != -1) { 2573 + while ((opt = getopt(argc, argv, "i:e:mnsT:o:awEd:")) != -1) { 2566 2574 switch (opt) { 2567 2575 case 'i': 2568 2576 kernel_read = optarg; ··· 2601 2609 sec_mismatch_fatal = 1; 2602 2610 break; 2603 2611 case 'd': 2604 - write_namespace_deps = 1; 2612 + missing_namespace_deps = optarg; 2605 2613 break; 2606 2614 default: 2607 2615 exit(1); ··· 2649 2657 write_if_changed(&buf, fname); 2650 2658 } 2651 2659 2652 - if (write_namespace_deps) 2653 - write_namespace_deps_files(); 2660 + if (missing_namespace_deps) 2661 + write_namespace_deps_files(missing_namespace_deps); 2654 2662 2655 2663 if (dump_write) 2656 2664 write_dump(dump_write);
+2 -2
scripts/mod/modpost.h
··· 126 126 struct buffer dev_table_buf; 127 127 char srcversion[25]; 128 128 int is_dot_o; 129 - // Required namespace dependencies 130 - struct namespace_list *required_namespaces; 129 + // Missing namespace dependencies 130 + struct namespace_list *missing_namespaces; 131 131 // Actual imported namespaces 132 132 struct namespace_list *imported_namespaces; 133 133 };
+10 -11
scripts/nsdeps
··· 27 27 } 28 28 29 29 generate_deps() { 30 - local mod_name=`basename $@ .ko` 31 - local mod_file=`echo $@ | sed -e 's/\.ko/\.mod/'` 32 - local ns_deps_file=`echo $@ | sed -e 's/\.ko/\.ns_deps/'` 33 - if [ ! -f "$ns_deps_file" ]; then return; fi 34 - local mod_source_files="`cat $mod_file | sed -n 1p \ 30 + local mod=${1%.ko:} 31 + shift 32 + local namespaces="$*" 33 + local mod_source_files="`cat $mod.mod | sed -n 1p \ 35 34 | sed -e 's/\.o/\.c/g' \ 36 35 | sed "s|[^ ]* *|${srctree}/&|g"`" 37 - for ns in `cat $ns_deps_file`; do 38 - echo "Adding namespace $ns to module $mod_name (if needed)." 36 + for ns in $namespaces; do 37 + echo "Adding namespace $ns to module $mod.ko." 39 38 generate_deps_for_ns $ns "$mod_source_files" 40 39 # sort the imports 41 40 for source_file in $mod_source_files; do ··· 51 52 done 52 53 } 53 54 54 - for f in `cat $objtree/modules.order`; do 55 - generate_deps $f 56 - done 57 - 55 + while read line 56 + do 57 + generate_deps $line 58 + done < modules.nsdeps