aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-10-20 16:35:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-20 16:35:07 -0400
commit92b29b86fe2e183d44eb467e5e74a5f718ef2e43 (patch)
tree1bac8a1aa11d47322b66d10ec3a370016d843d06 /kernel/module.c
parentb9d7ccf56be1ac77b71a284a1c0e6337f9a7aff0 (diff)
parent98d9c66ab07471006fd7910cb16453581c41a3e7 (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.c81
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
2796void 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 */
2812int 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