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>
This commit is contained in:
Masahiro Yamada 2019-10-29 21:38:07 +09:00
parent 0241ea8cae
commit bbc55bded4
7 changed files with 34 additions and 42 deletions

2
.gitignore vendored
View File

@ -32,7 +32,6 @@
*.lzo *.lzo
*.mod *.mod
*.mod.c *.mod.c
*.ns_deps
*.o *.o
*.o.* *.o.*
*.patch *.patch
@ -61,6 +60,7 @@ modules.order
/System.map /System.map
/Module.markers /Module.markers
/modules.builtin.modinfo /modules.builtin.modinfo
/modules.nsdeps
# #
# RPM spec file (make rpm-pkg) # RPM spec file (make rpm-pkg)

View File

@ -179,6 +179,7 @@ mkutf8data
modpost modpost
modules.builtin modules.builtin
modules.builtin.modinfo modules.builtin.modinfo
modules.nsdeps
modules.order modules.order
modversions.h* modversions.h*
nconf nconf

View File

@ -1357,7 +1357,7 @@ endif # CONFIG_MODULES
# Directories & files removed with 'make clean' # Directories & files removed with 'make clean'
CLEAN_DIRS += include/ksym CLEAN_DIRS += include/ksym
CLEAN_FILES += modules.builtin.modinfo CLEAN_FILES += modules.builtin.modinfo modules.nsdeps
# Directories & files removed with 'make mrproper' # Directories & files removed with 'make mrproper'
MRPROPER_DIRS += include/config include/generated \ MRPROPER_DIRS += include/config include/generated \
@ -1662,7 +1662,7 @@ clean: $(clean-dirs)
-o -name '*.ko.*' \ -o -name '*.ko.*' \
-o -name '*.dtb' -o -name '*.dtb.S' -o -name '*.dt.yaml' \ -o -name '*.dtb' -o -name '*.dtb.S' -o -name '*.dt.yaml' \
-o -name '*.dwo' -o -name '*.lst' \ -o -name '*.dwo' -o -name '*.lst' \
-o -name '*.su' -o -name '*.mod' -o -name '*.ns_deps' \ -o -name '*.su' -o -name '*.mod' \
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
-o -name '*.lex.c' -o -name '*.tab.[ch]' \ -o -name '*.lex.c' -o -name '*.tab.[ch]' \
-o -name '*.asn1.[ch]' \ -o -name '*.asn1.[ch]' \

View File

@ -66,7 +66,7 @@ __modpost:
else else
MODPOST += $(subst -i,-n,$(filter -i,$(MAKEFLAGS))) -s -T - \ MODPOST += $(subst -i,-n,$(filter -i,$(MAKEFLAGS))) -s -T - \
$(if $(KBUILD_NSDEPS),-d) $(if $(KBUILD_NSDEPS),-d modules.nsdeps)
ifeq ($(KBUILD_EXTMOD),) ifeq ($(KBUILD_EXTMOD),)
MODPOST += $(wildcard vmlinux) MODPOST += $(wildcard vmlinux)

View File

