diff options
author | Ingo Molnar <mingo@elte.hu> | 2011-06-04 06:13:06 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-06-04 06:13:06 -0400 |
commit | 710054ba25c0d1f8f41c22ce13ba336503fb5318 (patch) | |
tree | f9b09b722bf511841539173d946f90a20fc2e59a /kernel/trace | |
parent | 74c355fbdfedd3820046dba4f537876cea54c207 (diff) | |
parent | b273fa9716aa1564bee88ceee62f9042981cdc81 (diff) |
Merge branch 'perf/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Diffstat (limited to 'kernel/trace')
-rw-r--r-- | kernel/trace/ftrace.c | 31 | ||||
-rw-r--r-- | kernel/trace/ring_buffer.c | 10 | ||||
-rw-r--r-- | kernel/trace/trace.h | 15 | ||||
-rw-r--r-- | kernel/trace/trace_events.c | 7 | ||||
-rw-r--r-- | kernel/trace/trace_output.c | 27 |
5 files changed, 77 insertions, 13 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index d017c2c82c44..1ee417fcbfa5 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -109,12 +109,18 @@ ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip); | |||
109 | static void ftrace_global_list_func(unsigned long ip, | 109 | static void ftrace_global_list_func(unsigned long ip, |
110 | unsigned long parent_ip) | 110 | unsigned long parent_ip) |
111 | { | 111 | { |
112 | struct ftrace_ops *op = rcu_dereference_raw(ftrace_global_list); /*see above*/ | 112 | struct ftrace_ops *op; |
113 | |||
114 | if (unlikely(trace_recursion_test(TRACE_GLOBAL_BIT))) | ||
115 | return; | ||
113 | 116 | ||
117 | trace_recursion_set(TRACE_GLOBAL_BIT); | ||
118 | op = rcu_dereference_raw(ftrace_global_list); /*see above*/ | ||
114 | while (op != &ftrace_list_end) { | 119 | while (op != &ftrace_list_end) { |
115 | op->func(ip, parent_ip); | 120 | op->func(ip, parent_ip); |
116 | op = rcu_dereference_raw(op->next); /*see above*/ | 121 | op = rcu_dereference_raw(op->next); /*see above*/ |
117 | }; | 122 | }; |
123 | trace_recursion_clear(TRACE_GLOBAL_BIT); | ||
118 | } | 124 | } |
119 | 125 | ||
120 | static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip) | 126 | static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip) |
@@ -1638,12 +1644,12 @@ static void ftrace_startup_enable(int command) | |||
1638 | ftrace_run_update_code(command); | 1644 | ftrace_run_update_code(command); |
1639 | } | 1645 | } |
1640 | 1646 | ||
1641 | static void ftrace_startup(struct ftrace_ops *ops, int command) | 1647 | static int ftrace_startup(struct ftrace_ops *ops, int command) |
1642 | { | 1648 | { |
1643 | bool hash_enable = true; | 1649 | bool hash_enable = true; |
1644 | 1650 | ||
1645 | if (unlikely(ftrace_disabled)) | 1651 | if (unlikely(ftrace_disabled)) |
1646 | return; | 1652 | return -ENODEV; |
1647 | 1653 | ||
1648 | ftrace_start_up++; | 1654 | ftrace_start_up++; |
1649 | command |= FTRACE_ENABLE_CALLS; | 1655 | command |= FTRACE_ENABLE_CALLS; |
@@ -1662,6 +1668,8 @@ static void ftrace_startup(struct ftrace_ops *ops, int command) | |||
1662 | ftrace_hash_rec_enable(ops, 1); | 1668 | ftrace_hash_rec_enable(ops, 1); |
1663 | 1669 | ||
1664 | ftrace_startup_enable(command); | 1670 | ftrace_startup_enable(command); |
1671 | |||
1672 | return 0; | ||
1665 | } | 1673 | } |
1666 | 1674 | ||
1667 | static void ftrace_shutdown(struct ftrace_ops *ops, int command) | 1675 | static void ftrace_shutdown(struct ftrace_ops *ops, int command) |
@@ -2501,7 +2509,7 @@ static void __enable_ftrace_function_probe(void) | |||
2501 | 2509 | ||
2502 | ret = __register_ftrace_function(&trace_probe_ops); | 2510 | ret = __register_ftrace_function(&trace_probe_ops); |
2503 | if (!ret) | 2511 | if (!ret) |
2504 | ftrace_startup(&trace_probe_ops, 0); | 2512 | ret = ftrace_startup(&trace_probe_ops, 0); |
2505 | 2513 | ||
2506 | ftrace_probe_registered = 1; | 2514 | ftrace_probe_registered = 1; |
2507 | } | 2515 | } |
@@ -3466,7 +3474,11 @@ device_initcall(ftrace_nodyn_init); | |||
3466 | static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; } | 3474 | static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; } |
3467 | static inline void ftrace_startup_enable(int command) { } | 3475 | static inline void ftrace_startup_enable(int command) { } |
3468 | /* Keep as macros so we do not need to define the commands */ | 3476 | /* Keep as macros so we do not need to define the commands */ |
3469 | # define ftrace_startup(ops, command) do { } while (0) | 3477 | # define ftrace_startup(ops, command) \ |
3478 | ({ \ | ||
3479 | (ops)->flags |= FTRACE_OPS_FL_ENABLED; \ | ||
3480 | 0; \ | ||
3481 | }) | ||
3470 | # define ftrace_shutdown(ops, command) do { } while (0) | 3482 | # define ftrace_shutdown(ops, command) do { } while (0) |
3471 | # define ftrace_startup_sysctl() do { } while (0) | 3483 | # define ftrace_startup_sysctl() do { } while (0) |
3472 | # define ftrace_shutdown_sysctl() do { } while (0) | 3484 | # define ftrace_shutdown_sysctl() do { } while (0) |
@@ -3484,6 +3496,10 @@ ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip) | |||
3484 | { | 3496 | { |
3485 | struct ftrace_ops *op; | 3497 | struct ftrace_ops *op; |
3486 | 3498 | ||
3499 | if (unlikely(trace_recursion_test(TRACE_INTERNAL_BIT))) | ||
3500 | return; | ||
3501 | |||
3502 | trace_recursion_set(TRACE_INTERNAL_BIT); | ||
3487 | /* | 3503 | /* |
3488 | * Some of the ops may be dynamically allocated, | 3504 | * Some of the ops may be dynamically allocated, |
3489 | * they must be freed after a synchronize_sched(). | 3505 | * they must be freed after a synchronize_sched(). |
@@ -3496,6 +3512,7 @@ ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip) | |||
3496 | op = rcu_dereference_raw(op->next); | 3512 | op = rcu_dereference_raw(op->next); |
3497 | }; | 3513 | }; |
3498 | preempt_enable_notrace(); | 3514 | preempt_enable_notrace(); |
3515 | trace_recursion_clear(TRACE_INTERNAL_BIT); | ||
3499 | } | 3516 | } |
3500 | 3517 | ||
3501 | static void clear_ftrace_swapper(void) | 3518 | static void clear_ftrace_swapper(void) |
@@ -3799,7 +3816,7 @@ int register_ftrace_function(struct ftrace_ops *ops) | |||
3799 | 3816 | ||
3800 | ret = __register_ftrace_function(ops); | 3817 | ret = __register_ftrace_function(ops); |
3801 | if (!ret) | 3818 | if (!ret) |
3802 | ftrace_startup(ops, 0); | 3819 | ret = ftrace_startup(ops, 0); |
3803 | 3820 | ||
3804 | 3821 | ||
3805 | out_unlock: | 3822 | out_unlock: |
@@ -4045,7 +4062,7 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc, | |||
4045 | ftrace_graph_return = retfunc; | 4062 | ftrace_graph_return = retfunc; |
4046 | ftrace_graph_entry = entryfunc; | 4063 | ftrace_graph_entry = entryfunc; |
4047 | 4064 | ||
4048 | ftrace_startup(&global_ops, FTRACE_START_FUNC_RET); | 4065 | ret = ftrace_startup(&global_ops, FTRACE_START_FUNC_RET); |
4049 | 4066 | ||
4050 | out: | 4067 | out: |
4051 | mutex_unlock(&ftrace_lock); | 4068 | mutex_unlock(&ftrace_lock); |
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 0ef7b4b2a1f7..b0c7aa407943 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -2216,7 +2216,7 @@ static noinline void trace_recursive_fail(void) | |||
2216 | 2216 | ||
2217 | printk_once(KERN_WARNING "Tracing recursion: depth[%ld]:" | 2217 | printk_once(KERN_WARNING "Tracing recursion: depth[%ld]:" |
2218 | "HC[%lu]:SC[%lu]:NMI[%lu]\n", | 2218 | "HC[%lu]:SC[%lu]:NMI[%lu]\n", |
2219 | current->trace_recursion, | 2219 | trace_recursion_buffer(), |
2220 | hardirq_count() >> HARDIRQ_SHIFT, | 2220 | hardirq_count() >> HARDIRQ_SHIFT, |
2221 | softirq_count() >> SOFTIRQ_SHIFT, | 2221 | softirq_count() >> SOFTIRQ_SHIFT, |
2222 | in_nmi()); | 2222 | in_nmi()); |
@@ -2226,9 +2226,9 @@ static noinline void trace_recursive_fail(void) | |||
2226 | 2226 | ||
2227 | static inline int trace_recursive_lock(void) | 2227 | static inline int trace_recursive_lock(void) |
2228 | { | 2228 | { |
2229 | current->trace_recursion++; | 2229 | trace_recursion_inc(); |
2230 | 2230 | ||
2231 | if (likely(current->trace_recursion < TRACE_RECURSIVE_DEPTH)) | 2231 | if (likely(trace_recursion_buffer() < TRACE_RECURSIVE_DEPTH)) |
2232 | return 0; | 2232 | return 0; |
2233 | 2233 | ||
2234 | trace_recursive_fail(); | 2234 | trace_recursive_fail(); |
@@ -2238,9 +2238,9 @@ static inline int trace_recursive_lock(void) | |||
2238 | 2238 | ||
2239 | static inline void trace_recursive_unlock(void) | 2239 | static inline void trace_recursive_unlock(void) |
2240 | { | 2240 | { |
2241 | WARN_ON_ONCE(!current->trace_recursion); | 2241 | WARN_ON_ONCE(!trace_recursion_buffer()); |
2242 | 2242 | ||
2243 | current->trace_recursion--; | 2243 | trace_recursion_dec(); |
2244 | } | 2244 | } |
2245 | 2245 | ||
2246 | #else | 2246 | #else |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 6b69c4bd306f..229f8591f61d 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -784,4 +784,19 @@ extern const char *__stop___trace_bprintk_fmt[]; | |||
784 | FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print)) | 784 | FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print)) |
785 | #include "trace_entries.h" | 785 | #include "trace_entries.h" |
786 | 786 | ||
787 | /* Only current can touch trace_recursion */ | ||
788 | #define trace_recursion_inc() do { (current)->trace_recursion++; } while (0) | ||
789 | #define trace_recursion_dec() do { (current)->trace_recursion--; } while (0) | ||
790 | |||
791 | /* Ring buffer has the 10 LSB bits to count */ | ||
792 | #define trace_recursion_buffer() ((current)->trace_recursion & 0x3ff) | ||
793 | |||
794 | /* for function tracing recursion */ | ||
795 | #define TRACE_INTERNAL_BIT (1<<11) | ||
796 | #define TRACE_GLOBAL_BIT (1<<12) | ||
797 | |||
798 | #define trace_recursion_set(bit) do { (current)->trace_recursion |= (bit); } while (0) | ||
799 | #define trace_recursion_clear(bit) do { (current)->trace_recursion &= ~(bit); } while (0) | ||
800 | #define trace_recursion_test(bit) ((current)->trace_recursion & (bit)) | ||
801 | |||
787 | #endif /* _LINUX_KERNEL_TRACE_H */ | 802 | #endif /* _LINUX_KERNEL_TRACE_H */ |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 2fe110341359..686ec399f2a8 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -1657,7 +1657,12 @@ static struct ftrace_ops trace_ops __initdata = | |||
1657 | 1657 | ||
1658 | static __init void event_trace_self_test_with_function(void) | 1658 | static __init void event_trace_self_test_with_function(void) |
1659 | { | 1659 | { |
1660 | register_ftrace_function(&trace_ops); | 1660 | int ret; |
1661 | ret = register_ftrace_function(&trace_ops); | ||
1662 | if (WARN_ON(ret < 0)) { | ||
1663 | pr_info("Failed to enable function tracer for event tests\n"); | ||
1664 | return; | ||
1665 | } | ||
1661 | pr_info("Running tests again, along with the function tracer\n"); | 1666 | pr_info("Running tests again, along with the function tracer\n"); |
1662 | event_trace_self_tests(); | 1667 | event_trace_self_tests(); |
1663 | unregister_ftrace_function(&trace_ops); | 1668 | unregister_ftrace_function(&trace_ops); |
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index cf535ccedc86..e37de492a9e1 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c | |||
@@ -353,6 +353,33 @@ ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val, | |||
353 | } | 353 | } |
354 | EXPORT_SYMBOL(ftrace_print_symbols_seq); | 354 | EXPORT_SYMBOL(ftrace_print_symbols_seq); |
355 | 355 | ||
356 | #if BITS_PER_LONG == 32 | ||
357 | const char * | ||
358 | ftrace_print_symbols_seq_u64(struct trace_seq *p, unsigned long long val, | ||
359 | const struct trace_print_flags_u64 *symbol_array) | ||
360 | { | ||
361 | int i; | ||
362 | const char *ret = p->buffer + p->len; | ||
363 | |||
364 | for (i = 0; symbol_array[i].name; i++) { | ||
365 | |||
366 | if (val != symbol_array[i].mask) | ||
367 | continue; | ||
368 | |||
369 | trace_seq_puts(p, symbol_array[i].name); | ||
370 | break; | ||
371 | } | ||
372 | |||
373 | if (!p->len) | ||
374 | trace_seq_printf(p, "0x%llx", val); | ||
375 | |||
376 | trace_seq_putc(p, 0); | ||
377 | |||
378 | return ret; | ||
379 | } | ||
380 | EXPORT_SYMBOL(ftrace_print_symbols_seq_u64); | ||
381 | #endif | ||
382 | |||
356 | const char * | 383 | const char * |
357 | ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len) | 384 | ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len) |
358 | { | 385 | { |