Commit bbc55bde authored by Masahiro Yamada's avatar Masahiro Yamada
Browse files

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: default avatarMasahiro Yamada <yamada.masahiro@socionext.com>
Tested-by: default avatarJessica Yu <jeyu@kernel.org>
Acked-by: default avatarJessica Yu <jeyu@kernel.org>
Reviewed-by: default avatarMatthias Maennich <maennich@google.com>
Tested-by: default avatarMatthias Maennich <maennich@google.com>
parent 0241ea8c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@
*.lzo
*.mod
*.mod.c
*.ns_deps
*.o
*.o.*
*.patch
@@ -61,6 +60,7 @@ modules.order
/System.map
/Module.markers
/modules.builtin.modinfo
/modules.nsdeps

#
# RPM spec file (make rpm-pkg)
+1 −0
Original line number Diff line number Diff line
@@ -179,6 +179,7 @@ mkutf8data
modpost
modules.builtin
modules.builtin.modinfo
modules.nsdeps
modules.order
modversions.h*
nconf
+2 −2
Original line number Diff line number Diff line
@@ -1357,7 +1357,7 @@ endif # CONFIG_MODULES

# Directories & files removed with 'make clean'
CLEAN_DIRS  += include/ksym
CLEAN_FILES += modules.builtin.modinfo
CLEAN_FILES += modules.builtin.modinfo modules.nsdeps

# Directories & files removed with 'make mrproper'
MRPROPER_DIRS  += include/config include/generated          \
@@ -1662,7 +1662,7 @@ clean: $(clean-dirs)
		-o -name '*.ko.*' \
		-o -name '*.dtb' -o -name '*.dtb.S' -o -name '*.dt.yaml' \
		-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 '*.lex.c' -o -name '*.tab.[ch]' \
		-o -name '*.asn1.[ch]' \
+1 −1
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ __modpost:
else

MODPOST += $(subst -i,-n,$(filter -i,$(MAKEFLAGS))) -s -T - \
	$(if $(KBUILD_NSDEPS),-d)
	$(if $(KBUILD_NSDEPS),-d modules.nsdeps)

ifeq ($(KBUILD_EXTMOD),)
MODPOST += $(wildcard vmlinux)
+17 −25
Original line number Diff line number Diff line
@@ -38,8 +38,6 @@ static int sec_mismatch_count = 0;
static int sec_mismatch_fatal = 0;
/* ignore missing files */
static int ignore_missing_files;
/* write namespace dependencies */
static int write_namespace_deps;

enum export {
	export_plain,      export_unused,     export_gpl,
@@ -2217,14 +2215,11 @@ static int check_exports(struct module *mod)
		else
			basename = mod->name;

		if (exp->namespace) {
			add_namespace(&mod->required_namespaces,
				      exp->namespace);

			if (!module_imports_namespace(mod, exp->namespace)) {
		if (exp->namespace &&
		    !module_imports_namespace(mod, exp->namespace)) {
			warn("module %s uses symbol %s from namespace %s, but does not import it.\n",
			     basename, exp->name, exp->namespace);
			}
			add_namespace(&mod->missing_namespaces, exp->namespace);
		}

		if (!mod->gpl_compatible)
@@ -2526,30 +2521,26 @@ static void write_dump(const char *fname)
	free(buf.p);
}

static void write_namespace_deps_files(void)
static void write_namespace_deps_files(const char *fname)
{
	struct module *mod;
	struct namespace_list *ns;
	struct buffer ns_deps_buf = {};

	for (mod = modules; mod; mod = mod->next) {
		char fname[PATH_MAX];

		if (mod->skip)
		if (mod->skip || !mod->missing_namespaces)
			continue;

		ns_deps_buf.pos = 0;
		buf_printf(&ns_deps_buf, "%s.ko:", mod->name);

		for (ns = mod->required_namespaces; ns; ns = ns->next)
			buf_printf(&ns_deps_buf, "%s\n", ns->namespace);
		for (ns = mod->missing_namespaces; ns; ns = ns->next)
			buf_printf(&ns_deps_buf, " %s", ns->namespace);

		if (ns_deps_buf.pos == 0)
			continue;

		sprintf(fname, "%s.ns_deps", mod->name);
		write_if_changed(&ns_deps_buf, fname);
		buf_printf(&ns_deps_buf, "\n");
	}

	write_if_changed(&ns_deps_buf, fname);
	free(ns_deps_buf.p);
}

@@ -2563,6 +2554,7 @@ int main(int argc, char **argv)
	struct module *mod;
	struct buffer buf = { };
	char *kernel_read = NULL;
	char *missing_namespace_deps = NULL;
	char *dump_write = NULL, *files_source = NULL;
	int opt;
	int err;
@@ -2570,7 +2562,7 @@ int main(int argc, char **argv)
	struct ext_sym_list *extsym_iter;
	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) {
		case 'i':
			kernel_read = optarg;
@@ -2609,7 +2601,7 @@ int main(int argc, char **argv)
			sec_mismatch_fatal = 1;
			break;
		case 'd':
			write_namespace_deps = 1;
			missing_namespace_deps = optarg;
			break;
		default:
			exit(1);
@@ -2657,8 +2649,8 @@ int main(int argc, char **argv)
		write_if_changed(&buf, fname);
	}

	if (write_namespace_deps)
		write_namespace_deps_files();
	if (missing_namespace_deps)
		write_namespace_deps_files(missing_namespace_deps);

	if (dump_write)
		write_dump(dump_write);
Loading