From: John L. <le...@mo...> - 2003-03-25 02:07:22
|
Implement a module load notifier for the benefit of OProfile, tested with .66 on UP. This patch (1/2) provides the general support for registering notifiers, and calls the notifier when a module is loaded. Please apply. john diff -X dontdiff -Naur linux-linus/include/linux/module.h linux-cvs/include/linux/module.h --- linux-linus/include/linux/module.h 2003-03-25 01:38:51.000000000 +0000 +++ linux-cvs/include/linux/module.h 2003-03-25 01:34:42.000000000 +0000 @@ -138,6 +138,7 @@ const struct exception_table_entry *entry; }; +struct notifier_block; #ifdef CONFIG_MODULES @@ -348,6 +349,9 @@ /* For extable.c to search modules' exception tables. */ const struct exception_table_entry *search_module_extables(unsigned long addr); +int register_module_notifier(struct notifier_block * nb); +int unregister_module_notifier(struct notifier_block * nb); + #else /* !CONFIG_MODULES... */ #define EXPORT_SYMBOL(sym) #define EXPORT_SYMBOL_GPL(sym) @@ -392,6 +396,18 @@ { return NULL; } + +static inline int register_module_notifier(struct notifier_block * nb) +{ + /* no events will happen anyway, so this can always succeed */ + return 0; +} + +static inline int unregister_module_notifier(struct notifier_block * nb) +{ + return 0; +} + #endif /* CONFIG_MODULES */ #ifdef MODULE diff -X dontdiff -Naur linux-linus/kernel/module.c linux-cvs/kernel/module.c --- linux-linus/kernel/module.c 2003-03-17 21:44:21.000000000 +0000 +++ linux-cvs/kernel/module.c 2003-03-25 01:31:40.000000000 +0000 @@ -31,6 +31,7 @@ #include <linux/errno.h> #include <linux/err.h> #include <linux/vermagic.h> +#include <linux/notifier.h> #include <asm/uaccess.h> #include <asm/semaphore.h> #include <asm/pgalloc.h> @@ -61,6 +62,29 @@ static LIST_HEAD(symbols); static LIST_HEAD(extables); +static DECLARE_MUTEX(notify_mutex); +static struct notifier_block * module_notify_list; + +int register_module_notifier(struct notifier_block * nb) +{ + int err; + down(¬ify_mutex); + err = notifier_chain_register(&module_notify_list, nb); + up(¬ify_mutex); + return err; +} +EXPORT_SYMBOL(register_module_notifier); + +int unregister_module_notifier(struct notifier_block * nb) +{ + int err; + down(¬ify_mutex); + err = notifier_chain_unregister(&module_notify_list, nb); + up(¬ify_mutex); + return err; +} +EXPORT_SYMBOL(unregister_module_notifier); + /* We require a truly strong try_module_get() */ static inline int strong_try_module_get(struct module *mod) { @@ -1368,6 +1392,10 @@ /* Drop lock so they can recurse */ up(&module_mutex); + down(¬ify_mutex); + notifier_call_chain(&module_notify_list, MODULE_STATE_COMING, mod); + up(¬ify_mutex); + /* Start the module */ ret = mod->init(); if (ret < 0) { |
From: John L. <le...@mo...> - 2003-03-25 02:17:55
|
Implement a module load notifier for the benefit of OProfile, tested with .66 on UP. This patch (2/2) hooks OProfile into the notifier. You should still be able to use OProfile 0.5.1 or thereabouts ... thanks, john diff -X dontdiff -Naur linux-linus/drivers/oprofile/buffer_sync.c linux-cvs/drivers/oprofile/buffer_sync.c --- linux-linus/drivers/oprofile/buffer_sync.c 2003-03-25 01:38:46.000000000 +0000 +++ linux-cvs/drivers/oprofile/buffer_sync.c 2003-03-25 01:34:52.000000000 +0000 @@ -24,6 +24,7 @@ #include <linux/notifier.h> #include <linux/dcookies.h> #include <linux/profile.h> +#include <linux/module.h> #include <linux/fs.h> #include "oprofile_stats.h" @@ -67,6 +68,19 @@ } +static int module_load_notify(struct notifier_block * self, unsigned long val, void * data) +{ + if (val != MODULE_STATE_COMING) + return 0; + + sync_cpu_buffers(); + down(&buffer_sem); + add_event_entry(ESCAPE_CODE); + add_event_entry(MODULE_LOADED_CODE); + up(&buffer_sem); + return 0; +} + static struct notifier_block exit_task_nb = { .notifier_call = exit_task_notify, }; @@ -79,6 +93,10 @@ .notifier_call = mm_notify, }; +static struct notifier_block module_load_nb = { + .notifier_call = module_load_notify, +}; + int sync_start(void) { @@ -98,9 +116,14 @@ err = profile_event_register(EXEC_UNMAP, &exec_unmap_nb); if (err) goto out3; + err = register_module_notifier(&module_load_nb); + if (err) + goto out4; out: return err; +out4: + profile_event_unregister(EXEC_UNMAP, &exec_unmap_nb); out3: profile_event_unregister(EXIT_MMAP, &exit_mmap_nb); out2: @@ -113,6 +136,7 @@ void sync_stop(void) { + unregister_module_notifier(&module_load_nb); profile_event_unregister(EXIT_TASK, &exit_task_nb); profile_event_unregister(EXIT_MMAP, &exit_mmap_nb); profile_event_unregister(EXEC_UNMAP, &exec_unmap_nb); diff -X dontdiff -Naur linux-linus/drivers/oprofile/event_buffer.h linux-cvs/drivers/oprofile/event_buffer.h --- linux-linus/drivers/oprofile/event_buffer.h 2003-03-17 21:43:41.000000000 +0000 +++ linux-cvs/drivers/oprofile/event_buffer.h 2003-03-25 01:31:43.000000000 +0000 @@ -24,12 +24,13 @@ * then one of the following codes, then the * relevant data. */ -#define ESCAPE_CODE ~0UL +#define ESCAPE_CODE ~0UL #define CTX_SWITCH_CODE 1 #define CPU_SWITCH_CODE 2 #define COOKIE_SWITCH_CODE 3 #define KERNEL_ENTER_SWITCH_CODE 4 #define KERNEL_EXIT_SWITCH_CODE 5 +#define MODULE_LOADED_CODE 6 /* add data to the event buffer */ void add_event_entry(unsigned long data); |
From: Rusty R. <ru...@ru...> - 2003-03-25 06:33:25
|
In message <200...@co...> you write: > > Implement a module load notifier for the benefit of OProfile, tested > with .66 on UP. Minor change to make unregister_module_notifier return void. Either way Linus, don't really mind. Please apply. Rusty. -- Anyone who quotes me in their sig is an idiot. -- Rusty Russell. Name: Module Notifier Patch Author: John Levon Status: Experimental D: Adds a notifier for when modules are inserted, for use of oprofile. diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .17066-linux-2.5.66/include/linux/module.h .17066-linux-2.5.66.updated/include/linux/module.h --- .17066-linux-2.5.66/include/linux/module.h 2003-03-25 12:17:31.000000000 +1100 +++ .17066-linux-2.5.66.updated/include/linux/module.h 2003-03-25 17:31:06.000000000 +1100 @@ -138,6 +138,7 @@ struct exception_table const struct exception_table_entry *entry; }; +struct notifier_block; #ifdef CONFIG_MODULES @@ -348,6 +349,9 @@ const char *module_address_lookup(unsign /* For extable.c to search modules' exception tables. */ const struct exception_table_entry *search_module_extables(unsigned long addr); +int register_module_notifier(struct notifier_block *nb); +void unregister_module_notifier(struct notifier_block *nb); + #else /* !CONFIG_MODULES... */ #define EXPORT_SYMBOL(sym) #define EXPORT_SYMBOL_GPL(sym) @@ -392,6 +396,17 @@ static inline const char *module_address { return NULL; } + +static inline int register_module_notifier(struct notifier_block *nb) +{ + /* no events will happen anyway, so this can always succeed */ + return 0; +} + +static inline void unregister_module_notifier(struct notifier_block *nb) +{ +} + #endif /* CONFIG_MODULES */ #ifdef MODULE diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .17066-linux-2.5.66/kernel/module.c .17066-linux-2.5.66.updated/kernel/module.c --- .17066-linux-2.5.66/kernel/module.c 2003-03-18 05:01:52.000000000 +1100 +++ .17066-linux-2.5.66.updated/kernel/module.c 2003-03-25 17:31:06.000000000 +1100 @@ -31,6 +31,7 @@ #include <linux/errno.h> #include <linux/err.h> #include <linux/vermagic.h> +#include <linux/notifier.h> #include <asm/uaccess.h> #include <asm/semaphore.h> #include <asm/pgalloc.h> @@ -61,6 +62,27 @@ static LIST_HEAD(modules); static LIST_HEAD(symbols); static LIST_HEAD(extables); +static DECLARE_MUTEX(notify_mutex); +static struct notifier_block *module_notify_list; + +int register_module_notifier(struct notifier_block * nb) +{ + int err; + down(¬ify_mutex); + err = notifier_chain_register(&module_notify_list, nb); + up(¬ify_mutex); + return err; +} +EXPORT_SYMBOL(register_module_notifier); + +void unregister_module_notifier(struct notifier_block * nb) +{ + down(¬ify_mutex); + notifier_chain_unregister(&module_notify_list, nb); + up(¬ify_mutex); +} +EXPORT_SYMBOL(unregister_module_notifier); + /* We require a truly strong try_module_get() */ static inline int strong_try_module_get(struct module *mod) { @@ -1368,6 +1390,10 @@ sys_init_module(void *umod, /* Drop lock so they can recurse */ up(&module_mutex); + down(¬ify_mutex); + notifier_call_chain(&module_notify_list, MODULE_STATE_COMING, mod); + up(¬ify_mutex); + /* Start the module */ ret = mod->init(); if (ret < 0) { |
From: John L. <le...@mo...> - 2003-03-25 11:45:58
|
On Tue, Mar 25, 2003 at 05:32:33PM +1100, Rusty Russell wrote: > > Implement a module load notifier for the benefit of OProfile, tested > > with .66 on UP. > > Minor change to make unregister_module_notifier return void. The -ENOENT return is there for a reason. If you don't want it, then you should remove it from notifier_call_register too. john |
From: Rusty R. <ru...@ru...> - 2003-03-27 04:11:50
|
In message <200...@co...> you write: > On Tue, Mar 25, 2003 at 05:32:33PM +1100, Rusty Russell wrote: > > > > Implement a module load notifier for the benefit of OProfile, tested > > > with .66 on UP. > > > > Minor change to make unregister_module_notifier return void. > > The -ENOENT return is there for a reason. What reason? I just grepped 2.5.66-bk2, and *noone* uses the return value, not even to BUG() (you have to grep for all the wrappers for notifier_call_unregister, too). That's because everyone realizes that the return value is useless. > If you don't want it, then you should remove it from > notifier_call_register too. (I assume you mean notifier_call_unregister). Yes, but that's another battle. Meanwhile, at least I'm not adding to the problem. Rusty. -- Anyone who quotes me in their sig is an idiot. -- Rusty Russell. |
From: John L. <le...@mo...> - 2003-03-27 04:22:07
|
On Thu, Mar 27, 2003 at 01:20:23PM +1100, Rusty Russell wrote: > What reason? I just grepped 2.5.66-bk2, and *noone* uses the return > value, not even to BUG() (you have to grep for all the wrappers for > notifier_call_unregister, too). Just more grist for the mill of the ill ... > (I assume you mean notifier_call_unregister). Yes, but that's another > battle. ... and it's the same ill. Half-cleaned up stuff sucks. Either remove it or don't. > That's because everyone realizes that the return value is useless. It detects one variant of unmatched register/unregister, so it cannot be said to be entirely useless. I would not call it entirely useful, though, I admit. Beside the point though really, I appear to have made onto Linus' shitlist at last ... does this mean I finally graduated Linux School ? regards john |