aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/module.h14
-rw-r--r--include/trace/events/module.h126
-rw-r--r--kernel/kmod.c4
-rw-r--r--kernel/module.c11
4 files changed, 152 insertions, 3 deletions
diff --git a/include/linux/module.h b/include/linux/module.h
index 098bdb7bfacf..f8f92d015efe 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -17,10 +17,12 @@
17#include <linux/moduleparam.h> 17#include <linux/moduleparam.h>
18#include <linux/marker.h> 18#include <linux/marker.h>
19#include <linux/tracepoint.h> 19#include <linux/tracepoint.h>
20#include <asm/local.h>
21 20
21#include <asm/local.h>
22#include <asm/module.h> 22#include <asm/module.h>
23 23
24#include <trace/events/module.h>
25
24/* Not Yet Implemented */ 26/* Not Yet Implemented */
25#define MODULE_SUPPORTED_DEVICE(name) 27#define MODULE_SUPPORTED_DEVICE(name)
26 28
@@ -462,7 +464,10 @@ static inline local_t *__module_ref_addr(struct module *mod, int cpu)
462static inline void __module_get(struct module *module) 464static inline void __module_get(struct module *module)
463{ 465{
464 if (module) { 466 if (module) {
465 local_inc(__module_ref_addr(module, get_cpu())); 467 unsigned int cpu = get_cpu();
468 local_inc(__module_ref_addr(module, cpu));
469 trace_module_get(module, _THIS_IP_,
470 local_read(__module_ref_addr(module, cpu)));
466 put_cpu(); 471 put_cpu();
467 } 472 }
468} 473}
@@ -473,8 +478,11 @@ static inline int try_module_get(struct module *module)
473 478
474 if (module) { 479 if (module) {
475 unsigned int cpu = get_cpu(); 480 unsigned int cpu = get_cpu();
476 if (likely(module_is_live(module))) 481 if (likely(module_is_live(module))) {
477 local_inc(__module_ref_addr(module, cpu)); 482 local_inc(__module_ref_addr(module, cpu));
483 trace_module_get(module, _THIS_IP_,
484 local_read(__module_ref_addr(module, cpu)));
485 }
478 else 486 else
479 ret = 0; 487 ret = 0;
480 put_cpu(); 488 put_cpu();
diff --git a/include/trace/events/module.h b/include/trace/events/module.h
new file mode 100644
index 000000000000..84160fb18478
--- /dev/null
+++ b/include/trace/events/module.h
@@ -0,0 +1,126 @@
1#undef TRACE_SYSTEM
2#define TRACE_SYSTEM module
3
4#if !defined(_TRACE_MODULE_H) || defined(TRACE_HEADER_MULTI_READ)
5#define _TRACE_MODULE_H
6
7#include <linux/tracepoint.h>
8
9#ifdef CONFIG_MODULES
10
11struct module;
12
13#define show_module_flags(flags) __print_flags(flags, "", \
14 { (1UL << TAINT_PROPRIETARY_MODULE), "P" }, \
15 { (1UL << TAINT_FORCED_MODULE), "F" }, \
16 { (1UL << TAINT_CRAP), "C" })
17
18TRACE_EVENT(module_load,
19
20 TP_PROTO(struct module *mod),
21
22 TP_ARGS(mod),
23
24 TP_STRUCT__entry(
25 __field( unsigned int, taints )
26 __string( name, mod->name )
27 ),
28
29 TP_fast_assign(
30 __entry->taints = mod->taints;
31 __assign_str(name, mod->name);
32 ),
33
34 TP_printk("%s %s", __get_str(name), show_module_flags(__entry->taints))
35);
36
37TRACE_EVENT(module_free,
38
39 TP_PROTO(struct module *mod),
40
41 TP_ARGS(mod),
42
43 TP_STRUCT__entry(
44 __string( name, mod->name )
45 ),
46
47 TP_fast_assign(
48 __assign_str(name, mod->name);
49 ),
50
51 TP_printk("%s", __get_str(name))
52);
53
54TRACE_EVENT(module_get,
55
56 TP_PROTO(struct module *mod, unsigned long ip, int refcnt),
57
58 TP_ARGS(mod, ip, refcnt),
59
60 TP_STRUCT__entry(
61 __field( unsigned long, ip )
62 __field( int, refcnt )
63 __string( name, mod->name )
64 ),
65
66 TP_fast_assign(
67 __entry->ip = ip;
68 __entry->refcnt = refcnt;
69 __assign_str(name, mod->name);
70 ),
71
72 TP_printk("%s call_site=%pf refcnt=%d",
73 __get_str(name), (void *)__entry->ip, __entry->refcnt)
74);
75
76TRACE_EVENT(module_put,
77
78 TP_PROTO(struct module *mod, unsigned long ip, int refcnt),
79
80 TP_ARGS(mod, ip, refcnt),
81
82 TP_STRUCT__entry(
83 __field( unsigned long, ip )
84 __field( int, refcnt )
85 __string( name, mod->name )
86 ),
87
88 TP_fast_assign(
89 __entry->ip = ip;
90 __entry->refcnt = refcnt;
91 __assign_str(name, mod->name);
92 ),
93
94 TP_printk("%s call_site=%pf refcnt=%d",
95 __get_str(name), (void *)__entry->ip, __entry->refcnt)
96);
97
98TRACE_EVENT(module_request,
99
100 TP_PROTO(char *name, bool wait, unsigned long ip),
101
102 TP_ARGS(name, wait, ip),
103
104 TP_STRUCT__entry(
105 __field( bool, wait )
106 __field( unsigned long, ip )
107 __string( name, name )
108 ),
109
110 TP_fast_assign(
111 __entry->wait = wait;
112 __entry->ip = ip;
113 __assign_str(name, name);
114 ),
115
116 TP_printk("%s wait=%d call_site=%pf",
117 __get_str(name), (int)__entry->wait, (void *)__entry->ip)
118);
119
120#endif /* CONFIG_MODULES */
121
122#endif /* _TRACE_MODULE_H */
123
124/* This part must be outside protection */
125#include <trace/define_trace.h>
126
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 385c31a1bdbf..a92280870e30 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -37,6 +37,8 @@
37#include <linux/suspend.h> 37#include <linux/suspend.h>
38#include <asm/uaccess.h> 38#include <asm/uaccess.h>
39 39
40#include <trace/events/module.h>
41
40extern int max_threads; 42extern int max_threads;
41 43
42static struct workqueue_struct *khelper_wq; 44static struct workqueue_struct *khelper_wq;
@@ -108,6 +110,8 @@ int __request_module(bool wait, const char *fmt, ...)
108 return -ENOMEM; 110 return -ENOMEM;
109 } 111 }
110 112
113 trace_module_request(module_name, wait, _RET_IP_);
114
111 ret = call_usermodehelper(modprobe_path, argv, envp, 115 ret = call_usermodehelper(modprobe_path, argv, envp,
112 wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC); 116 wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC);
113 atomic_dec(&kmod_concurrent); 117 atomic_dec(&kmod_concurrent);
diff --git a/kernel/module.c b/kernel/module.c
index fd1411403558..b1821438694e 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
61EXPORT_TRACEPOINT_SYMBOL(module_get);
62
58#if 0 63#if 0
59#define DEBUGP printk 64#define DEBUGP printk
60#else 65#else
@@ -940,6 +945,8 @@ void module_put(struct module *module)
940 if (module) { 945 if (module) {
941 unsigned int cpu = get_cpu(); 946 unsigned int cpu = get_cpu();
942 local_dec(__module_ref_addr(module, cpu)); 947 local_dec(__module_ref_addr(module, cpu));
948 trace_module_put(module, _RET_IP_,
949 local_read(__module_ref_addr(module, cpu)));
943 /* Maybe they're waiting for us to drop reference? */ 950 /* Maybe they're waiting for us to drop reference? */
944 if (unlikely(!module_is_live(module))) 951 if (unlikely(!module_is_live(module)))
945 wake_up_process(module->waiter); 952 wake_up_process(module->waiter);
@@ -1491,6 +1498,8 @@ static int __unlink_module(void *_mod)
1491/* Free a module, remove from lists, etc (must hold module_mutex). */ 1498/* Free a module, remove from lists, etc (must hold module_mutex). */
1492static void free_module(struct module *mod) 1499static void free_module(struct module *mod)
1493{ 1500{
1501 trace_module_free(mod);
1502
1494 /* Delete from various lists */ 1503 /* Delete from various lists */
1495 stop_machine(__unlink_module, mod, NULL); 1504 stop_machine(__unlink_module, mod, NULL);
1496 remove_notes_attrs(mod); 1505 remove_notes_attrs(mod);
@@ -2358,6 +2367,8 @@ static noinline struct module *load_module(void __user *umod,
2358 /* Get rid of temporary copy */ 2367 /* Get rid of temporary copy */
2359 vfree(hdr); 2368 vfree(hdr);
2360 2369
2370 trace_module_load(mod);
2371
2361 /* Done! */ 2372 /* Done! */
2362 return mod; 2373 return mod;
2363 2374