diff options
Diffstat (limited to 'kernel/trace/trace_stat.c')
-rw-r--r-- | kernel/trace/trace_stat.c | 147 |
1 files changed, 71 insertions, 76 deletions
diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c index 2110cea2ece3..eae9cef39291 100644 --- a/kernel/trace/trace_stat.c +++ b/kernel/trace/trace_stat.c | |||
@@ -17,16 +17,16 @@ | |||
17 | 17 | ||
18 | /* List of stat entries from a tracer */ | 18 | /* List of stat entries from a tracer */ |
19 | struct trace_stat_list { | 19 | struct trace_stat_list { |
20 | struct list_head list; | 20 | struct list_head list; |
21 | void *stat; | 21 | void *stat; |
22 | }; | 22 | }; |
23 | 23 | ||
24 | /* A stat session is the stats output in one file */ | 24 | /* A stat session is the stats output in one file */ |
25 | struct tracer_stat_session { | 25 | struct tracer_stat_session { |
26 | struct list_head session_list; | 26 | struct list_head session_list; |
27 | struct tracer_stat *ts; | 27 | struct tracer_stat *ts; |
28 | struct list_head stat_list; | 28 | struct list_head stat_list; |
29 | struct mutex stat_mutex; | 29 | struct mutex stat_mutex; |
30 | struct dentry *file; | 30 | struct dentry *file; |
31 | }; | 31 | }; |
32 | 32 | ||
@@ -35,7 +35,7 @@ static LIST_HEAD(all_stat_sessions); | |||
35 | static DEFINE_MUTEX(all_stat_sessions_mutex); | 35 | static DEFINE_MUTEX(all_stat_sessions_mutex); |
36 | 36 | ||
37 | /* The root directory for all stat files */ | 37 | /* The root directory for all stat files */ |
38 | static struct dentry *stat_dir; | 38 | static struct dentry *stat_dir; |
39 | 39 | ||
40 | 40 | ||
41 | static void reset_stat_session(struct tracer_stat_session *session) | 41 | static void reset_stat_session(struct tracer_stat_session *session) |
@@ -56,71 +56,6 @@ static void destroy_session(struct tracer_stat_session *session) | |||
56 | kfree(session); | 56 | kfree(session); |
57 | } | 57 | } |
58 | 58 | ||
59 | |||
60 | static int init_stat_file(struct tracer_stat_session *session); | ||
61 | |||
62 | int register_stat_tracer(struct tracer_stat *trace) | ||
63 | { | ||
64 | struct tracer_stat_session *session, *node, *tmp; | ||
65 | int ret; | ||
66 | |||
67 | if (!trace) | ||
68 | return -EINVAL; | ||
69 | |||
70 | if (!trace->stat_start || !trace->stat_next || !trace->stat_show) | ||
71 | return -EINVAL; | ||
72 | |||
73 | /* Already registered? */ | ||
74 | mutex_lock(&all_stat_sessions_mutex); | ||
75 | list_for_each_entry_safe(node, tmp, &all_stat_sessions, session_list) { | ||
76 | if (node->ts == trace) { | ||
77 | mutex_unlock(&all_stat_sessions_mutex); | ||
78 | return -EINVAL; | ||
79 | } | ||
80 | } | ||
81 | mutex_unlock(&all_stat_sessions_mutex); | ||
82 | |||
83 | /* Init the session */ | ||
84 | session = kmalloc(sizeof(struct tracer_stat_session), GFP_KERNEL); | ||
85 | if (!session) | ||
86 | return -ENOMEM; | ||
87 | |||
88 | session->ts = trace; | ||
89 | INIT_LIST_HEAD(&session->session_list); | ||
90 | INIT_LIST_HEAD(&session->stat_list); | ||
91 | mutex_init(&session->stat_mutex); | ||
92 | session->file = NULL; | ||
93 | |||
94 | ret = init_stat_file(session); | ||
95 | if (ret) { | ||
96 | destroy_session(session); | ||
97 | return ret; | ||
98 | } | ||
99 | |||
100 | /* Register */ | ||
101 | mutex_lock(&all_stat_sessions_mutex); | ||
102 | list_add_tail(&session->session_list, &all_stat_sessions); | ||
103 | mutex_unlock(&all_stat_sessions_mutex); | ||
104 | |||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | void unregister_stat_tracer(struct tracer_stat *trace) | ||
109 | { | ||
110 | struct tracer_stat_session *node, *tmp; | ||
111 | |||
112 | mutex_lock(&all_stat_sessions_mutex); | ||
113 | list_for_each_entry_safe(node, tmp, &all_stat_sessions, session_list) { | ||
114 | if (node->ts == trace) { | ||
115 | list_del(&node->session_list); | ||
116 | destroy_session(node); | ||
117 | break; | ||
118 | } | ||
119 | } | ||
120 | mutex_unlock(&all_stat_sessions_mutex); | ||
121 | } | ||
122 | |||
123 | |||
124 | /* | 59 | /* |
125 | * For tracers that don't provide a stat_cmp callback. | 60 | * For tracers that don't provide a stat_cmp callback. |
126 | * This one will force an immediate insertion on tail of | 61 | * This one will force an immediate insertion on tail of |
@@ -252,10 +187,10 @@ static int stat_seq_show(struct seq_file *s, void *v) | |||
252 | } | 187 | } |
253 | 188 | ||
254 | static const struct seq_operations trace_stat_seq_ops = { | 189 | static const struct seq_operations trace_stat_seq_ops = { |
255 | .start = stat_seq_start, | 190 | .start = stat_seq_start, |
256 | .next = stat_seq_next, | 191 | .next = stat_seq_next, |
257 | .stop = stat_seq_stop, | 192 | .stop = stat_seq_stop, |
258 | .show = stat_seq_show | 193 | .show = stat_seq_show |
259 | }; | 194 | }; |
260 | 195 | ||
261 | /* The session stat is refilled and resorted at each stat file opening */ | 196 | /* The session stat is refilled and resorted at each stat file opening */ |
@@ -275,7 +210,6 @@ static int tracing_stat_open(struct inode *inode, struct file *file) | |||
275 | return ret; | 210 | return ret; |
276 | } | 211 | } |
277 | 212 | ||
278 | |||
279 | /* | 213 | /* |
280 | * Avoid consuming memory with our now useless list. | 214 | * Avoid consuming memory with our now useless list. |
281 | */ | 215 | */ |
@@ -322,3 +256,64 @@ static int init_stat_file(struct tracer_stat_session *session) | |||
322 | return -ENOMEM; | 256 | return -ENOMEM; |
323 | return 0; | 257 | return 0; |
324 | } | 258 | } |
259 | |||
260 | int register_stat_tracer(struct tracer_stat *trace) | ||
261 | { | ||
262 | struct tracer_stat_session *session, *node, *tmp; | ||
263 | int ret; | ||
264 | |||
265 | if (!trace) | ||
266 | return -EINVAL; | ||
267 | |||
268 | if (!trace->stat_start || !trace->stat_next || !trace->stat_show) | ||
269 | return -EINVAL; | ||
270 | |||
271 | /* Already registered? */ | ||
272 | mutex_lock(&all_stat_sessions_mutex); | ||
273 | list_for_each_entry_safe(node, tmp, &all_stat_sessions, session_list) { | ||
274 | if (node->ts == trace) { | ||
275 | mutex_unlock(&all_stat_sessions_mutex); | ||
276 | return -EINVAL; | ||
277 | } | ||
278 | } | ||
279 | mutex_unlock(&all_stat_sessions_mutex); | ||
280 | |||
281 | /* Init the session */ | ||
282 | session = kmalloc(sizeof(struct tracer_stat_session), GFP_KERNEL); | ||
283 | if (!session) | ||
284 | return -ENOMEM; | ||
285 | |||
286 | session->ts = trace; | ||
287 | INIT_LIST_HEAD(&session->session_list); | ||
288 | INIT_LIST_HEAD(&session->stat_list); | ||
289 | mutex_init(&session->stat_mutex); | ||
290 | session->file = NULL; | ||
291 | |||
292 | ret = init_stat_file(session); | ||
293 | if (ret) { | ||
294 | destroy_session(session); | ||
295 | return ret; | ||
296 | } | ||
297 | |||
298 | /* Register */ | ||
299 | mutex_lock(&all_stat_sessions_mutex); | ||
300 | list_add_tail(&session->session_list, &all_stat_sessions); | ||
301 | mutex_unlock(&all_stat_sessions_mutex); | ||
302 | |||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | void unregister_stat_tracer(struct tracer_stat *trace) | ||
307 | { | ||
308 | struct tracer_stat_session *node, *tmp; | ||
309 | |||
310 | mutex_lock(&all_stat_sessions_mutex); | ||
311 | list_for_each_entry_safe(node, tmp, &all_stat_sessions, session_list) { | ||
312 | if (node->ts == trace) { | ||
313 | list_del(&node->session_list); | ||
314 | destroy_session(node); | ||
315 | break; | ||
316 | } | ||
317 | } | ||
318 | mutex_unlock(&all_stat_sessions_mutex); | ||
319 | } | ||