Re: PATCH: get_module_symbol() not SMP-safe

From: Keith Owens (kaos@ocs.com.au)
Date: Tue May 09 2000 - 08:06:06 EST


On Tue, 09 May 2000 13:38:55 +0100,
David Woodhouse <dwmw2@infradead.org> wrote:
>However, we do need a clean way to find the _correct_ module and increment
>its use count. What 8390.hI currently does is fairly ugly, IMO.

__MOD_INC_USE_COUNT(mod) increments the use count so all you need is
this routine to convert a symbol's address to its owning module.
Totally untested, it might not even compile.

struct module *address_to_module(unsigned long addr)
{
        struct module *mod;
        for (mod = module_list; mod; mod = mod->next) {
                if (MOD_CAN_QUERY(mod) &&
                    addr >= (unsigned long)mod &&
                    addr < (unsigned long)mod + mod->size)
                        return(mod);
        }
        return(NULL);
}

>I know how we could achieve that - why not just have get_module_symbol()
>increase the use count for you? That way, people just _couldn't_ screw it
>up.

Two problems with having get_module_symbol() increase the use count:

(1) The caller has to do put_module_symbol() for every symbol they
    looked up. Easy to miss one, and it makes it awkward to do things
    like this

#define NS8390_KSYSMS_PRESENT ( \
        get_module_symbol(NULL, "ethdev_init") != 0 && \
        get_module_symbol(NULL, "NS8390_init") != 0 && \
        get_module_symbol(NULL, "ei_open") != 0 && \
        get_module_symbol(NULL, "ei_close") != 0 && \
        get_module_symbol(NULL, "ei_interrupt") != 0)

    If the fifth test fails, you have to do put_module_symbol() on the
    four that worked to release the module. Try coding that as a
    single statement and handling all the possible cases - messy.

(2) More importantly, it differs from most of the other code that
    increases module use counts. Most uses of MOD_INC_USE are in the
    modules proper, not in kernel/module.c.

>+ * NOTE: Unless you are holding the kernel lock, there's no guarantee
>+ * that the module in which your symbol was found is still loaded by
>+ * the time get_module_symbol() returns.
>+ *
>+ * You should be holding the kernel lock while calling this function,
>+ * and must subsequently find the module and increase its use count,
>+ * before doing anything which may sleep. Otherwise, the module may
>+ * have disappeared by the time you dereference the symbol.

Good grief. Kernel documentation that says what locks are expected for
a routine. Be careful, you will have everybody documenting lock
requirements (well, I can hope, can't I?).

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon May 15 2000 - 21:00:13 EST