diff options
Diffstat (limited to 'kernel/trace/trace_events.c')
-rw-r--r-- | kernel/trace/trace_events.c | 85 |
1 files changed, 32 insertions, 53 deletions
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 78b1ed230177..56c260b83a9c 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | #include "trace_output.h" | 22 | #include "trace_output.h" |
23 | 23 | ||
24 | #undef TRACE_SYSTEM | ||
24 | #define TRACE_SYSTEM "TRACE_SYSTEM" | 25 | #define TRACE_SYSTEM "TRACE_SYSTEM" |
25 | 26 | ||
26 | DEFINE_MUTEX(event_mutex); | 27 | DEFINE_MUTEX(event_mutex); |
@@ -86,7 +87,7 @@ int trace_define_common_fields(struct ftrace_event_call *call) | |||
86 | __common_field(unsigned char, flags); | 87 | __common_field(unsigned char, flags); |
87 | __common_field(unsigned char, preempt_count); | 88 | __common_field(unsigned char, preempt_count); |
88 | __common_field(int, pid); | 89 | __common_field(int, pid); |
89 | __common_field(int, tgid); | 90 | __common_field(int, lock_depth); |
90 | 91 | ||
91 | return ret; | 92 | return ret; |
92 | } | 93 | } |
@@ -230,11 +231,9 @@ static ssize_t | |||
230 | ftrace_event_write(struct file *file, const char __user *ubuf, | 231 | ftrace_event_write(struct file *file, const char __user *ubuf, |
231 | size_t cnt, loff_t *ppos) | 232 | size_t cnt, loff_t *ppos) |
232 | { | 233 | { |
234 | struct trace_parser parser; | ||
233 | size_t read = 0; | 235 | size_t read = 0; |
234 | int i, set = 1; | ||
235 | ssize_t ret; | 236 | ssize_t ret; |
236 | char *buf; | ||
237 | char ch; | ||
238 | 237 | ||
239 | if (!cnt || cnt < 0) | 238 | if (!cnt || cnt < 0) |
240 | return 0; | 239 | return 0; |
@@ -243,60 +242,28 @@ ftrace_event_write(struct file *file, const char __user *ubuf, | |||
243 | if (ret < 0) | 242 | if (ret < 0) |
244 | return ret; | 243 | return ret; |
245 | 244 | ||
246 | ret = get_user(ch, ubuf++); | 245 | if (trace_parser_get_init(&parser, EVENT_BUF_SIZE + 1)) |
247 | if (ret) | ||
248 | return ret; | ||
249 | read++; | ||
250 | cnt--; | ||
251 | |||
252 | /* skip white space */ | ||
253 | while (cnt && isspace(ch)) { | ||
254 | ret = get_user(ch, ubuf++); | ||
255 | if (ret) | ||
256 | return ret; | ||
257 | read++; | ||
258 | cnt--; | ||
259 | } | ||
260 | |||
261 | /* Only white space found? */ | ||
262 | if (isspace(ch)) { | ||
263 | file->f_pos += read; | ||
264 | ret = read; | ||
265 | return ret; | ||
266 | } | ||
267 | |||
268 | buf = kmalloc(EVENT_BUF_SIZE+1, GFP_KERNEL); | ||
269 | if (!buf) | ||
270 | return -ENOMEM; | 246 | return -ENOMEM; |
271 | 247 | ||
272 | if (cnt > EVENT_BUF_SIZE) | 248 | read = trace_get_user(&parser, ubuf, cnt, ppos); |
273 | cnt = EVENT_BUF_SIZE; | 249 | |
250 | if (trace_parser_loaded((&parser))) { | ||
251 | int set = 1; | ||
274 | 252 | ||
275 | i = 0; | 253 | if (*parser.buffer == '!') |
276 | while (cnt && !isspace(ch)) { | ||
277 | if (!i && ch == '!') | ||
278 | set = 0; | 254 | set = 0; |
279 | else | ||
280 | buf[i++] = ch; | ||
281 | 255 | ||
282 | ret = get_user(ch, ubuf++); | 256 | parser.buffer[parser.idx] = 0; |
257 | |||
258 | ret = ftrace_set_clr_event(parser.buffer + !set, set); | ||
283 | if (ret) | 259 | if (ret) |
284 | goto out_free; | 260 | goto out_put; |
285 | read++; | ||
286 | cnt--; | ||
287 | } | 261 | } |
288 | buf[i] = 0; | ||
289 | |||
290 | file->f_pos += read; | ||
291 | |||
292 | ret = ftrace_set_clr_event(buf, set); | ||
293 | if (ret) | ||
294 | goto out_free; | ||
295 | 262 | ||
296 | ret = read; | 263 | ret = read; |
297 | 264 | ||
298 | out_free: | 265 | out_put: |
299 | kfree(buf); | 266 | trace_parser_put(&parser); |
300 | 267 | ||
301 | return ret; | 268 | return ret; |
302 | } | 269 | } |
@@ -578,7 +545,7 @@ static int trace_write_header(struct trace_seq *s) | |||
578 | FIELD(unsigned char, flags), | 545 | FIELD(unsigned char, flags), |
579 | FIELD(unsigned char, preempt_count), | 546 | FIELD(unsigned char, preempt_count), |
580 | FIELD(int, pid), | 547 | FIELD(int, pid), |
581 | FIELD(int, tgid)); | 548 | FIELD(int, lock_depth)); |
582 | } | 549 | } |
583 | 550 | ||
584 | static ssize_t | 551 | static ssize_t |
@@ -1187,7 +1154,7 @@ static int trace_module_notify(struct notifier_block *self, | |||
1187 | } | 1154 | } |
1188 | #endif /* CONFIG_MODULES */ | 1155 | #endif /* CONFIG_MODULES */ |
1189 | 1156 | ||
1190 | struct notifier_block trace_module_nb = { | 1157 | static struct notifier_block trace_module_nb = { |
1191 | .notifier_call = trace_module_notify, | 1158 | .notifier_call = trace_module_notify, |
1192 | .priority = 0, | 1159 | .priority = 0, |
1193 | }; | 1160 | }; |
@@ -1359,6 +1326,18 @@ static __init void event_trace_self_tests(void) | |||
1359 | if (!call->regfunc) | 1326 | if (!call->regfunc) |
1360 | continue; | 1327 | continue; |
1361 | 1328 | ||
1329 | /* | ||
1330 | * Testing syscall events here is pretty useless, but | ||
1331 | * we still do it if configured. But this is time consuming. | ||
1332 | * What we really need is a user thread to perform the | ||
1333 | * syscalls as we test. | ||
1334 | */ | ||
1335 | #ifndef CONFIG_EVENT_TRACE_TEST_SYSCALLS | ||
1336 | if (call->system && | ||
1337 | strcmp(call->system, "syscalls") == 0) | ||
1338 | continue; | ||
1339 | #endif | ||
1340 | |||
1362 | pr_info("Testing event %s: ", call->name); | 1341 | pr_info("Testing event %s: ", call->name); |
1363 | 1342 | ||
1364 | /* | 1343 | /* |
@@ -1432,7 +1411,7 @@ static __init void event_trace_self_tests(void) | |||
1432 | 1411 | ||
1433 | #ifdef CONFIG_FUNCTION_TRACER | 1412 | #ifdef CONFIG_FUNCTION_TRACER |
1434 | 1413 | ||
1435 | static DEFINE_PER_CPU(atomic_t, test_event_disable); | 1414 | static DEFINE_PER_CPU(atomic_t, ftrace_test_event_disable); |
1436 | 1415 | ||
1437 | static void | 1416 | static void |
1438 | function_test_events_call(unsigned long ip, unsigned long parent_ip) | 1417 | function_test_events_call(unsigned long ip, unsigned long parent_ip) |
@@ -1449,7 +1428,7 @@ function_test_events_call(unsigned long ip, unsigned long parent_ip) | |||
1449 | pc = preempt_count(); | 1428 | pc = preempt_count(); |
1450 | resched = ftrace_preempt_disable(); | 1429 | resched = ftrace_preempt_disable(); |
1451 | cpu = raw_smp_processor_id(); | 1430 | cpu = raw_smp_processor_id(); |
1452 | disabled = atomic_inc_return(&per_cpu(test_event_disable, cpu)); | 1431 | disabled = atomic_inc_return(&per_cpu(ftrace_test_event_disable, cpu)); |
1453 | 1432 | ||
1454 | if (disabled != 1) | 1433 | if (disabled != 1) |
1455 | goto out; | 1434 | goto out; |
@@ -1468,7 +1447,7 @@ function_test_events_call(unsigned long ip, unsigned long parent_ip) | |||
1468 | trace_nowake_buffer_unlock_commit(buffer, event, flags, pc); | 1447 | trace_nowake_buffer_unlock_commit(buffer, event, flags, pc); |
1469 | 1448 | ||
1470 | out: | 1449 | out: |
1471 | atomic_dec(&per_cpu(test_event_disable, cpu)); | 1450 | atomic_dec(&per_cpu(ftrace_test_event_disable, cpu)); |
1472 | ftrace_preempt_enable(resched); | 1451 | ftrace_preempt_enable(resched); |
1473 | } | 1452 | } |
1474 | 1453 | ||