diff options
-rw-r--r-- | include/linux/ftrace_event.h | 4 | ||||
-rw-r--r-- | include/linux/kernel.h | 3 | ||||
-rw-r--r-- | include/linux/syscalls.h | 6 | ||||
-rw-r--r-- | include/trace/ftrace.h | 56 | ||||
-rw-r--r-- | kernel/trace/ftrace.c | 30 | ||||
-rw-r--r-- | kernel/trace/power-traces.c | 2 | ||||
-rw-r--r-- | kernel/trace/ring_buffer.c | 29 | ||||
-rw-r--r-- | kernel/trace/trace.c | 182 | ||||
-rw-r--r-- | kernel/trace/trace.h | 23 | ||||
-rw-r--r-- | kernel/trace/trace_event_profile.c | 6 | ||||
-rw-r--r-- | kernel/trace/trace_events.c | 41 | ||||
-rw-r--r-- | kernel/trace/trace_export.c | 4 | ||||
-rw-r--r-- | kernel/trace/trace_irqsoff.c | 2 | ||||
-rw-r--r-- | kernel/trace/trace_kprobe.c | 9 | ||||
-rw-r--r-- | kernel/trace/trace_ksym.c | 56 | ||||
-rw-r--r-- | kernel/trace/trace_syscalls.c | 18 |
16 files changed, 196 insertions, 275 deletions
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 38f8d6553831..2233c98d80df 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h | |||
@@ -131,7 +131,7 @@ struct ftrace_event_call { | |||
131 | void *mod; | 131 | void *mod; |
132 | void *data; | 132 | void *data; |
133 | 133 | ||
134 | atomic_t profile_count; | 134 | int profile_count; |
135 | int (*profile_enable)(struct ftrace_event_call *); | 135 | int (*profile_enable)(struct ftrace_event_call *); |
136 | void (*profile_disable)(struct ftrace_event_call *); | 136 | void (*profile_disable)(struct ftrace_event_call *); |
137 | }; | 137 | }; |
@@ -158,7 +158,7 @@ enum { | |||
158 | FILTER_PTR_STRING, | 158 | FILTER_PTR_STRING, |
159 | }; | 159 | }; |
160 | 160 | ||
161 | extern int trace_define_common_fields(struct ftrace_event_call *call); | 161 | extern int trace_event_raw_init(struct ftrace_event_call *call); |
162 | extern int trace_define_field(struct ftrace_event_call *call, const char *type, | 162 | extern int trace_define_field(struct ftrace_event_call *call, const char *type, |
163 | const char *name, int offset, int size, | 163 | const char *name, int offset, int size, |
164 | int is_signed, int filter_type); | 164 | int is_signed, int filter_type); |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 4d9c916d06d9..3fc9f5aab5f8 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -535,6 +535,8 @@ extern int | |||
535 | __trace_printk(unsigned long ip, const char *fmt, ...) | 535 | __trace_printk(unsigned long ip, const char *fmt, ...) |
536 | __attribute__ ((format (printf, 2, 3))); | 536 | __attribute__ ((format (printf, 2, 3))); |
537 | 537 | ||
538 | extern void trace_dump_stack(void); | ||
539 | |||
538 | /* | 540 | /* |
539 | * The double __builtin_constant_p is because gcc will give us an error | 541 | * The double __builtin_constant_p is because gcc will give us an error |
540 | * if we try to allocate the static variable to fmt if it is not a | 542 | * if we try to allocate the static variable to fmt if it is not a |
@@ -568,6 +570,7 @@ trace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); | |||
568 | static inline void tracing_start(void) { } | 570 | static inline void tracing_start(void) { } |
569 | static inline void tracing_stop(void) { } | 571 | static inline void tracing_stop(void) { } |
570 | static inline void ftrace_off_permanent(void) { } | 572 | static inline void ftrace_off_permanent(void) { } |
573 | static inline void trace_dump_stack(void) { } | ||
571 | static inline int | 574 | static inline int |
572 | trace_printk(const char *fmt, ...) | 575 | trace_printk(const char *fmt, ...) |
573 | { | 576 | { |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 939a61507ac5..65793e90d6f6 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -102,12 +102,10 @@ struct perf_event_attr; | |||
102 | #ifdef CONFIG_EVENT_PROFILE | 102 | #ifdef CONFIG_EVENT_PROFILE |
103 | 103 | ||
104 | #define TRACE_SYS_ENTER_PROFILE_INIT(sname) \ | 104 | #define TRACE_SYS_ENTER_PROFILE_INIT(sname) \ |
105 | .profile_count = ATOMIC_INIT(-1), \ | ||
106 | .profile_enable = prof_sysenter_enable, \ | 105 | .profile_enable = prof_sysenter_enable, \ |
107 | .profile_disable = prof_sysenter_disable, | 106 | .profile_disable = prof_sysenter_disable, |
108 | 107 | ||
109 | #define TRACE_SYS_EXIT_PROFILE_INIT(sname) \ | 108 | #define TRACE_SYS_EXIT_PROFILE_INIT(sname) \ |
110 | .profile_count = ATOMIC_INIT(-1), \ | ||
111 | .profile_enable = prof_sysexit_enable, \ | 109 | .profile_enable = prof_sysexit_enable, \ |
112 | .profile_disable = prof_sysexit_disable, | 110 | .profile_disable = prof_sysexit_disable, |
113 | #else | 111 | #else |
@@ -145,7 +143,7 @@ struct perf_event_attr; | |||
145 | .name = "sys_enter"#sname, \ | 143 | .name = "sys_enter"#sname, \ |
146 | .system = "syscalls", \ | 144 | .system = "syscalls", \ |
147 | .event = &enter_syscall_print_##sname, \ | 145 | .event = &enter_syscall_print_##sname, \ |
148 | .raw_init = init_syscall_trace, \ | 146 | .raw_init = trace_event_raw_init, \ |
149 | .show_format = syscall_enter_format, \ | 147 | .show_format = syscall_enter_format, \ |
150 | .define_fields = syscall_enter_define_fields, \ | 148 | .define_fields = syscall_enter_define_fields, \ |
151 | .regfunc = reg_event_syscall_enter, \ | 149 | .regfunc = reg_event_syscall_enter, \ |
@@ -167,7 +165,7 @@ struct perf_event_attr; | |||
167 | .name = "sys_exit"#sname, \ | 165 | .name = "sys_exit"#sname, \ |
168 | .system = "syscalls", \ | 166 | .system = "syscalls", \ |
169 | .event = &exit_syscall_print_##sname, \ | 167 | .event = &exit_syscall_print_##sname, \ |
170 | .raw_init = init_syscall_trace, \ | 168 | .raw_init = trace_event_raw_init, \ |
171 | .show_format = syscall_exit_format, \ | 169 | .show_format = syscall_exit_format, \ |
172 | .define_fields = syscall_exit_define_fields, \ | 170 | .define_fields = syscall_exit_define_fields, \ |
173 | .regfunc = reg_event_syscall_exit, \ | 171 | .regfunc = reg_event_syscall_exit, \ |
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index d1b3de9c1a71..73523151a731 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h | |||
@@ -436,10 +436,6 @@ ftrace_define_fields_##call(struct ftrace_event_call *event_call) \ | |||
436 | struct ftrace_raw_##call field; \ | 436 | struct ftrace_raw_##call field; \ |
437 | int ret; \ | 437 | int ret; \ |
438 | \ | 438 | \ |
439 | ret = trace_define_common_fields(event_call); \ | ||
440 | if (ret) \ | ||
441 | return ret; \ | ||
442 | \ | ||
443 | tstruct; \ | 439 | tstruct; \ |
444 | \ | 440 | \ |
445 | return ret; \ | 441 | return ret; \ |
@@ -559,13 +555,7 @@ static void ftrace_profile_disable_##name(struct ftrace_event_call *unused)\ | |||
559 | * | 555 | * |
560 | * static int ftrace_reg_event_<call>(struct ftrace_event_call *unused) | 556 | * static int ftrace_reg_event_<call>(struct ftrace_event_call *unused) |
561 | * { | 557 | * { |
562 | * int ret; | 558 | * return register_trace_<call>(ftrace_event_<call>); |
563 | * | ||
564 | * ret = register_trace_<call>(ftrace_event_<call>); | ||
565 | * if (!ret) | ||
566 | * pr_info("event trace: Could not activate trace point " | ||
567 | * "probe to <call>"); | ||
568 | * return ret; | ||
569 | * } | 559 | * } |
570 | * | 560 | * |
571 | * static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused) | 561 | * static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused) |
@@ -623,23 +613,12 @@ static void ftrace_profile_disable_##name(struct ftrace_event_call *unused)\ | |||
623 | * .trace = ftrace_raw_output_<call>, <-- stage 2 | 613 | * .trace = ftrace_raw_output_<call>, <-- stage 2 |
624 | * }; | 614 | * }; |
625 | * | 615 | * |
626 | * static int ftrace_raw_init_event_<call>(struct ftrace_event_call *unused) | ||
627 | * { | ||
628 | * int id; | ||
629 | * | ||
630 | * id = register_ftrace_event(&ftrace_event_type_<call>); | ||
631 | * if (!id) | ||
632 | * return -ENODEV; | ||
633 | * event_<call>.id = id; | ||
634 | * return 0; | ||
635 | * } | ||
636 | * | ||
637 | * static struct ftrace_event_call __used | 616 | * static struct ftrace_event_call __used |
638 | * __attribute__((__aligned__(4))) | 617 | * __attribute__((__aligned__(4))) |
639 | * __attribute__((section("_ftrace_events"))) event_<call> = { | 618 | * __attribute__((section("_ftrace_events"))) event_<call> = { |
640 | * .name = "<call>", | 619 | * .name = "<call>", |
641 | * .system = "<system>", | 620 | * .system = "<system>", |
642 | * .raw_init = ftrace_raw_init_event_<call>, | 621 | * .raw_init = trace_event_raw_init, |
643 | * .regfunc = ftrace_reg_event_<call>, | 622 | * .regfunc = ftrace_reg_event_<call>, |
644 | * .unregfunc = ftrace_unreg_event_<call>, | 623 | * .unregfunc = ftrace_unreg_event_<call>, |
645 | * .show_format = ftrace_format_<call>, | 624 | * .show_format = ftrace_format_<call>, |
@@ -647,13 +626,9 @@ static void ftrace_profile_disable_##name(struct ftrace_event_call *unused)\ | |||
647 | * | 626 | * |
648 | */ | 627 | */ |
649 | 628 | ||
650 | #undef TP_FMT | ||
651 | #define TP_FMT(fmt, args...) fmt "\n", ##args | ||
652 | |||
653 | #ifdef CONFIG_EVENT_PROFILE | 629 | #ifdef CONFIG_EVENT_PROFILE |
654 | 630 | ||
655 | #define _TRACE_PROFILE_INIT(call) \ | 631 | #define _TRACE_PROFILE_INIT(call) \ |
656 | .profile_count = ATOMIC_INIT(-1), \ | ||
657 | .profile_enable = ftrace_profile_enable_##call, \ | 632 | .profile_enable = ftrace_profile_enable_##call, \ |
658 | .profile_disable = ftrace_profile_disable_##call, | 633 | .profile_disable = ftrace_profile_disable_##call, |
659 | 634 | ||
@@ -728,13 +703,7 @@ static void ftrace_raw_event_##call(proto) \ | |||
728 | \ | 703 | \ |
729 | static int ftrace_raw_reg_event_##call(struct ftrace_event_call *unused)\ | 704 | static int ftrace_raw_reg_event_##call(struct ftrace_event_call *unused)\ |
730 | { \ | 705 | { \ |
731 | int ret; \ | 706 | return register_trace_##call(ftrace_raw_event_##call); \ |
732 | \ | ||
733 | ret = register_trace_##call(ftrace_raw_event_##call); \ | ||
734 | if (ret) \ | ||
735 | pr_info("event trace: Could not activate trace point " \ | ||
736 | "probe to " #call "\n"); \ | ||
737 | return ret; \ | ||
738 | } \ | 707 | } \ |
739 | \ | 708 | \ |
740 | static void ftrace_raw_unreg_event_##call(struct ftrace_event_call *unused)\ | 709 | static void ftrace_raw_unreg_event_##call(struct ftrace_event_call *unused)\ |
@@ -744,19 +713,7 @@ static void ftrace_raw_unreg_event_##call(struct ftrace_event_call *unused)\ | |||
744 | \ | 713 | \ |
745 | static struct trace_event ftrace_event_type_##call = { \ | 714 | static struct trace_event ftrace_event_type_##call = { \ |
746 | .trace = ftrace_raw_output_##call, \ | 715 | .trace = ftrace_raw_output_##call, \ |
747 | }; \ | 716 | }; |
748 | \ | ||
749 | static int ftrace_raw_init_event_##call(struct ftrace_event_call *unused)\ | ||
750 | { \ | ||
751 | int id; \ | ||
752 | \ | ||
753 | id = register_ftrace_event(&ftrace_event_type_##call); \ | ||
754 | if (!id) \ | ||
755 | return -ENODEV; \ | ||
756 | event_##call.id = id; \ | ||
757 | INIT_LIST_HEAD(&event_##call.fields); \ | ||
758 | return 0; \ | ||
759 | } | ||
760 | 717 | ||
761 | #undef DEFINE_EVENT_PRINT | 718 | #undef DEFINE_EVENT_PRINT |
762 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ | 719 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ |
@@ -776,7 +733,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ | |||
776 | .name = #call, \ | 733 | .name = #call, \ |
777 | .system = __stringify(TRACE_SYSTEM), \ | 734 | .system = __stringify(TRACE_SYSTEM), \ |
778 | .event = &ftrace_event_type_##call, \ | 735 | .event = &ftrace_event_type_##call, \ |
779 | .raw_init = ftrace_raw_init_event_##call, \ | 736 | .raw_init = trace_event_raw_init, \ |
780 | .regfunc = ftrace_raw_reg_event_##call, \ | 737 | .regfunc = ftrace_raw_reg_event_##call, \ |
781 | .unregfunc = ftrace_raw_unreg_event_##call, \ | 738 | .unregfunc = ftrace_raw_unreg_event_##call, \ |
782 | .show_format = ftrace_format_##template, \ | 739 | .show_format = ftrace_format_##template, \ |
@@ -793,7 +750,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ | |||
793 | .name = #call, \ | 750 | .name = #call, \ |
794 | .system = __stringify(TRACE_SYSTEM), \ | 751 | .system = __stringify(TRACE_SYSTEM), \ |
795 | .event = &ftrace_event_type_##call, \ | 752 | .event = &ftrace_event_type_##call, \ |
796 | .raw_init = ftrace_raw_init_event_##call, \ | 753 | .raw_init = trace_event_raw_init, \ |
797 | .regfunc = ftrace_raw_reg_event_##call, \ | 754 | .regfunc = ftrace_raw_reg_event_##call, \ |
798 | .unregfunc = ftrace_raw_unreg_event_##call, \ | 755 | .unregfunc = ftrace_raw_unreg_event_##call, \ |
799 | .show_format = ftrace_format_##call, \ | 756 | .show_format = ftrace_format_##call, \ |
@@ -953,7 +910,6 @@ end: \ | |||
953 | perf_swevent_put_recursion_context(rctx); \ | 910 | perf_swevent_put_recursion_context(rctx); \ |
954 | end_recursion: \ | 911 | end_recursion: \ |
955 | local_irq_restore(irq_flags); \ | 912 | local_irq_restore(irq_flags); \ |
956 | \ | ||
957 | } | 913 | } |
958 | 914 | ||
959 | #undef DEFINE_EVENT | 915 | #undef DEFINE_EVENT |
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index e51a1bcb7bed..7968762c8167 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -1724,7 +1724,7 @@ ftrace_match_record(struct dyn_ftrace *rec, char *regex, int len, int type) | |||
1724 | return ftrace_match(str, regex, len, type); | 1724 | return ftrace_match(str, regex, len, type); |
1725 | } | 1725 | } |
1726 | 1726 | ||
1727 | static void ftrace_match_records(char *buff, int len, int enable) | 1727 | static int ftrace_match_records(char *buff, int len, int enable) |
1728 | { | 1728 | { |
1729 | unsigned int search_len; | 1729 | unsigned int search_len; |
1730 | struct ftrace_page *pg; | 1730 | struct ftrace_page *pg; |
@@ -1733,6 +1733,7 @@ static void ftrace_match_records(char *buff, int len, int enable) | |||
1733 | char *search; | 1733 | char *search; |
1734 | int type; | 1734 | int type; |
1735 | int not; | 1735 | int not; |
1736 | int found = 0; | ||
1736 | 1737 | ||
1737 | flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE; | 1738 | flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE; |
1738 | type = filter_parse_regex(buff, len, &search, ¬); | 1739 | type = filter_parse_regex(buff, len, &search, ¬); |
@@ -1750,6 +1751,7 @@ static void ftrace_match_records(char *buff, int len, int enable) | |||
1750 | rec->flags &= ~flag; | 1751 | rec->flags &= ~flag; |
1751 | else | 1752 | else |
1752 | rec->flags |= flag; | 1753 | rec->flags |= flag; |
1754 | found = 1; | ||
1753 | } | 1755 | } |
1754 | /* | 1756 | /* |
1755 | * Only enable filtering if we have a function that | 1757 | * Only enable filtering if we have a function that |
@@ -1759,6 +1761,8 @@ static void ftrace_match_records(char *buff, int len, int enable) | |||
1759 | ftrace_filtered = 1; | 1761 | ftrace_filtered = 1; |
1760 | } while_for_each_ftrace_rec(); | 1762 | } while_for_each_ftrace_rec(); |
1761 | mutex_unlock(&ftrace_lock); | 1763 | mutex_unlock(&ftrace_lock); |
1764 | |||
1765 | return found; | ||
1762 | } | 1766 | } |
1763 | 1767 | ||
1764 | static int | 1768 | static int |
@@ -1780,7 +1784,7 @@ ftrace_match_module_record(struct dyn_ftrace *rec, char *mod, | |||
1780 | return 1; | 1784 | return 1; |
1781 | } | 1785 | } |
1782 | 1786 | ||
1783 | static void ftrace_match_module_records(char *buff, char *mod, int enable) | 1787 | static int ftrace_match_module_records(char *buff, char *mod, int enable) |
1784 | { | 1788 | { |
1785 | unsigned search_len = 0; | 1789 | unsigned search_len = 0; |
1786 | struct ftrace_page *pg; | 1790 | struct ftrace_page *pg; |
@@ -1789,6 +1793,7 @@ static void ftrace_match_module_records(char *buff, char *mod, int enable) | |||
1789 | char *search = buff; | 1793 | char *search = buff; |
1790 | unsigned long flag; | 1794 | unsigned long flag; |
1791 | int not = 0; | 1795 | int not = 0; |
1796 | int found = 0; | ||
1792 | 1797 | ||
1793 | flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE; | 1798 | flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE; |
1794 | 1799 | ||
@@ -1819,12 +1824,15 @@ static void ftrace_match_module_records(char *buff, char *mod, int enable) | |||
1819 | rec->flags &= ~flag; | 1824 | rec->flags &= ~flag; |
1820 | else | 1825 | else |
1821 | rec->flags |= flag; | 1826 | rec->flags |= flag; |
1827 | found = 1; | ||
1822 | } | 1828 | } |
1823 | if (enable && (rec->flags & FTRACE_FL_FILTER)) | 1829 | if (enable && (rec->flags & FTRACE_FL_FILTER)) |
1824 | ftrace_filtered = 1; | 1830 | ftrace_filtered = 1; |
1825 | 1831 | ||
1826 | } while_for_each_ftrace_rec(); | 1832 | } while_for_each_ftrace_rec(); |
1827 | mutex_unlock(&ftrace_lock); | 1833 | mutex_unlock(&ftrace_lock); |
1834 | |||
1835 | return found; | ||
1828 | } | 1836 | } |
1829 | 1837 | ||
1830 | /* | 1838 | /* |
@@ -1853,8 +1861,9 @@ ftrace_mod_callback(char *func, char *cmd, char *param, int enable) | |||
1853 | if (!strlen(mod)) | 1861 | if (!strlen(mod)) |
1854 | return -EINVAL; | 1862 | return -EINVAL; |
1855 | 1863 | ||
1856 | ftrace_match_module_records(func, mod, enable); | 1864 | if (ftrace_match_module_records(func, mod, enable)) |
1857 | return 0; | 1865 | return 0; |
1866 | return -EINVAL; | ||
1858 | } | 1867 | } |
1859 | 1868 | ||
1860 | static struct ftrace_func_command ftrace_mod_cmd = { | 1869 | static struct ftrace_func_command ftrace_mod_cmd = { |
@@ -2151,8 +2160,9 @@ static int ftrace_process_regex(char *buff, int len, int enable) | |||
2151 | func = strsep(&next, ":"); | 2160 | func = strsep(&next, ":"); |
2152 | 2161 | ||
2153 | if (!next) { | 2162 | if (!next) { |
2154 | ftrace_match_records(func, len, enable); | 2163 | if (ftrace_match_records(func, len, enable)) |
2155 | return 0; | 2164 | return 0; |
2165 | return ret; | ||
2156 | } | 2166 | } |
2157 | 2167 | ||
2158 | /* command found */ | 2168 | /* command found */ |
@@ -2198,10 +2208,9 @@ ftrace_regex_write(struct file *file, const char __user *ubuf, | |||
2198 | !trace_parser_cont(parser)) { | 2208 | !trace_parser_cont(parser)) { |
2199 | ret = ftrace_process_regex(parser->buffer, | 2209 | ret = ftrace_process_regex(parser->buffer, |
2200 | parser->idx, enable); | 2210 | parser->idx, enable); |
2211 | trace_parser_clear(parser); | ||
2201 | if (ret) | 2212 | if (ret) |
2202 | goto out_unlock; | 2213 | goto out_unlock; |
2203 | |||
2204 | trace_parser_clear(parser); | ||
2205 | } | 2214 | } |
2206 | 2215 | ||
2207 | ret = read; | 2216 | ret = read; |
@@ -2543,10 +2552,9 @@ ftrace_set_func(unsigned long *array, int *idx, char *buffer) | |||
2543 | exists = true; | 2552 | exists = true; |
2544 | break; | 2553 | break; |
2545 | } | 2554 | } |
2546 | if (!exists) { | 2555 | if (!exists) |
2547 | array[(*idx)++] = rec->ip; | 2556 | array[(*idx)++] = rec->ip; |
2548 | found = 1; | 2557 | found = 1; |
2549 | } | ||
2550 | } | 2558 | } |
2551 | } while_for_each_ftrace_rec(); | 2559 | } while_for_each_ftrace_rec(); |
2552 | 2560 | ||
diff --git a/kernel/trace/power-traces.c b/kernel/trace/power-traces.c index e06c6e3d56a3..9f4f565b01e6 100644 --- a/kernel/trace/power-traces.c +++ b/kernel/trace/power-traces.c | |||
@@ -14,7 +14,5 @@ | |||
14 | #define CREATE_TRACE_POINTS | 14 | #define CREATE_TRACE_POINTS |
15 | #include <trace/events/power.h> | 15 | #include <trace/events/power.h> |
16 | 16 | ||
17 | EXPORT_TRACEPOINT_SYMBOL_GPL(power_start); | ||
18 | EXPORT_TRACEPOINT_SYMBOL_GPL(power_end); | ||
19 | EXPORT_TRACEPOINT_SYMBOL_GPL(power_frequency); | 17 | EXPORT_TRACEPOINT_SYMBOL_GPL(power_frequency); |
20 | 18 | ||
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index f58c9ad15830..2326b04c95c4 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -1193,9 +1193,6 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned nr_pages) | |||
1193 | struct list_head *p; | 1193 | struct list_head *p; |
1194 | unsigned i; | 1194 | unsigned i; |
1195 | 1195 | ||
1196 | atomic_inc(&cpu_buffer->record_disabled); | ||
1197 | synchronize_sched(); | ||
1198 | |||
1199 | spin_lock_irq(&cpu_buffer->reader_lock); | 1196 | spin_lock_irq(&cpu_buffer->reader_lock); |
1200 | rb_head_page_deactivate(cpu_buffer); | 1197 | rb_head_page_deactivate(cpu_buffer); |
1201 | 1198 | ||
@@ -1211,12 +1208,9 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned nr_pages) | |||
1211 | return; | 1208 | return; |
1212 | 1209 | ||
1213 | rb_reset_cpu(cpu_buffer); | 1210 | rb_reset_cpu(cpu_buffer); |
1214 | spin_unlock_irq(&cpu_buffer->reader_lock); | ||
1215 | |||
1216 | rb_check_pages(cpu_buffer); | 1211 | rb_check_pages(cpu_buffer); |
1217 | 1212 | ||
1218 | atomic_dec(&cpu_buffer->record_disabled); | 1213 | spin_unlock_irq(&cpu_buffer->reader_lock); |
1219 | |||
1220 | } | 1214 | } |
1221 | 1215 | ||
1222 | static void | 1216 | static void |
@@ -1227,9 +1221,6 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer, | |||
1227 | struct list_head *p; | 1221 | struct list_head *p; |
1228 | unsigned i; | 1222 | unsigned i; |
1229 | 1223 | ||
1230 | atomic_inc(&cpu_buffer->record_disabled); | ||
1231 | synchronize_sched(); | ||
1232 | |||
1233 | spin_lock_irq(&cpu_buffer->reader_lock); | 1224 | spin_lock_irq(&cpu_buffer->reader_lock); |
1234 | rb_head_page_deactivate(cpu_buffer); | 1225 | rb_head_page_deactivate(cpu_buffer); |
1235 | 1226 | ||
@@ -1242,11 +1233,9 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer, | |||
1242 | list_add_tail(&bpage->list, cpu_buffer->pages); | 1233 | list_add_tail(&bpage->list, cpu_buffer->pages); |
1243 | } | 1234 | } |
1244 | rb_reset_cpu(cpu_buffer); | 1235 | rb_reset_cpu(cpu_buffer); |
1245 | spin_unlock_irq(&cpu_buffer->reader_lock); | ||
1246 | |||
1247 | rb_check_pages(cpu_buffer); | 1236 | rb_check_pages(cpu_buffer); |
1248 | 1237 | ||
1249 | atomic_dec(&cpu_buffer->record_disabled); | 1238 | spin_unlock_irq(&cpu_buffer->reader_lock); |
1250 | } | 1239 | } |
1251 | 1240 | ||
1252 | /** | 1241 | /** |
@@ -1254,11 +1243,6 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer, | |||
1254 | * @buffer: the buffer to resize. | 1243 | * @buffer: the buffer to resize. |
1255 | * @size: the new size. | 1244 | * @size: the new size. |
1256 | * | 1245 | * |
1257 | * The tracer is responsible for making sure that the buffer is | ||
1258 | * not being used while changing the size. | ||
1259 | * Note: We may be able to change the above requirement by using | ||
1260 | * RCU synchronizations. | ||
1261 | * | ||
1262 | * Minimum size is 2 * BUF_PAGE_SIZE. | 1246 | * Minimum size is 2 * BUF_PAGE_SIZE. |
1263 | * | 1247 | * |
1264 | * Returns -1 on failure. | 1248 | * Returns -1 on failure. |
@@ -1290,6 +1274,11 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size) | |||
1290 | if (size == buffer_size) | 1274 | if (size == buffer_size) |
1291 | return size; | 1275 | return size; |
1292 | 1276 | ||
1277 | atomic_inc(&buffer->record_disabled); | ||
1278 | |||
1279 | /* Make sure all writers are done with this buffer. */ | ||
1280 | synchronize_sched(); | ||
1281 | |||
1293 | mutex_lock(&buffer->mutex); | 1282 | mutex_lock(&buffer->mutex); |
1294 | get_online_cpus(); | 1283 | get_online_cpus(); |
1295 | 1284 | ||
@@ -1352,6 +1341,8 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size) | |||
1352 | put_online_cpus(); | 1341 | put_online_cpus(); |
1353 | mutex_unlock(&buffer->mutex); | 1342 | mutex_unlock(&buffer->mutex); |
1354 | 1343 | ||
1344 | atomic_dec(&buffer->record_disabled); | ||
1345 | |||
1355 | return size; | 1346 | return size; |
1356 | 1347 | ||
1357 | free_pages: | 1348 | free_pages: |
@@ -1361,6 +1352,7 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size) | |||
1361 | } | 1352 | } |
1362 | put_online_cpus(); | 1353 | put_online_cpus(); |
1363 | mutex_unlock(&buffer->mutex); | 1354 | mutex_unlock(&buffer->mutex); |
1355 | atomic_dec(&buffer->record_disabled); | ||
1364 | return -ENOMEM; | 1356 | return -ENOMEM; |
1365 | 1357 | ||
1366 | /* | 1358 | /* |
@@ -1370,6 +1362,7 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size) | |||
1370 | out_fail: | 1362 | out_fail: |
1371 | put_online_cpus(); | 1363 | put_online_cpus(); |
1372 | mutex_unlock(&buffer->mutex); | 1364 | mutex_unlock(&buffer->mutex); |
1365 | atomic_dec(&buffer->record_disabled); | ||
1373 | return -1; | 1366 | return -1; |
1374 | } | 1367 | } |
1375 | EXPORT_SYMBOL_GPL(ring_buffer_resize); | 1368 | EXPORT_SYMBOL_GPL(ring_buffer_resize); |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 31118ae16f03..06ba26747d7e 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -313,7 +313,6 @@ static const char *trace_options[] = { | |||
313 | "bin", | 313 | "bin", |
314 | "block", | 314 | "block", |
315 | "stacktrace", | 315 | "stacktrace", |
316 | "sched-tree", | ||
317 | "trace_printk", | 316 | "trace_printk", |
318 | "ftrace_preempt", | 317 | "ftrace_preempt", |
319 | "branch", | 318 | "branch", |
@@ -1151,6 +1150,22 @@ void __trace_stack(struct trace_array *tr, unsigned long flags, int skip, | |||
1151 | __ftrace_trace_stack(tr->buffer, flags, skip, pc); | 1150 | __ftrace_trace_stack(tr->buffer, flags, skip, pc); |
1152 | } | 1151 | } |
1153 | 1152 | ||
1153 | /** | ||
1154 | * trace_dump_stack - record a stack back trace in the trace buffer | ||
1155 | */ | ||
1156 | void trace_dump_stack(void) | ||
1157 | { | ||
1158 | unsigned long flags; | ||
1159 | |||
1160 | if (tracing_disabled || tracing_selftest_running) | ||
1161 | return; | ||
1162 | |||
1163 | local_save_flags(flags); | ||
1164 | |||
1165 | /* skipping 3 traces, seems to get us at the caller of this function */ | ||
1166 | __ftrace_trace_stack(global_trace.buffer, flags, 3, preempt_count()); | ||
1167 | } | ||
1168 | |||
1154 | void | 1169 | void |
1155 | ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc) | 1170 | ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc) |
1156 | { | 1171 | { |
@@ -2316,67 +2331,49 @@ static const struct file_operations tracing_cpumask_fops = { | |||
2316 | .write = tracing_cpumask_write, | 2331 | .write = tracing_cpumask_write, |
2317 | }; | 2332 | }; |
2318 | 2333 | ||
2319 | static ssize_t | 2334 | static int tracing_trace_options_show(struct seq_file *m, void *v) |
2320 | tracing_trace_options_read(struct file *filp, char __user *ubuf, | ||
2321 | size_t cnt, loff_t *ppos) | ||
2322 | { | 2335 | { |
2323 | struct tracer_opt *trace_opts; | 2336 | struct tracer_opt *trace_opts; |
2324 | u32 tracer_flags; | 2337 | u32 tracer_flags; |
2325 | int len = 0; | ||
2326 | char *buf; | ||
2327 | int r = 0; | ||
2328 | int i; | 2338 | int i; |
2329 | 2339 | ||
2330 | |||
2331 | /* calculate max size */ | ||
2332 | for (i = 0; trace_options[i]; i++) { | ||
2333 | len += strlen(trace_options[i]); | ||
2334 | len += 3; /* "no" and newline */ | ||
2335 | } | ||
2336 | |||
2337 | mutex_lock(&trace_types_lock); | 2340 | mutex_lock(&trace_types_lock); |
2338 | tracer_flags = current_trace->flags->val; | 2341 | tracer_flags = current_trace->flags->val; |
2339 | trace_opts = current_trace->flags->opts; | 2342 | trace_opts = current_trace->flags->opts; |
2340 | 2343 | ||
2341 | /* | ||
2342 | * Increase the size with names of options specific | ||
2343 | * of the current tracer. | ||
2344 | */ | ||
2345 | for (i = 0; trace_opts[i].name; i++) { | ||
2346 | len += strlen(trace_opts[i].name); | ||
2347 | len += 3; /* "no" and newline */ | ||
2348 | } | ||
2349 | |||
2350 | /* +1 for \0 */ | ||
2351 | buf = kmalloc(len + 1, GFP_KERNEL); | ||
2352 | if (!buf) { | ||
2353 | mutex_unlock(&trace_types_lock); | ||
2354 | return -ENOMEM; | ||
2355 | } | ||
2356 | |||
2357 | for (i = 0; trace_options[i]; i++) { | 2344 | for (i = 0; trace_options[i]; i++) { |
2358 | if (trace_flags & (1 << i)) | 2345 | if (trace_flags & (1 << i)) |
2359 | r += sprintf(buf + r, "%s\n", trace_options[i]); | 2346 | seq_printf(m, "%s\n", trace_options[i]); |
2360 | else | 2347 | else |
2361 | r += sprintf(buf + r, "no%s\n", trace_options[i]); | 2348 | seq_printf(m, "no%s\n", trace_options[i]); |
2362 | } | 2349 | } |
2363 | 2350 | ||
2364 | for (i = 0; trace_opts[i].name; i++) { | 2351 | for (i = 0; trace_opts[i].name; i++) { |
2365 | if (tracer_flags & trace_opts[i].bit) | 2352 | if (tracer_flags & trace_opts[i].bit) |
2366 | r += sprintf(buf + r, "%s\n", | 2353 | seq_printf(m, "%s\n", trace_opts[i].name); |
2367 | trace_opts[i].name); | ||
2368 | else | 2354 | else |
2369 | r += sprintf(buf + r, "no%s\n", | 2355 | seq_printf(m, "no%s\n", trace_opts[i].name); |
2370 | trace_opts[i].name); | ||
2371 | } | 2356 | } |
2372 | mutex_unlock(&trace_types_lock); | 2357 | mutex_unlock(&trace_types_lock); |
2373 | 2358 | ||
2374 | WARN_ON(r >= len + 1); | 2359 | return 0; |
2360 | } | ||
2375 | 2361 | ||
2376 | r = simple_read_from_buffer(ubuf, cnt, ppos, buf, r); | 2362 | static int __set_tracer_option(struct tracer *trace, |
2363 | struct tracer_flags *tracer_flags, | ||
2364 | struct tracer_opt *opts, int neg) | ||
2365 | { | ||
2366 | int ret; | ||
2377 | 2367 | ||
2378 | kfree(buf); | 2368 | ret = trace->set_flag(tracer_flags->val, opts->bit, !neg); |
2379 | return r; | 2369 | if (ret) |
2370 | return ret; | ||
2371 | |||
2372 | if (neg) | ||
2373 | tracer_flags->val &= ~opts->bit; | ||
2374 | else | ||
2375 | tracer_flags->val |= opts->bit; | ||
2376 | return 0; | ||
2380 | } | 2377 | } |
2381 | 2378 | ||
2382 | /* Try to assign a tracer specific option */ | 2379 | /* Try to assign a tracer specific option */ |
@@ -2384,33 +2381,17 @@ static int set_tracer_option(struct tracer *trace, char *cmp, int neg) | |||
2384 | { | 2381 | { |
2385 | struct tracer_flags *tracer_flags = trace->flags; | 2382 | struct tracer_flags *tracer_flags = trace->flags; |
2386 | struct tracer_opt *opts = NULL; | 2383 | struct tracer_opt *opts = NULL; |
2387 | int ret = 0, i = 0; | 2384 | int i; |
2388 | int len; | ||
2389 | 2385 | ||
2390 | for (i = 0; tracer_flags->opts[i].name; i++) { | 2386 | for (i = 0; tracer_flags->opts[i].name; i++) { |
2391 | opts = &tracer_flags->opts[i]; | 2387 | opts = &tracer_flags->opts[i]; |
2392 | len = strlen(opts->name); | ||
2393 | 2388 | ||
2394 | if (strncmp(cmp, opts->name, len) == 0) { | 2389 | if (strcmp(cmp, opts->name) == 0) |
2395 | ret = trace->set_flag(tracer_flags->val, | 2390 | return __set_tracer_option(trace, trace->flags, |
2396 | opts->bit, !neg); | 2391 | opts, neg); |
2397 | break; | ||
2398 | } | ||
2399 | } | 2392 | } |
2400 | /* Not found */ | ||
2401 | if (!tracer_flags->opts[i].name) | ||
2402 | return -EINVAL; | ||
2403 | |||
2404 | /* Refused to handle */ | ||
2405 | if (ret) | ||
2406 | return ret; | ||
2407 | |||
2408 | if (neg) | ||
2409 | tracer_flags->val &= ~opts->bit; | ||
2410 | else | ||
2411 | tracer_flags->val |= opts->bit; | ||
2412 | 2393 | ||
2413 | return 0; | 2394 | return -EINVAL; |
2414 | } | 2395 | } |
2415 | 2396 | ||
2416 | static void set_tracer_flags(unsigned int mask, int enabled) | 2397 | static void set_tracer_flags(unsigned int mask, int enabled) |
@@ -2430,7 +2411,7 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf, | |||
2430 | size_t cnt, loff_t *ppos) | 2411 | size_t cnt, loff_t *ppos) |
2431 | { | 2412 | { |
2432 | char buf[64]; | 2413 | char buf[64]; |
2433 | char *cmp = buf; | 2414 | char *cmp; |
2434 | int neg = 0; | 2415 | int neg = 0; |
2435 | int ret; | 2416 | int ret; |
2436 | int i; | 2417 | int i; |
@@ -2442,16 +2423,15 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf, | |||
2442 | return -EFAULT; | 2423 | return -EFAULT; |
2443 | 2424 | ||
2444 | buf[cnt] = 0; | 2425 | buf[cnt] = 0; |
2426 | cmp = strstrip(buf); | ||
2445 | 2427 | ||
2446 | if (strncmp(buf, "no", 2) == 0) { | 2428 | if (strncmp(cmp, "no", 2) == 0) { |
2447 | neg = 1; | 2429 | neg = 1; |
2448 | cmp += 2; | 2430 | cmp += 2; |
2449 | } | 2431 | } |
2450 | 2432 | ||
2451 | for (i = 0; trace_options[i]; i++) { | 2433 | for (i = 0; trace_options[i]; i++) { |
2452 | int len = strlen(trace_options[i]); | 2434 | if (strcmp(cmp, trace_options[i]) == 0) { |
2453 | |||
2454 | if (strncmp(cmp, trace_options[i], len) == 0) { | ||
2455 | set_tracer_flags(1 << i, !neg); | 2435 | set_tracer_flags(1 << i, !neg); |
2456 | break; | 2436 | break; |
2457 | } | 2437 | } |
@@ -2471,9 +2451,18 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf, | |||
2471 | return cnt; | 2451 | return cnt; |
2472 | } | 2452 | } |
2473 | 2453 | ||
2454 | static int tracing_trace_options_open(struct inode *inode, struct file *file) | ||
2455 | { | ||
2456 | if (tracing_disabled) | ||
2457 | return -ENODEV; | ||
2458 | return single_open(file, tracing_trace_options_show, NULL); | ||
2459 | } | ||
2460 | |||
2474 | static const struct file_operations tracing_iter_fops = { | 2461 | static const struct file_operations tracing_iter_fops = { |
2475 | .open = tracing_open_generic, | 2462 | .open = tracing_trace_options_open, |
2476 | .read = tracing_trace_options_read, | 2463 | .read = seq_read, |
2464 | .llseek = seq_lseek, | ||
2465 | .release = single_release, | ||
2477 | .write = tracing_trace_options_write, | 2466 | .write = tracing_trace_options_write, |
2478 | }; | 2467 | }; |
2479 | 2468 | ||
@@ -3392,21 +3381,18 @@ tracing_mark_write(struct file *filp, const char __user *ubuf, | |||
3392 | return cnt; | 3381 | return cnt; |
3393 | } | 3382 | } |
3394 | 3383 | ||
3395 | static ssize_t tracing_clock_read(struct file *filp, char __user *ubuf, | 3384 | static int tracing_clock_show(struct seq_file *m, void *v) |
3396 | size_t cnt, loff_t *ppos) | ||
3397 | { | 3385 | { |
3398 | char buf[64]; | ||
3399 | int bufiter = 0; | ||
3400 | int i; | 3386 | int i; |
3401 | 3387 | ||
3402 | for (i = 0; i < ARRAY_SIZE(trace_clocks); i++) | 3388 | for (i = 0; i < ARRAY_SIZE(trace_clocks); i++) |
3403 | bufiter += snprintf(buf + bufiter, sizeof(buf) - bufiter, | 3389 | seq_printf(m, |
3404 | "%s%s%s%s", i ? " " : "", | 3390 | "%s%s%s%s", i ? " " : "", |
3405 | i == trace_clock_id ? "[" : "", trace_clocks[i].name, | 3391 | i == trace_clock_id ? "[" : "", trace_clocks[i].name, |
3406 | i == trace_clock_id ? "]" : ""); | 3392 | i == trace_clock_id ? "]" : ""); |
3407 | bufiter += snprintf(buf + bufiter, sizeof(buf) - bufiter, "\n"); | 3393 | seq_putc(m, '\n'); |
3408 | 3394 | ||
3409 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, bufiter); | 3395 | return 0; |
3410 | } | 3396 | } |
3411 | 3397 | ||
3412 | static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf, | 3398 | static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf, |
@@ -3448,6 +3434,13 @@ static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf, | |||
3448 | return cnt; | 3434 | return cnt; |
3449 | } | 3435 | } |
3450 | 3436 | ||
3437 | static int tracing_clock_open(struct inode *inode, struct file *file) | ||
3438 | { | ||
3439 | if (tracing_disabled) | ||
3440 | return -ENODEV; | ||
3441 | return single_open(file, tracing_clock_show, NULL); | ||
3442 | } | ||
3443 | |||
3451 | static const struct file_operations tracing_max_lat_fops = { | 3444 | static const struct file_operations tracing_max_lat_fops = { |
3452 | .open = tracing_open_generic, | 3445 | .open = tracing_open_generic, |
3453 | .read = tracing_max_lat_read, | 3446 | .read = tracing_max_lat_read, |
@@ -3486,8 +3479,10 @@ static const struct file_operations tracing_mark_fops = { | |||
3486 | }; | 3479 | }; |
3487 | 3480 | ||
3488 | static const struct file_operations trace_clock_fops = { | 3481 | static const struct file_operations trace_clock_fops = { |
3489 | .open = tracing_open_generic, | 3482 | .open = tracing_clock_open, |
3490 | .read = tracing_clock_read, | 3483 | .read = seq_read, |
3484 | .llseek = seq_lseek, | ||
3485 | .release = single_release, | ||
3491 | .write = tracing_clock_write, | 3486 | .write = tracing_clock_write, |
3492 | }; | 3487 | }; |
3493 | 3488 | ||
@@ -3948,39 +3943,16 @@ trace_options_write(struct file *filp, const char __user *ubuf, size_t cnt, | |||
3948 | if (ret < 0) | 3943 | if (ret < 0) |
3949 | return ret; | 3944 | return ret; |
3950 | 3945 | ||
3951 | ret = 0; | 3946 | if (val != 0 && val != 1) |
3952 | switch (val) { | 3947 | return -EINVAL; |
3953 | case 0: | ||
3954 | /* do nothing if already cleared */ | ||
3955 | if (!(topt->flags->val & topt->opt->bit)) | ||
3956 | break; | ||
3957 | |||
3958 | mutex_lock(&trace_types_lock); | ||
3959 | if (current_trace->set_flag) | ||
3960 | ret = current_trace->set_flag(topt->flags->val, | ||
3961 | topt->opt->bit, 0); | ||
3962 | mutex_unlock(&trace_types_lock); | ||
3963 | if (ret) | ||
3964 | return ret; | ||
3965 | topt->flags->val &= ~topt->opt->bit; | ||
3966 | break; | ||
3967 | case 1: | ||
3968 | /* do nothing if already set */ | ||
3969 | if (topt->flags->val & topt->opt->bit) | ||
3970 | break; | ||
3971 | 3948 | ||
3949 | if (!!(topt->flags->val & topt->opt->bit) != val) { | ||
3972 | mutex_lock(&trace_types_lock); | 3950 | mutex_lock(&trace_types_lock); |
3973 | if (current_trace->set_flag) | 3951 | ret = __set_tracer_option(current_trace, topt->flags, |
3974 | ret = current_trace->set_flag(topt->flags->val, | 3952 | topt->opt, val); |
3975 | topt->opt->bit, 1); | ||
3976 | mutex_unlock(&trace_types_lock); | 3953 | mutex_unlock(&trace_types_lock); |
3977 | if (ret) | 3954 | if (ret) |
3978 | return ret; | 3955 | return ret; |
3979 | topt->flags->val |= topt->opt->bit; | ||
3980 | break; | ||
3981 | |||
3982 | default: | ||
3983 | return -EINVAL; | ||
3984 | } | 3956 | } |
3985 | 3957 | ||
3986 | *ppos += cnt; | 3958 | *ppos += cnt; |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index a52bed2eedd8..4df6a77eb196 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -597,18 +597,17 @@ enum trace_iterator_flags { | |||
597 | TRACE_ITER_BIN = 0x40, | 597 | TRACE_ITER_BIN = 0x40, |
598 | TRACE_ITER_BLOCK = 0x80, | 598 | TRACE_ITER_BLOCK = 0x80, |
599 | TRACE_ITER_STACKTRACE = 0x100, | 599 | TRACE_ITER_STACKTRACE = 0x100, |
600 | TRACE_ITER_SCHED_TREE = 0x200, | 600 | TRACE_ITER_PRINTK = 0x200, |
601 | TRACE_ITER_PRINTK = 0x400, | 601 | TRACE_ITER_PREEMPTONLY = 0x400, |
602 | TRACE_ITER_PREEMPTONLY = 0x800, | 602 | TRACE_ITER_BRANCH = 0x800, |
603 | TRACE_ITER_BRANCH = 0x1000, | 603 | TRACE_ITER_ANNOTATE = 0x1000, |
604 | TRACE_ITER_ANNOTATE = 0x2000, | 604 | TRACE_ITER_USERSTACKTRACE = 0x2000, |
605 | TRACE_ITER_USERSTACKTRACE = 0x4000, | 605 | TRACE_ITER_SYM_USEROBJ = 0x4000, |
606 | TRACE_ITER_SYM_USEROBJ = 0x8000, | 606 | TRACE_ITER_PRINTK_MSGONLY = 0x8000, |
607 | TRACE_ITER_PRINTK_MSGONLY = 0x10000, | 607 | TRACE_ITER_CONTEXT_INFO = 0x10000, /* Print pid/cpu/time */ |
608 | TRACE_ITER_CONTEXT_INFO = 0x20000, /* Print pid/cpu/time */ | 608 | TRACE_ITER_LATENCY_FMT = 0x20000, |
609 | TRACE_ITER_LATENCY_FMT = 0x40000, | 609 | TRACE_ITER_SLEEP_TIME = 0x40000, |
610 | TRACE_ITER_SLEEP_TIME = 0x80000, | 610 | TRACE_ITER_GRAPH_TIME = 0x80000, |
611 | TRACE_ITER_GRAPH_TIME = 0x100000, | ||
612 | }; | 611 | }; |
613 | 612 | ||
614 | /* | 613 | /* |
diff --git a/kernel/trace/trace_event_profile.c b/kernel/trace/trace_event_profile.c index d9c60f80aa0d..9e25573242cf 100644 --- a/kernel/trace/trace_event_profile.c +++ b/kernel/trace/trace_event_profile.c | |||
@@ -25,7 +25,7 @@ static int ftrace_profile_enable_event(struct ftrace_event_call *event) | |||
25 | char *buf; | 25 | char *buf; |
26 | int ret = -ENOMEM; | 26 | int ret = -ENOMEM; |
27 | 27 | ||
28 | if (atomic_inc_return(&event->profile_count)) | 28 | if (event->profile_count++ > 0) |
29 | return 0; | 29 | return 0; |
30 | 30 | ||
31 | if (!total_profile_count) { | 31 | if (!total_profile_count) { |
@@ -56,7 +56,7 @@ fail_buf_nmi: | |||
56 | perf_trace_buf = NULL; | 56 | perf_trace_buf = NULL; |
57 | } | 57 | } |
58 | fail_buf: | 58 | fail_buf: |
59 | atomic_dec(&event->profile_count); | 59 | event->profile_count--; |
60 | 60 | ||
61 | return ret; | 61 | return ret; |
62 | } | 62 | } |
@@ -83,7 +83,7 @@ static void ftrace_profile_disable_event(struct ftrace_event_call *event) | |||
83 | { | 83 | { |
84 | char *buf, *nmi_buf; | 84 | char *buf, *nmi_buf; |
85 | 85 | ||
86 | if (!atomic_add_negative(-1, &event->profile_count)) | 86 | if (--event->profile_count > 0) |
87 | return; | 87 | return; |
88 | 88 | ||
89 | event->profile_disable(event); | 89 | event->profile_disable(event); |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 1d18315dc836..189b09baf4fb 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -78,7 +78,7 @@ EXPORT_SYMBOL_GPL(trace_define_field); | |||
78 | if (ret) \ | 78 | if (ret) \ |
79 | return ret; | 79 | return ret; |
80 | 80 | ||
81 | int trace_define_common_fields(struct ftrace_event_call *call) | 81 | static int trace_define_common_fields(struct ftrace_event_call *call) |
82 | { | 82 | { |
83 | int ret; | 83 | int ret; |
84 | struct trace_entry ent; | 84 | struct trace_entry ent; |
@@ -91,7 +91,6 @@ int trace_define_common_fields(struct ftrace_event_call *call) | |||
91 | 91 | ||
92 | return ret; | 92 | return ret; |
93 | } | 93 | } |
94 | EXPORT_SYMBOL_GPL(trace_define_common_fields); | ||
95 | 94 | ||
96 | void trace_destroy_fields(struct ftrace_event_call *call) | 95 | void trace_destroy_fields(struct ftrace_event_call *call) |
97 | { | 96 | { |
@@ -105,9 +104,25 @@ void trace_destroy_fields(struct ftrace_event_call *call) | |||
105 | } | 104 | } |
106 | } | 105 | } |
107 | 106 | ||
108 | static void ftrace_event_enable_disable(struct ftrace_event_call *call, | 107 | int trace_event_raw_init(struct ftrace_event_call *call) |
108 | { | ||
109 | int id; | ||
110 | |||
111 | id = register_ftrace_event(call->event); | ||
112 | if (!id) | ||
113 | return -ENODEV; | ||
114 | call->id = id; | ||
115 | INIT_LIST_HEAD(&call->fields); | ||
116 | |||
117 | return 0; | ||
118 | } | ||
119 | EXPORT_SYMBOL_GPL(trace_event_raw_init); | ||
120 | |||
121 | static int ftrace_event_enable_disable(struct ftrace_event_call *call, | ||
109 | int enable) | 122 | int enable) |
110 | { | 123 | { |
124 | int ret = 0; | ||
125 | |||
111 | switch (enable) { | 126 | switch (enable) { |
112 | case 0: | 127 | case 0: |
113 | if (call->enabled) { | 128 | if (call->enabled) { |
@@ -118,12 +133,20 @@ static void ftrace_event_enable_disable(struct ftrace_event_call *call, | |||
118 | break; | 133 | break; |
119 | case 1: | 134 | case 1: |
120 | if (!call->enabled) { | 135 | if (!call->enabled) { |
121 | call->enabled = 1; | ||
122 | tracing_start_cmdline_record(); | 136 | tracing_start_cmdline_record(); |
123 | call->regfunc(call); | 137 | ret = call->regfunc(call); |
138 | if (ret) { | ||
139 | tracing_stop_cmdline_record(); | ||
140 | pr_info("event trace: Could not enable event " | ||
141 | "%s\n", call->name); | ||
142 | break; | ||
143 | } | ||
144 | call->enabled = 1; | ||
124 | } | 145 | } |
125 | break; | 146 | break; |
126 | } | 147 | } |
148 | |||
149 | return ret; | ||
127 | } | 150 | } |
128 | 151 | ||
129 | static void ftrace_clear_events(void) | 152 | static void ftrace_clear_events(void) |
@@ -402,7 +425,7 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, | |||
402 | case 0: | 425 | case 0: |
403 | case 1: | 426 | case 1: |
404 | mutex_lock(&event_mutex); | 427 | mutex_lock(&event_mutex); |
405 | ftrace_event_enable_disable(call, val); | 428 | ret = ftrace_event_enable_disable(call, val); |
406 | mutex_unlock(&event_mutex); | 429 | mutex_unlock(&event_mutex); |
407 | break; | 430 | break; |
408 | 431 | ||
@@ -412,7 +435,7 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, | |||
412 | 435 | ||
413 | *ppos += cnt; | 436 | *ppos += cnt; |
414 | 437 | ||
415 | return cnt; | 438 | return ret ? ret : cnt; |
416 | } | 439 | } |
417 | 440 | ||
418 | static ssize_t | 441 | static ssize_t |
@@ -913,7 +936,9 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events, | |||
913 | id); | 936 | id); |
914 | 937 | ||
915 | if (call->define_fields) { | 938 | if (call->define_fields) { |
916 | ret = call->define_fields(call); | 939 | ret = trace_define_common_fields(call); |
940 | if (!ret) | ||
941 | ret = call->define_fields(call); | ||
917 | if (ret < 0) { | 942 | if (ret < 0) { |
918 | pr_warning("Could not initialize trace point" | 943 | pr_warning("Could not initialize trace point" |
919 | " events/%s\n", call->name); | 944 | " events/%s\n", call->name); |
diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c index dff8c84ddf17..458e5bfe26d0 100644 --- a/kernel/trace/trace_export.c +++ b/kernel/trace/trace_export.c | |||
@@ -184,10 +184,6 @@ ftrace_define_fields_##name(struct ftrace_event_call *event_call) \ | |||
184 | struct struct_name field; \ | 184 | struct struct_name field; \ |
185 | int ret; \ | 185 | int ret; \ |
186 | \ | 186 | \ |
187 | ret = trace_define_common_fields(event_call); \ | ||
188 | if (ret) \ | ||
189 | return ret; \ | ||
190 | \ | ||
191 | tstruct; \ | 187 | tstruct; \ |
192 | \ | 188 | \ |
193 | return ret; \ | 189 | return ret; \ |
diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index 3aa7eaa2114c..2974bc7538c7 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c | |||
@@ -151,6 +151,8 @@ check_critical_timing(struct trace_array *tr, | |||
151 | goto out_unlock; | 151 | goto out_unlock; |
152 | 152 | ||
153 | trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc); | 153 | trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc); |
154 | /* Skip 5 functions to get to the irq/preempt enable function */ | ||
155 | __trace_stack(tr, flags, 5, pc); | ||
154 | 156 | ||
155 | if (data->critical_sequence != max_sequence) | 157 | if (data->critical_sequence != max_sequence) |
156 | goto out_unlock; | 158 | goto out_unlock; |
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index b52d397e57eb..7ecab06547a5 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
@@ -1132,10 +1132,6 @@ static int kprobe_event_define_fields(struct ftrace_event_call *event_call) | |||
1132 | struct kprobe_trace_entry field; | 1132 | struct kprobe_trace_entry field; |
1133 | struct trace_probe *tp = (struct trace_probe *)event_call->data; | 1133 | struct trace_probe *tp = (struct trace_probe *)event_call->data; |
1134 | 1134 | ||
1135 | ret = trace_define_common_fields(event_call); | ||
1136 | if (ret) | ||
1137 | return ret; | ||
1138 | |||
1139 | DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0); | 1135 | DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0); |
1140 | DEFINE_FIELD(int, nargs, FIELD_STRING_NARGS, 1); | 1136 | DEFINE_FIELD(int, nargs, FIELD_STRING_NARGS, 1); |
1141 | /* Set argument names as fields */ | 1137 | /* Set argument names as fields */ |
@@ -1150,10 +1146,6 @@ static int kretprobe_event_define_fields(struct ftrace_event_call *event_call) | |||
1150 | struct kretprobe_trace_entry field; | 1146 | struct kretprobe_trace_entry field; |
1151 | struct trace_probe *tp = (struct trace_probe *)event_call->data; | 1147 | struct trace_probe *tp = (struct trace_probe *)event_call->data; |
1152 | 1148 | ||
1153 | ret = trace_define_common_fields(event_call); | ||
1154 | if (ret) | ||
1155 | return ret; | ||
1156 | |||
1157 | DEFINE_FIELD(unsigned long, func, FIELD_STRING_FUNC, 0); | 1149 | DEFINE_FIELD(unsigned long, func, FIELD_STRING_FUNC, 0); |
1158 | DEFINE_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP, 0); | 1150 | DEFINE_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP, 0); |
1159 | DEFINE_FIELD(int, nargs, FIELD_STRING_NARGS, 1); | 1151 | DEFINE_FIELD(int, nargs, FIELD_STRING_NARGS, 1); |
@@ -1453,7 +1445,6 @@ static int register_probe_event(struct trace_probe *tp) | |||
1453 | call->unregfunc = probe_event_disable; | 1445 | call->unregfunc = probe_event_disable; |
1454 | 1446 | ||
1455 | #ifdef CONFIG_EVENT_PROFILE | 1447 | #ifdef CONFIG_EVENT_PROFILE |
1456 | atomic_set(&call->profile_count, -1); | ||
1457 | call->profile_enable = probe_profile_enable; | 1448 | call->profile_enable = probe_profile_enable; |
1458 | call->profile_disable = probe_profile_disable; | 1449 | call->profile_disable = probe_profile_disable; |
1459 | #endif | 1450 | #endif |
diff --git a/kernel/trace/trace_ksym.c b/kernel/trace/trace_ksym.c index acb87d4a4ac1..faf37fa4408c 100644 --- a/kernel/trace/trace_ksym.c +++ b/kernel/trace/trace_ksym.c | |||
@@ -236,7 +236,8 @@ static ssize_t ksym_trace_filter_read(struct file *filp, char __user *ubuf, | |||
236 | mutex_lock(&ksym_tracer_mutex); | 236 | mutex_lock(&ksym_tracer_mutex); |
237 | 237 | ||
238 | hlist_for_each_entry(entry, node, &ksym_filter_head, ksym_hlist) { | 238 | hlist_for_each_entry(entry, node, &ksym_filter_head, ksym_hlist) { |
239 | ret = trace_seq_printf(s, "%pS:", (void *)entry->attr.bp_addr); | 239 | ret = trace_seq_printf(s, "%pS:", |
240 | (void *)(unsigned long)entry->attr.bp_addr); | ||
240 | if (entry->attr.bp_type == HW_BREAKPOINT_R) | 241 | if (entry->attr.bp_type == HW_BREAKPOINT_R) |
241 | ret = trace_seq_puts(s, "r--\n"); | 242 | ret = trace_seq_puts(s, "r--\n"); |
242 | else if (entry->attr.bp_type == HW_BREAKPOINT_W) | 243 | else if (entry->attr.bp_type == HW_BREAKPOINT_W) |
@@ -278,21 +279,20 @@ static ssize_t ksym_trace_filter_write(struct file *file, | |||
278 | { | 279 | { |
279 | struct trace_ksym *entry; | 280 | struct trace_ksym *entry; |
280 | struct hlist_node *node; | 281 | struct hlist_node *node; |
281 | char *input_string, *ksymname = NULL; | 282 | char *buf, *input_string, *ksymname = NULL; |
282 | unsigned long ksym_addr = 0; | 283 | unsigned long ksym_addr = 0; |
283 | int ret, op, changed = 0; | 284 | int ret, op, changed = 0; |
284 | 285 | ||
285 | input_string = kzalloc(count + 1, GFP_KERNEL); | 286 | buf = kzalloc(count + 1, GFP_KERNEL); |
286 | if (!input_string) | 287 | if (!buf) |
287 | return -ENOMEM; | 288 | return -ENOMEM; |
288 | 289 | ||
289 | if (copy_from_user(input_string, buffer, count)) { | 290 | ret = -EFAULT; |
290 | kfree(input_string); | 291 | if (copy_from_user(buf, buffer, count)) |
291 | return -EFAULT; | 292 | goto out; |
292 | } | ||
293 | input_string[count] = '\0'; | ||
294 | 293 | ||
295 | strstrip(input_string); | 294 | buf[count] = '\0'; |
295 | input_string = strstrip(buf); | ||
296 | 296 | ||
297 | /* | 297 | /* |
298 | * Clear all breakpoints if: | 298 | * Clear all breakpoints if: |
@@ -300,18 +300,16 @@ static ssize_t ksym_trace_filter_write(struct file *file, | |||
300 | * 2: echo 0 > ksym_trace_filter | 300 | * 2: echo 0 > ksym_trace_filter |
301 | * 3: echo "*:---" > ksym_trace_filter | 301 | * 3: echo "*:---" > ksym_trace_filter |
302 | */ | 302 | */ |
303 | if (!input_string[0] || !strcmp(input_string, "0") || | 303 | if (!buf[0] || !strcmp(buf, "0") || |
304 | !strcmp(input_string, "*:---")) { | 304 | !strcmp(buf, "*:---")) { |
305 | __ksym_trace_reset(); | 305 | __ksym_trace_reset(); |
306 | kfree(input_string); | 306 | ret = 0; |
307 | return count; | 307 | goto out; |
308 | } | 308 | } |
309 | 309 | ||
310 | ret = op = parse_ksym_trace_str(input_string, &ksymname, &ksym_addr); | 310 | ret = op = parse_ksym_trace_str(input_string, &ksymname, &ksym_addr); |
311 | if (ret < 0) { | 311 | if (ret < 0) |
312 | kfree(input_string); | 312 | goto out; |
313 | return ret; | ||
314 | } | ||
315 | 313 | ||
316 | mutex_lock(&ksym_tracer_mutex); | 314 | mutex_lock(&ksym_tracer_mutex); |
317 | 315 | ||
@@ -322,7 +320,7 @@ static ssize_t ksym_trace_filter_write(struct file *file, | |||
322 | if (entry->attr.bp_type != op) | 320 | if (entry->attr.bp_type != op) |
323 | changed = 1; | 321 | changed = 1; |
324 | else | 322 | else |
325 | goto out; | 323 | goto out_unlock; |
326 | break; | 324 | break; |
327 | } | 325 | } |
328 | } | 326 | } |
@@ -337,28 +335,24 @@ static ssize_t ksym_trace_filter_write(struct file *file, | |||
337 | if (IS_ERR(entry->ksym_hbp)) | 335 | if (IS_ERR(entry->ksym_hbp)) |
338 | ret = PTR_ERR(entry->ksym_hbp); | 336 | ret = PTR_ERR(entry->ksym_hbp); |
339 | else | 337 | else |
340 | goto out; | 338 | goto out_unlock; |
341 | } | 339 | } |
342 | /* Error or "symbol:---" case: drop it */ | 340 | /* Error or "symbol:---" case: drop it */ |
343 | ksym_filter_entry_count--; | 341 | ksym_filter_entry_count--; |
344 | hlist_del_rcu(&(entry->ksym_hlist)); | 342 | hlist_del_rcu(&(entry->ksym_hlist)); |
345 | synchronize_rcu(); | 343 | synchronize_rcu(); |
346 | kfree(entry); | 344 | kfree(entry); |
347 | goto out; | 345 | goto out_unlock; |
348 | } else { | 346 | } else { |
349 | /* Check for malformed request: (4) */ | 347 | /* Check for malformed request: (4) */ |
350 | if (op == 0) | 348 | if (op) |
351 | goto out; | 349 | ret = process_new_ksym_entry(ksymname, op, ksym_addr); |
352 | ret = process_new_ksym_entry(ksymname, op, ksym_addr); | ||
353 | } | 350 | } |
354 | out: | 351 | out_unlock: |
355 | mutex_unlock(&ksym_tracer_mutex); | 352 | mutex_unlock(&ksym_tracer_mutex); |
356 | 353 | out: | |
357 | kfree(input_string); | 354 | kfree(buf); |
358 | 355 | return !ret ? count : ret; | |
359 | if (!ret) | ||
360 | ret = count; | ||
361 | return ret; | ||
362 | } | 356 | } |
363 | 357 | ||
364 | static const struct file_operations ksym_tracing_fops = { | 358 | static const struct file_operations ksym_tracing_fops = { |
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index 57501d90096a..75289f372dd2 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c | |||
@@ -217,10 +217,6 @@ int syscall_enter_define_fields(struct ftrace_event_call *call) | |||
217 | int i; | 217 | int i; |
218 | int offset = offsetof(typeof(trace), args); | 218 | int offset = offsetof(typeof(trace), args); |
219 | 219 | ||
220 | ret = trace_define_common_fields(call); | ||
221 | if (ret) | ||
222 | return ret; | ||
223 | |||
224 | ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER); | 220 | ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER); |
225 | if (ret) | 221 | if (ret) |
226 | return ret; | 222 | return ret; |
@@ -241,10 +237,6 @@ int syscall_exit_define_fields(struct ftrace_event_call *call) | |||
241 | struct syscall_trace_exit trace; | 237 | struct syscall_trace_exit trace; |
242 | int ret; | 238 | int ret; |
243 | 239 | ||
244 | ret = trace_define_common_fields(call); | ||
245 | if (ret) | ||
246 | return ret; | ||
247 | |||
248 | ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER); | 240 | ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER); |
249 | if (ret) | 241 | if (ret) |
250 | return ret; | 242 | return ret; |
@@ -333,10 +325,7 @@ int reg_event_syscall_enter(struct ftrace_event_call *call) | |||
333 | mutex_lock(&syscall_trace_lock); | 325 | mutex_lock(&syscall_trace_lock); |
334 | if (!sys_refcount_enter) | 326 | if (!sys_refcount_enter) |
335 | ret = register_trace_sys_enter(ftrace_syscall_enter); | 327 | ret = register_trace_sys_enter(ftrace_syscall_enter); |
336 | if (ret) { | 328 | if (!ret) { |
337 | pr_info("event trace: Could not activate" | ||
338 | "syscall entry trace point"); | ||
339 | } else { | ||
340 | set_bit(num, enabled_enter_syscalls); | 329 | set_bit(num, enabled_enter_syscalls); |
341 | sys_refcount_enter++; | 330 | sys_refcount_enter++; |
342 | } | 331 | } |
@@ -370,10 +359,7 @@ int reg_event_syscall_exit(struct ftrace_event_call *call) | |||
370 | mutex_lock(&syscall_trace_lock); | 359 | mutex_lock(&syscall_trace_lock); |
371 | if (!sys_refcount_exit) | 360 | if (!sys_refcount_exit) |
372 | ret = register_trace_sys_exit(ftrace_syscall_exit); | 361 | ret = register_trace_sys_exit(ftrace_syscall_exit); |
373 | if (ret) { | 362 | if (!ret) { |
374 | pr_info("event trace: Could not activate" | ||
375 | "syscall exit trace point"); | ||
376 | } else { | ||
377 | set_bit(num, enabled_exit_syscalls); | 363 | set_bit(num, enabled_exit_syscalls); |
378 | sys_refcount_exit++; | 364 | sys_refcount_exit++; |
379 | } | 365 | } |