diff options
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r-- | kernel/trace/trace.c | 124 |
1 files changed, 69 insertions, 55 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 307524d784ec..57b4220d96a9 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -818,6 +818,72 @@ static void default_wait_pipe(struct trace_iterator *iter) | |||
818 | ring_buffer_wait(iter->trace_buffer->buffer, iter->cpu_file); | 818 | ring_buffer_wait(iter->trace_buffer->buffer, iter->cpu_file); |
819 | } | 819 | } |
820 | 820 | ||
821 | #ifdef CONFIG_FTRACE_STARTUP_TEST | ||
822 | static int run_tracer_selftest(struct tracer *type) | ||
823 | { | ||
824 | struct trace_array *tr = &global_trace; | ||
825 | struct tracer *saved_tracer = tr->current_trace; | ||
826 | int ret; | ||
827 | |||
828 | if (!type->selftest || tracing_selftest_disabled) | ||
829 | return 0; | ||
830 | |||
831 | /* | ||
832 | * Run a selftest on this tracer. | ||
833 | * Here we reset the trace buffer, and set the current | ||
834 | * tracer to be this tracer. The tracer can then run some | ||
835 | * internal tracing to verify that everything is in order. | ||
836 | * If we fail, we do not register this tracer. | ||
837 | */ | ||
838 | tracing_reset_online_cpus(&tr->trace_buffer); | ||
839 | |||
840 | tr->current_trace = type; | ||
841 | |||
842 | #ifdef CONFIG_TRACER_MAX_TRACE | ||
843 | if (type->use_max_tr) { | ||
844 | /* If we expanded the buffers, make sure the max is expanded too */ | ||
845 | if (ring_buffer_expanded) | ||
846 | ring_buffer_resize(tr->max_buffer.buffer, trace_buf_size, | ||
847 | RING_BUFFER_ALL_CPUS); | ||
848 | tr->allocated_snapshot = true; | ||
849 | } | ||
850 | #endif | ||
851 | |||
852 | /* the test is responsible for initializing and enabling */ | ||
853 | pr_info("Testing tracer %s: ", type->name); | ||
854 | ret = type->selftest(type, tr); | ||
855 | /* the test is responsible for resetting too */ | ||
856 | tr->current_trace = saved_tracer; | ||
857 | if (ret) { | ||
858 | printk(KERN_CONT "FAILED!\n"); | ||
859 | /* Add the warning after printing 'FAILED' */ | ||
860 | WARN_ON(1); | ||
861 | return -1; | ||
862 | } | ||
863 | /* Only reset on passing, to avoid touching corrupted buffers */ | ||
864 | tracing_reset_online_cpus(&tr->trace_buffer); | ||
865 | |||
866 | #ifdef CONFIG_TRACER_MAX_TRACE | ||
867 | if (type->use_max_tr) { | ||
868 | tr->allocated_snapshot = false; | ||
869 | |||
870 | /* Shrink the max buffer again */ | ||
871 | if (ring_buffer_expanded) | ||
872 | ring_buffer_resize(tr->max_buffer.buffer, 1, | ||
873 | RING_BUFFER_ALL_CPUS); | ||
874 | } | ||
875 | #endif | ||
876 | |||
877 | printk(KERN_CONT "PASSED\n"); | ||
878 | return 0; | ||
879 | } | ||
880 | #else | ||
881 | static inline int run_tracer_selftest(struct tracer *type) | ||
882 | { | ||
883 | return 0; | ||
884 | } | ||
885 | #endif /* CONFIG_FTRACE_STARTUP_TEST */ | ||
886 | |||
821 | /** | 887 | /** |
822 | * register_tracer - register a tracer with the ftrace system. | 888 | * register_tracer - register a tracer with the ftrace system. |
823 | * @type - the plugin for the tracer | 889 | * @type - the plugin for the tracer |
@@ -863,61 +929,9 @@ int register_tracer(struct tracer *type) | |||
863 | if (!type->wait_pipe) | 929 | if (!type->wait_pipe) |
864 | type->wait_pipe = default_wait_pipe; | 930 | type->wait_pipe = default_wait_pipe; |
865 | 931 | ||
866 | 932 | ret = run_tracer_selftest(type); | |
867 | #ifdef CONFIG_FTRACE_STARTUP_TEST | 933 | if (ret < 0) |
868 | if (type->selftest && !tracing_selftest_disabled) { | 934 | goto out; |
869 | struct trace_array *tr = &global_trace; | ||
870 | struct tracer *saved_tracer = tr->current_trace; | ||
871 | |||
872 | /* | ||
873 | * Run a selftest on this tracer. | ||
874 | * Here we reset the trace buffer, and set the current | ||
875 | * tracer to be this tracer. The tracer can then run some | ||
876 | * internal tracing to verify that everything is in order. | ||
877 | * If we fail, we do not register this tracer. | ||
878 | */ | ||
879 | tracing_reset_online_cpus(&tr->trace_buffer); | ||
880 | |||
881 | tr->current_trace = type; | ||
882 | |||
883 | #ifdef CONFIG_TRACER_MAX_TRACE | ||
884 | if (type->use_max_tr) { | ||
885 | /* If we expanded the buffers, make sure the max is expanded too */ | ||
886 | if (ring_buffer_expanded) | ||
887 | ring_buffer_resize(tr->max_buffer.buffer, trace_buf_size, | ||
888 | RING_BUFFER_ALL_CPUS); | ||
889 | tr->allocated_snapshot = true; | ||
890 | } | ||
891 | #endif | ||
892 | |||
893 | /* the test is responsible for initializing and enabling */ | ||
894 | pr_info("Testing tracer %s: ", type->name); | ||
895 | ret = type->selftest(type, tr); | ||
896 | /* the test is responsible for resetting too */ | ||
897 | tr->current_trace = saved_tracer; | ||
898 | if (ret) { | ||
899 | printk(KERN_CONT "FAILED!\n"); | ||
900 | /* Add the warning after printing 'FAILED' */ | ||
901 | WARN_ON(1); | ||
902 | goto out; | ||
903 | } | ||
904 | /* Only reset on passing, to avoid touching corrupted buffers */ | ||
905 | tracing_reset_online_cpus(&tr->trace_buffer); | ||
906 | |||
907 | #ifdef CONFIG_TRACER_MAX_TRACE | ||
908 | if (type->use_max_tr) { | ||
909 | tr->allocated_snapshot = false; | ||
910 | |||
911 | /* Shrink the max buffer again */ | ||
912 | if (ring_buffer_expanded) | ||
913 | ring_buffer_resize(tr->max_buffer.buffer, 1, | ||
914 | RING_BUFFER_ALL_CPUS); | ||
915 | } | ||
916 | #endif | ||
917 | |||
918 | printk(KERN_CONT "PASSED\n"); | ||
919 | } | ||
920 | #endif | ||
921 | 935 | ||
922 | type->next = trace_types; | 936 | type->next = trace_types; |
923 | trace_types = type; | 937 | trace_types = type; |