lkml.org 
[lkml]   [2009]   [Aug]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    SubjectRe: [PATCH] tracing/profile: Fix profile_disable vs module_unload
    From
    Date
    On Wed, 2009-08-26 at 08:46 +0200, Peter Zijlstra wrote:

    > Aahh, I see the bug, its only ftrace that knows about the module, not
    > tracepoints themselves, _that_ needs fixing.

    These are the bits I hacked up until I figured out the above bug.

    ---
    include/linux/ftrace_event.h | 2 +-
    include/linux/module.h | 18 ++++++++++++++----
    kernel/module.c | 9 +--------
    3 files changed, 16 insertions(+), 13 deletions(-)

    diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
    index df5b085..d86d60c 100644
    --- a/include/linux/ftrace_event.h
    +++ b/include/linux/ftrace_event.h
    @@ -122,7 +122,7 @@ struct ftrace_event_call {
    struct list_head fields;
    int filter_active;
    struct event_filter *filter;
    - void *mod;
    + struct module *mod;
    void *data;

    atomic_t profile_count;
    diff --git a/include/linux/module.h b/include/linux/module.h
    index 86863cd..09e2b88 100644
    --- a/include/linux/module.h
    +++ b/include/linux/module.h
    @@ -409,16 +409,26 @@ struct module *__module_address(unsigned long addr);
    bool is_module_address(unsigned long addr);
    bool is_module_text_address(unsigned long addr);

    +static inline
    +int __within_module(unsigned long addr, void *start, unsigned long size)
    +{
    + return ((void *)addr >= start && (void *)addr < start + size);
    +}
    +
    static inline int within_module_core(unsigned long addr, struct module *mod)
    {
    - return (unsigned long)mod->module_core <= addr &&
    - addr < (unsigned long)mod->module_core + mod->core_size;
    + return __within_module(addr, mod->module_core, mod->core_size);
    }

    static inline int within_module_init(unsigned long addr, struct module *mod)
    {
    - return (unsigned long)mod->module_init <= addr &&
    - addr < (unsigned long)mod->module_init + mod->init_size;
    + return __within_module(addr, mod->module_init, mod->init_size);
    +}
    +
    +static inline int within_module_text(unsigned long addr, struct module *mod)
    +{
    + return __within_module(addr, mod->module_init, mod->init_text_size) ||
    + __within_module(addr, mod->core_init, mod->core_text_size);
    }

    /* Search for module by name: must hold module_mutex. */
    diff --git a/kernel/module.c b/kernel/module.c
    index b182143..822adb6 100644
    --- a/kernel/module.c
    +++ b/kernel/module.c
    @@ -2493,11 +2493,6 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
    return 0;
    }

    -static inline int within(unsigned long addr, void *start, unsigned long size)
    -{
    - return ((void *)addr >= start && (void *)addr < start + size);
    -}
    -
    #ifdef CONFIG_KALLSYMS
    /*
    * This ignores the intensely annoying "mapping symbols" found
    @@ -2912,9 +2907,7 @@ struct module *__module_text_address(unsigned long addr)
    {
    struct module *mod = __module_address(addr);
    if (mod) {
    - /* Make sure it's within the text section. */
    - if (!within(addr, mod->module_init, mod->init_text_size)
    - && !within(addr, mod->module_core, mod->core_text_size))
    + if (!within_module_text(addr, mod))
    mod = NULL;
    }
    return mod;


    \
     
     \ /
      Last update: 2009-08-26 08:57    [W:2.889 / U:0.060 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site