diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-09-07 02:19:51 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-09-07 02:19:51 -0400 |
commit | a1922ed661ab2c1637d0b10cde933bd9cd33d965 (patch) | |
tree | 0f1777542b385ebefd30b3586d830fd8ed6fda5b /kernel/module.c | |
parent | 75e33751ca8bbb72dd6f1a74d2810ddc8cbe4bdf (diff) | |
parent | d28daf923ac5e4a0d7cecebae56f3e339189366b (diff) |
Merge branch 'tracing/core' into tracing/hw-breakpoints
Conflicts:
arch/Kconfig
kernel/trace/trace.h
Merge reason: resolve the conflicts, plus adopt to the new
ring-buffer APIs.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/kernel/module.c b/kernel/module.c index 215aaab09e91..46580edff0cb 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -55,6 +55,11 @@ | |||
55 | #include <linux/percpu.h> | 55 | #include <linux/percpu.h> |
56 | #include <linux/kmemleak.h> | 56 | #include <linux/kmemleak.h> |
57 | 57 | ||
58 | #define CREATE_TRACE_POINTS | ||
59 | #include <trace/events/module.h> | ||
60 | |||
61 | EXPORT_TRACEPOINT_SYMBOL(module_get); | ||
62 | |||
58 | #if 0 | 63 | #if 0 |
59 | #define DEBUGP printk | 64 | #define DEBUGP printk |
60 | #else | 65 | #else |
@@ -909,16 +914,18 @@ void __symbol_put(const char *symbol) | |||
909 | } | 914 | } |
910 | EXPORT_SYMBOL(__symbol_put); | 915 | EXPORT_SYMBOL(__symbol_put); |
911 | 916 | ||
917 | /* Note this assumes addr is a function, which it currently always is. */ | ||
912 | void symbol_put_addr(void *addr) | 918 | void symbol_put_addr(void *addr) |
913 | { | 919 | { |
914 | struct module *modaddr; | 920 | struct module *modaddr; |
921 | unsigned long a = (unsigned long)dereference_function_descriptor(addr); | ||
915 | 922 | ||
916 | if (core_kernel_text((unsigned long)addr)) | 923 | if (core_kernel_text(a)) |
917 | return; | 924 | return; |
918 | 925 | ||
919 | /* module_text_address is safe here: we're supposed to have reference | 926 | /* module_text_address is safe here: we're supposed to have reference |
920 | * to module from symbol_get, so it can't go away. */ | 927 | * to module from symbol_get, so it can't go away. */ |
921 | modaddr = __module_text_address((unsigned long)addr); | 928 | modaddr = __module_text_address(a); |
922 | BUG_ON(!modaddr); | 929 | BUG_ON(!modaddr); |
923 | module_put(modaddr); | 930 | module_put(modaddr); |
924 | } | 931 | } |
@@ -940,6 +947,8 @@ void module_put(struct module *module) | |||
940 | if (module) { | 947 | if (module) { |
941 | unsigned int cpu = get_cpu(); | 948 | unsigned int cpu = get_cpu(); |
942 | local_dec(__module_ref_addr(module, cpu)); | 949 | local_dec(__module_ref_addr(module, cpu)); |
950 | trace_module_put(module, _RET_IP_, | ||
951 | local_read(__module_ref_addr(module, cpu))); | ||
943 | /* Maybe they're waiting for us to drop reference? */ | 952 | /* Maybe they're waiting for us to drop reference? */ |
944 | if (unlikely(!module_is_live(module))) | 953 | if (unlikely(!module_is_live(module))) |
945 | wake_up_process(module->waiter); | 954 | wake_up_process(module->waiter); |
@@ -1068,7 +1077,8 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs, | |||
1068 | { | 1077 | { |
1069 | const unsigned long *crc; | 1078 | const unsigned long *crc; |
1070 | 1079 | ||
1071 | if (!find_symbol("module_layout", NULL, &crc, true, false)) | 1080 | if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL, |
1081 | &crc, true, false)) | ||
1072 | BUG(); | 1082 | BUG(); |
1073 | return check_version(sechdrs, versindex, "module_layout", mod, crc); | 1083 | return check_version(sechdrs, versindex, "module_layout", mod, crc); |
1074 | } | 1084 | } |
@@ -1271,6 +1281,10 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect, | |||
1271 | struct module_notes_attrs *notes_attrs; | 1281 | struct module_notes_attrs *notes_attrs; |
1272 | struct bin_attribute *nattr; | 1282 | struct bin_attribute *nattr; |
1273 | 1283 | ||
1284 | /* failed to create section attributes, so can't create notes */ | ||
1285 | if (!mod->sect_attrs) | ||
1286 | return; | ||
1287 | |||
1274 | /* Count notes sections and allocate structures. */ | 1288 | /* Count notes sections and allocate structures. */ |
1275 | notes = 0; | 1289 | notes = 0; |
1276 | for (i = 0; i < nsect; i++) | 1290 | for (i = 0; i < nsect; i++) |
@@ -1490,6 +1504,8 @@ static int __unlink_module(void *_mod) | |||
1490 | /* Free a module, remove from lists, etc (must hold module_mutex). */ | 1504 | /* Free a module, remove from lists, etc (must hold module_mutex). */ |
1491 | static void free_module(struct module *mod) | 1505 | static void free_module(struct module *mod) |
1492 | { | 1506 | { |
1507 | trace_module_free(mod); | ||
1508 | |||
1493 | /* Delete from various lists */ | 1509 | /* Delete from various lists */ |
1494 | stop_machine(__unlink_module, mod, NULL); | 1510 | stop_machine(__unlink_module, mod, NULL); |
1495 | remove_notes_attrs(mod); | 1511 | remove_notes_attrs(mod); |
@@ -2216,6 +2232,10 @@ static noinline struct module *load_module(void __user *umod, | |||
2216 | mod->unused_gpl_crcs = section_addr(hdr, sechdrs, secstrings, | 2232 | mod->unused_gpl_crcs = section_addr(hdr, sechdrs, secstrings, |
2217 | "__kcrctab_unused_gpl"); | 2233 | "__kcrctab_unused_gpl"); |
2218 | #endif | 2234 | #endif |
2235 | #ifdef CONFIG_CONSTRUCTORS | ||
2236 | mod->ctors = section_objs(hdr, sechdrs, secstrings, ".ctors", | ||
2237 | sizeof(*mod->ctors), &mod->num_ctors); | ||
2238 | #endif | ||
2219 | 2239 | ||
2220 | #ifdef CONFIG_MARKERS | 2240 | #ifdef CONFIG_MARKERS |
2221 | mod->markers = section_objs(hdr, sechdrs, secstrings, "__markers", | 2241 | mod->markers = section_objs(hdr, sechdrs, secstrings, "__markers", |
@@ -2353,6 +2373,8 @@ static noinline struct module *load_module(void __user *umod, | |||
2353 | /* Get rid of temporary copy */ | 2373 | /* Get rid of temporary copy */ |
2354 | vfree(hdr); | 2374 | vfree(hdr); |
2355 | 2375 | ||
2376 | trace_module_load(mod); | ||
2377 | |||
2356 | /* Done! */ | 2378 | /* Done! */ |
2357 | return mod; | 2379 | return mod; |
2358 | 2380 | ||
@@ -2389,6 +2411,17 @@ static noinline struct module *load_module(void __user *umod, | |||
2389 | goto free_hdr; | 2411 | goto free_hdr; |
2390 | } | 2412 | } |
2391 | 2413 | ||
2414 | /* Call module constructors. */ | ||
2415 | static void do_mod_ctors(struct module *mod) | ||
2416 | { | ||
2417 | #ifdef CONFIG_CONSTRUCTORS | ||
2418 | unsigned long i; | ||
2419 | |||
2420 | for (i = 0; i < mod->num_ctors; i++) | ||
2421 | mod->ctors[i](); | ||
2422 | #endif | ||
2423 | } | ||
2424 | |||
2392 | /* This is where the real work happens */ | 2425 | /* This is where the real work happens */ |
2393 | SYSCALL_DEFINE3(init_module, void __user *, umod, | 2426 | SYSCALL_DEFINE3(init_module, void __user *, umod, |
2394 | unsigned long, len, const char __user *, uargs) | 2427 | unsigned long, len, const char __user *, uargs) |
@@ -2417,6 +2450,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, | |||
2417 | blocking_notifier_call_chain(&module_notify_list, | 2450 | blocking_notifier_call_chain(&module_notify_list, |
2418 | MODULE_STATE_COMING, mod); | 2451 | MODULE_STATE_COMING, mod); |
2419 | 2452 | ||
2453 | do_mod_ctors(mod); | ||
2420 | /* Start the module */ | 2454 | /* Start the module */ |
2421 | if (mod->init != NULL) | 2455 | if (mod->init != NULL) |
2422 | ret = do_one_initcall(mod->init); | 2456 | ret = do_one_initcall(mod->init); |
@@ -2435,9 +2469,9 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, | |||
2435 | return ret; | 2469 | return ret; |
2436 | } | 2470 | } |
2437 | if (ret > 0) { | 2471 | if (ret > 0) { |
2438 | printk(KERN_WARNING "%s: '%s'->init suspiciously returned %d, " | 2472 | printk(KERN_WARNING |
2439 | "it should follow 0/-E convention\n" | 2473 | "%s: '%s'->init suspiciously returned %d, it should follow 0/-E convention\n" |
2440 | KERN_WARNING "%s: loading module anyway...\n", | 2474 | "%s: loading module anyway...\n", |
2441 | __func__, mod->name, ret, | 2475 | __func__, mod->name, ret, |
2442 | __func__); | 2476 | __func__); |
2443 | dump_stack(); | 2477 | dump_stack(); |