diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-20 16:35:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-20 16:35:07 -0400 |
commit | 92b29b86fe2e183d44eb467e5e74a5f718ef2e43 (patch) | |
tree | 1bac8a1aa11d47322b66d10ec3a370016d843d06 /kernel/module.c | |
parent | b9d7ccf56be1ac77b71a284a1c0e6337f9a7aff0 (diff) | |
parent | 98d9c66ab07471006fd7910cb16453581c41a3e7 (diff) |
Merge branch 'tracing-v28-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'tracing-v28-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (131 commits)
tracing/fastboot: improve help text
tracing/stacktrace: improve help text
tracing/fastboot: fix initcalls disposition in bootgraph.pl
tracing/fastboot: fix bootgraph.pl initcall name regexp
tracing/fastboot: fix issues and improve output of bootgraph.pl
tracepoints: synchronize unregister static inline
tracepoints: tracepoint_synchronize_unregister()
ftrace: make ftrace_test_p6nop disassembler-friendly
markers: fix synchronize marker unregister static inline
tracing/fastboot: add better resolution to initcall debug/tracing
trace: add build-time check to avoid overrunning hex buffer
ftrace: fix hex output mode of ftrace
tracing/fastboot: fix initcalls disposition in bootgraph.pl
tracing/fastboot: fix printk format typo in boot tracer
ftrace: return an error when setting a nonexistent tracer
ftrace: make some tracers reentrant
ring-buffer: make reentrant
ring-buffer: move page indexes into page headers
tracing/fastboot: only trace non-module initcalls
ftrace: move pc counter in irqtrace
...
Manually fix conflicts:
- init/main.c: initcall tracing
- kernel/module.c: verbose level vs tracepoints
- scripts/bootgraph.pl: fallout from cherry-picking commits.
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 81 |
1 files changed, 80 insertions, 1 deletions
diff --git a/kernel/module.c b/kernel/module.c index 25bc9ac9e226..0d8d21ee792c 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -46,6 +46,8 @@ | |||
46 | #include <asm/cacheflush.h> | 46 | #include <asm/cacheflush.h> |
47 | #include <linux/license.h> | 47 | #include <linux/license.h> |
48 | #include <asm/sections.h> | 48 | #include <asm/sections.h> |
49 | #include <linux/tracepoint.h> | ||
50 | #include <linux/ftrace.h> | ||
49 | 51 | ||
50 | #if 0 | 52 | #if 0 |
51 | #define DEBUGP printk | 53 | #define DEBUGP printk |
@@ -1430,6 +1432,9 @@ static void free_module(struct module *mod) | |||
1430 | /* Module unload stuff */ | 1432 | /* Module unload stuff */ |
1431 | module_unload_free(mod); | 1433 | module_unload_free(mod); |
1432 | 1434 | ||
1435 | /* release any pointers to mcount in this module */ | ||
1436 | ftrace_release(mod->module_core, mod->core_size); | ||
1437 | |||
1433 | /* This may be NULL, but that's OK */ | 1438 | /* This may be NULL, but that's OK */ |
1434 | module_free(mod, mod->module_init); | 1439 | module_free(mod, mod->module_init); |
1435 | kfree(mod->args); | 1440 | kfree(mod->args); |
@@ -1861,9 +1866,13 @@ static noinline struct module *load_module(void __user *umod, | |||
1861 | unsigned int markersindex; | 1866 | unsigned int markersindex; |
1862 | unsigned int markersstringsindex; | 1867 | unsigned int markersstringsindex; |
1863 | unsigned int verboseindex; | 1868 | unsigned int verboseindex; |
1869 | unsigned int tracepointsindex; | ||
1870 | unsigned int tracepointsstringsindex; | ||
1871 | unsigned int mcountindex; | ||
1864 | struct module *mod; | 1872 | struct module *mod; |
1865 | long err = 0; | 1873 | long err = 0; |
1866 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ | 1874 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ |
1875 | void *mseg; | ||
1867 | struct exception_table_entry *extable; | 1876 | struct exception_table_entry *extable; |
1868 | mm_segment_t old_fs; | 1877 | mm_segment_t old_fs; |
1869 | 1878 | ||
@@ -2156,6 +2165,12 @@ static noinline struct module *load_module(void __user *umod, | |||
2156 | markersstringsindex = find_sec(hdr, sechdrs, secstrings, | 2165 | markersstringsindex = find_sec(hdr, sechdrs, secstrings, |
2157 | "__markers_strings"); | 2166 | "__markers_strings"); |
2158 | verboseindex = find_sec(hdr, sechdrs, secstrings, "__verbose"); | 2167 | verboseindex = find_sec(hdr, sechdrs, secstrings, "__verbose"); |
2168 | tracepointsindex = find_sec(hdr, sechdrs, secstrings, "__tracepoints"); | ||
2169 | tracepointsstringsindex = find_sec(hdr, sechdrs, secstrings, | ||
2170 | "__tracepoints_strings"); | ||
2171 | |||
2172 | mcountindex = find_sec(hdr, sechdrs, secstrings, | ||
2173 | "__mcount_loc"); | ||
2159 | 2174 | ||
2160 | /* Now do relocations. */ | 2175 | /* Now do relocations. */ |
2161 | for (i = 1; i < hdr->e_shnum; i++) { | 2176 | for (i = 1; i < hdr->e_shnum; i++) { |
@@ -2183,6 +2198,12 @@ static noinline struct module *load_module(void __user *umod, | |||
2183 | mod->num_markers = | 2198 | mod->num_markers = |
2184 | sechdrs[markersindex].sh_size / sizeof(*mod->markers); | 2199 | sechdrs[markersindex].sh_size / sizeof(*mod->markers); |
2185 | #endif | 2200 | #endif |
2201 | #ifdef CONFIG_TRACEPOINTS | ||
2202 | mod->tracepoints = (void *)sechdrs[tracepointsindex].sh_addr; | ||
2203 | mod->num_tracepoints = | ||
2204 | sechdrs[tracepointsindex].sh_size / sizeof(*mod->tracepoints); | ||
2205 | #endif | ||
2206 | |||
2186 | 2207 | ||
2187 | /* Find duplicate symbols */ | 2208 | /* Find duplicate symbols */ |
2188 | err = verify_export_symbols(mod); | 2209 | err = verify_export_symbols(mod); |
@@ -2201,12 +2222,22 @@ static noinline struct module *load_module(void __user *umod, | |||
2201 | 2222 | ||
2202 | add_kallsyms(mod, sechdrs, symindex, strindex, secstrings); | 2223 | add_kallsyms(mod, sechdrs, symindex, strindex, secstrings); |
2203 | 2224 | ||
2225 | if (!mod->taints) { | ||
2204 | #ifdef CONFIG_MARKERS | 2226 | #ifdef CONFIG_MARKERS |
2205 | if (!mod->taints) | ||
2206 | marker_update_probe_range(mod->markers, | 2227 | marker_update_probe_range(mod->markers, |
2207 | mod->markers + mod->num_markers); | 2228 | mod->markers + mod->num_markers); |
2208 | #endif | 2229 | #endif |
2209 | dynamic_printk_setup(sechdrs, verboseindex); | 2230 | dynamic_printk_setup(sechdrs, verboseindex); |
2231 | #ifdef CONFIG_TRACEPOINTS | ||
2232 | tracepoint_update_probe_range(mod->tracepoints, | ||
2233 | mod->tracepoints + mod->num_tracepoints); | ||
2234 | #endif | ||
2235 | } | ||
2236 | |||
2237 | /* sechdrs[0].sh_size is always zero */ | ||
2238 | mseg = (void *)sechdrs[mcountindex].sh_addr; | ||
2239 | ftrace_init_module(mseg, mseg + sechdrs[mcountindex].sh_size); | ||
2240 | |||
2210 | err = module_finalize(hdr, sechdrs, mod); | 2241 | err = module_finalize(hdr, sechdrs, mod); |
2211 | if (err < 0) | 2242 | if (err < 0) |
2212 | goto cleanup; | 2243 | goto cleanup; |
@@ -2276,6 +2307,7 @@ static noinline struct module *load_module(void __user *umod, | |||
2276 | cleanup: | 2307 | cleanup: |
2277 | kobject_del(&mod->mkobj.kobj); | 2308 | kobject_del(&mod->mkobj.kobj); |
2278 | kobject_put(&mod->mkobj.kobj); | 2309 | kobject_put(&mod->mkobj.kobj); |
2310 | ftrace_release(mod->module_core, mod->core_size); | ||
2279 | free_unload: | 2311 | free_unload: |
2280 | module_unload_free(mod); | 2312 | module_unload_free(mod); |
2281 | module_free(mod, mod->module_init); | 2313 | module_free(mod, mod->module_init); |
@@ -2759,3 +2791,50 @@ void module_update_markers(void) | |||
2759 | mutex_unlock(&module_mutex); | 2791 | mutex_unlock(&module_mutex); |
2760 | } | 2792 | } |
2761 | #endif | 2793 | #endif |
2794 | |||
2795 | #ifdef CONFIG_TRACEPOINTS | ||
2796 | void module_update_tracepoints(void) | ||
2797 | { | ||
2798 | struct module *mod; | ||
2799 | |||
2800 | mutex_lock(&module_mutex); | ||
2801 | list_for_each_entry(mod, &modules, list) | ||
2802 | if (!mod->taints) | ||
2803 | tracepoint_update_probe_range(mod->tracepoints, | ||
2804 | mod->tracepoints + mod->num_tracepoints); | ||
2805 | mutex_unlock(&module_mutex); | ||
2806 | } | ||
2807 | |||
2808 | /* | ||
2809 | * Returns 0 if current not found. | ||
2810 | * Returns 1 if current found. | ||
2811 | */ | ||
2812 | int module_get_iter_tracepoints(struct tracepoint_iter *iter) | ||
2813 | { | ||
2814 | struct module *iter_mod; | ||
2815 | int found = 0; | ||
2816 | |||
2817 | mutex_lock(&module_mutex); | ||
2818 | list_for_each_entry(iter_mod, &modules, list) { | ||
2819 | if (!iter_mod->taints) { | ||
2820 | /* | ||
2821 | * Sorted module list | ||
2822 | */ | ||
2823 | if (iter_mod < iter->module) | ||
2824 | continue; | ||
2825 | else if (iter_mod > iter->module) | ||
2826 | iter->tracepoint = NULL; | ||
2827 | found = tracepoint_get_iter_range(&iter->tracepoint, | ||
2828 | iter_mod->tracepoints, | ||
2829 | iter_mod->tracepoints | ||
2830 | + iter_mod->num_tracepoints); | ||
2831 | if (found) { | ||
2832 | iter->module = iter_mod; | ||
2833 | break; | ||
2834 | } | ||
2835 | } | ||
2836 | } | ||
2837 | mutex_unlock(&module_mutex); | ||
2838 | return found; | ||
2839 | } | ||
2840 | #endif | ||