@ -38,8 +38,6 @@ static int sec_mismatch_count = 0;
static int sec_mismatch_fatal = 0; static int sec_mismatch_fatal = 0;
/* ignore missing files */ /* ignore missing files */
static int ignore_missing_files; static int ignore_missing_files;
/* write namespace dependencies */
static int write_namespace_deps;
enum export { enum export {
export_plain, export_unused, export_gpl, export_plain, export_unused, export_gpl,
@ -2217,14 +2215,11 @@ static int check_exports(struct module *mod)
else else
basename = mod->name; basename = mod->name;
if (exp->namespace) { if (exp->namespace &&
add_namespace(&mod->required_namespaces, !module_imports_namespace(mod, exp->namespace)) {
exp->namespace); warn("module %s uses symbol %s from namespace %s, but does not import it.\n",
basename, exp->name, exp->namespace);
if (!module_imports_namespace(mod, exp->namespace)) { add_namespace(&mod->missing_namespaces, exp->namespace);
warn("module %s uses symbol %s from namespace %s, but does not import it.\n",
basename, exp->name, exp->namespace);
}
} }
if (!mod->gpl_compatible) if (!mod->gpl_compatible)
@ -2526,30 +2521,26 @@ static void write_dump(const char *fname)
free(buf.p); free(buf.p);
} }
static void write_namespace_deps_files(void) static void write_namespace_deps_files(const char *fname)
{ {
struct module *mod; struct module *mod;
struct namespace_list *ns; struct namespace_list *ns;
struct buffer ns_deps_buf = {}; struct buffer ns_deps_buf = {};
for (mod = modules; mod; mod = mod->next) { for (mod = modules; mod; mod = mod->next) {
char fname[PATH_MAX];
if (mod->skip) if (mod->skip || !mod->missing_namespaces)
continue; continue;
ns_deps_buf.pos = 0; buf_printf(&ns_deps_buf, "%s.ko:", mod->name);
for (ns = mod->required_namespaces; ns; ns = ns->next) for (ns = mod->missing_namespaces; ns; ns = ns->next)
buf_printf(&ns_deps_buf, "%s\n", ns->namespace); buf_printf(&ns_deps_buf, " %s", ns->namespace);
if (ns_deps_buf.pos == 0) buf_printf(&ns_deps_buf, "\n");
continue;
sprintf(fname, "%s.ns_deps", mod->name);
write_if_changed(&ns_deps_buf, fname);
} }
write_if_changed(&ns_deps_buf, fname);
free(ns_deps_buf.p); free(ns_deps_buf.p);
} }
@ -2563,6 +2554,7 @@ int main(int argc, char **argv)
struct module *mod; struct module *mod;
struct buffer buf = { }; struct buffer buf = { };
char *kernel_read = NULL; char *kernel_read = NULL;
char *missing_namespace_deps = NULL;
char *dump_write = NULL, *files_source = NULL; char *dump_write = NULL, *files_source = NULL;
int opt; int opt;
int err; int err;
@ -2570,7 +2562,7 @@ int main(int argc, char **argv)
struct ext_sym_list *extsym_iter; struct ext_sym_list *extsym_iter;
struct ext_sym_list *extsym_start = NULL; struct ext_sym_list *extsym_start = NULL;
while ((opt = getopt(argc, argv, "i:e:mnsT:o:awEd")) != -1) { while ((opt = getopt(argc, argv, "i:e:mnsT:o:awEd:")) != -1) {
switch (opt) { switch (opt) {
case 'i': case 'i':
kernel_read = optarg; kernel_read = optarg;
@ -2609,7 +2601,7 @@ int main(int argc, char **argv)
sec_mismatch_fatal = 1; sec_mismatch_fatal = 1;
break; break;
case 'd': case 'd':
write_namespace_deps = 1; missing_namespace_deps = optarg;
break; break;
default: default:
exit(1); exit(1);
@ -2657,8 +2649,8 @@ int main(int argc, char **argv)
write_if_changed(&buf, fname); write_if_changed(&buf, fname);
} }
if (write_namespace_deps) if (missing_namespace_deps)
write_namespace_deps_files(); write_namespace_deps_files(missing_namespace_deps);
if (dump_write) if (dump_write)
write_dump(dump_write); write_dump(dump_write);

View File

@ -126,8 +126,8 @@ struct module {
struct buffer dev_table_buf; struct buffer dev_table_buf;
char srcversion[25]; char srcversion[25];
int is_dot_o; int is_dot_o;
// Required namespace dependencies // Missing namespace dependencies
struct namespace_list *required_namespaces; struct namespace_list *missing_namespaces;
// Actual imported namespaces // Actual imported namespaces
struct namespace_list *imported_namespaces; struct namespace_list *imported_namespaces;
}; };

View File

@ -27,15 +27,14 @@ generate_deps_for_ns() {
} }
generate_deps() { generate_deps() {
local mod_name=`basename $@ .ko` local mod=${1%.ko:}
local mod_file=`echo $@ | sed -e 's/\.ko/\.mod/'` shift
local ns_deps_file=`echo $@ | sed -e 's/\.ko/\.ns_deps/'` local namespaces="$*"
if [ ! -f "$ns_deps_file" ]; then return; fi local mod_source_files="`cat $mod.mod | sed -n 1p \
local mod_source_files="`cat $mod_file | sed -n 1p \
| sed -e 's/\.o/\.c/g' \ | sed -e 's/\.o/\.c/g' \
| sed "s|[^ ]* *|${srctree}/&|g"`" | sed "s|[^ ]* *|${srctree}/&|g"`"
for ns in `cat $ns_deps_file`; do for ns in $namespaces; do
echo "Adding namespace $ns to module $mod_name (if needed)." echo "Adding namespace $ns to module $mod.ko."
generate_deps_for_ns $ns "$mod_source_files" generate_deps_for_ns $ns "$mod_source_files"
# sort the imports # sort the imports
for source_file in $mod_source_files; do for source_file in $mod_source_files; do
@ -52,7 +51,7 @@ generate_deps() {
done done
} }
for f in `cat $objtree/modules.order`; do while read line
generate_deps $f do
done generate_deps $line
done < modules.nsdeps