Re: [PATCH 1/2] module: add a function to add module references

From: Daniel Vetter
Date: Fri Apr 29 2022 - 03:54:20 EST


On Fri, Apr 29, 2022 at 07:31:15AM +0100, Mauro Carvalho Chehab wrote:
> Sometimes, device drivers are bound using indirect references,
> which is not visible when looking at /proc/modules or lsmod.
>
> Add a function to allow setting up module references for such
> cases.
>
> Reviewed-by: Dan Williams <dan.j.williams@xxxxxxxxx>
> Signed-off-by: Mauro Carvalho Chehab <mchehab@xxxxxxxxxx>

This sounds like duct tape at the wrong level. We should have a
device_link connecting these devices, and maybe device_link internally
needs to make sure the respective driver modules stay around for long
enough too. But open-coding this all over the place into every driver that
has some kind of cross-driver dependency sounds terrible.

Or maybe the bug is that the snd driver keeps accessing the hw/component
side when that is just plain gone. Iirc there's still fundamental issues
there on the sound side of things, which have been attempted to paper over
by timeouts and stuff like that in the past instead of enforcing a hard
link between the snd and i915 side.

Adding Greg for device model questions like this.
-Daniel

> ---
>
> See [PATCH 0/2] at: https://lore.kernel.org/all/cover.1651212016.git.mchehab@xxxxxxxxxx/
>
> include/linux/module.h | 7 +++++++
> kernel/module/main.c | 31 +++++++++++++++++++++++++++++++
> 2 files changed, 38 insertions(+)
>
> diff --git a/include/linux/module.h b/include/linux/module.h
> index 46d4d5f2516e..be74f807e41d 100644
> --- a/include/linux/module.h
> +++ b/include/linux/module.h
> @@ -596,6 +596,8 @@ static inline bool within_module(unsigned long addr, const struct module *mod)
> /* Search for module by name: must be in a RCU-sched critical section. */
> struct module *find_module(const char *name);
>
> +int module_add_named_dependency(const char *name, struct module *this);
> +
> /* Returns 0 and fills in value, defined and namebuf, or -ERANGE if
> symnum out of range. */
> int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
> @@ -772,6 +774,11 @@ static inline int lookup_module_symbol_attrs(unsigned long addr, unsigned long *
> return -ERANGE;
> }
>
> +static inline int module_add_named_dependency(const char *name, struct module *this)
> +{
> + return 0;
> +}
> +
> static inline int module_get_kallsym(unsigned int symnum, unsigned long *value,
> char *type, char *name,
> char *module_name, int *exported)
> diff --git a/kernel/module/main.c b/kernel/module/main.c
> index 05a42d8fcd7a..dbd577ccc38c 100644
> --- a/kernel/module/main.c
> +++ b/kernel/module/main.c
> @@ -631,6 +631,37 @@ static int ref_module(struct module *a, struct module *b)
> return 0;
> }
>
> +int module_add_named_dependency(const char *name, struct module *this)
> +{
> + struct module *mod;
> + int ret;
> +
> + if (!name || !this || !this->name) {
> + return -EINVAL;
> + }
> +
> + mutex_lock(&module_mutex);
> + mod = find_module(name);
> + if (!mod) {
> + ret = -EINVAL;
> + goto ret;
> + }
> +
> + ret = ref_module(this, mod);
> + if (ret)
> + goto ret;
> +
> +#ifdef CONFIG_MODULE_UNLOAD
> + ret = sysfs_create_link(mod->holders_dir,
> + &this->mkobj.kobj, this->name);
> +#endif
> +
> +ret:
> + mutex_unlock(&module_mutex);
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(module_add_named_dependency);
> +
> /* Clear the unload stuff of the module. */
> static void module_unload_free(struct module *mod)
> {
> --
> 2.35.1
>

--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch