aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r--kernel/trace/trace.c86
1 files changed, 71 insertions, 15 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index c2e2c2310374..4f1dade56981 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -704,7 +704,7 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
704void 704void
705update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) 705update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
706{ 706{
707 struct ring_buffer *buf = tr->buffer; 707 struct ring_buffer *buf;
708 708
709 if (trace_stop_count) 709 if (trace_stop_count)
710 return; 710 return;
@@ -719,6 +719,7 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
719 719
720 arch_spin_lock(&ftrace_max_lock); 720 arch_spin_lock(&ftrace_max_lock);
721 721
722 buf = tr->buffer;
722 tr->buffer = max_tr.buffer; 723 tr->buffer = max_tr.buffer;
723 max_tr.buffer = buf; 724 max_tr.buffer = buf;
724 725
@@ -2400,6 +2401,27 @@ static void test_ftrace_alive(struct seq_file *m)
2400 seq_printf(m, "# MAY BE MISSING FUNCTION EVENTS\n"); 2401 seq_printf(m, "# MAY BE MISSING FUNCTION EVENTS\n");
2401} 2402}
2402 2403
2404#ifdef CONFIG_TRACER_MAX_TRACE
2405static void print_snapshot_help(struct seq_file *m, struct trace_iterator *iter)
2406{
2407 if (iter->trace->allocated_snapshot)
2408 seq_printf(m, "#\n# * Snapshot is allocated *\n#\n");
2409 else
2410 seq_printf(m, "#\n# * Snapshot is freed *\n#\n");
2411
2412 seq_printf(m, "# Snapshot commands:\n");
2413 seq_printf(m, "# echo 0 > snapshot : Clears and frees snapshot buffer\n");
2414 seq_printf(m, "# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.\n");
2415 seq_printf(m, "# Takes a snapshot of the main buffer.\n");
2416 seq_printf(m, "# echo 2 > snapshot : Clears snapshot buffer (but does not allocate)\n");
2417 seq_printf(m, "# (Doesn't have to be '2' works with any number that\n");
2418 seq_printf(m, "# is not a '0' or '1')\n");
2419}
2420#else
2421/* Should never be called */
2422static inline void print_snapshot_help(struct seq_file *m, struct trace_iterator *iter) { }
2423#endif
2424
2403static int s_show(struct seq_file *m, void *v) 2425static int s_show(struct seq_file *m, void *v)
2404{ 2426{
2405 struct trace_iterator *iter = v; 2427 struct trace_iterator *iter = v;
@@ -2411,7 +2433,9 @@ static int s_show(struct seq_file *m, void *v)
2411 seq_puts(m, "#\n"); 2433 seq_puts(m, "#\n");
2412 test_ftrace_alive(m); 2434 test_ftrace_alive(m);
2413 } 2435 }
2414 if (iter->trace && iter->trace->print_header) 2436 if (iter->snapshot && trace_empty(iter))
2437 print_snapshot_help(m, iter);
2438 else if (iter->trace && iter->trace->print_header)
2415 iter->trace->print_header(m); 2439 iter->trace->print_header(m);
2416 else 2440 else
2417 trace_default_header(m); 2441 trace_default_header(m);
@@ -2857,11 +2881,25 @@ static int set_tracer_option(struct tracer *trace, char *cmp, int neg)
2857 return -EINVAL; 2881 return -EINVAL;
2858} 2882}
2859 2883
2860static void set_tracer_flags(unsigned int mask, int enabled) 2884/* Some tracers require overwrite to stay enabled */
2885int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set)
2886{
2887 if (tracer->enabled && (mask & TRACE_ITER_OVERWRITE) && !set)
2888 return -1;
2889
2890 return 0;
2891}
2892
2893int set_tracer_flag(unsigned int mask, int enabled)
2861{ 2894{
2862 /* do nothing if flag is already set */ 2895 /* do nothing if flag is already set */
2863 if (!!(trace_flags & mask) == !!enabled) 2896 if (!!(trace_flags & mask) == !!enabled)
2864 return; 2897 return 0;
2898
2899 /* Give the tracer a chance to approve the change */
2900 if (current_trace->flag_changed)
2901 if (current_trace->flag_changed(current_trace, mask, !!enabled))
2902 return -EINVAL;
2865 2903
2866 if (enabled) 2904 if (enabled)
2867 trace_flags |= mask; 2905 trace_flags |= mask;
@@ -2871,18 +2909,24 @@ static void set_tracer_flags(unsigned int mask, int enabled)
2871 if (mask == TRACE_ITER_RECORD_CMD) 2909 if (mask == TRACE_ITER_RECORD_CMD)
2872 trace_event_enable_cmd_record(enabled); 2910 trace_event_enable_cmd_record(enabled);
2873 2911
2874 if (mask == TRACE_ITER_OVERWRITE) 2912 if (mask == TRACE_ITER_OVERWRITE) {
2875 ring_buffer_change_overwrite(global_trace.buffer, enabled); 2913 ring_buffer_change_overwrite(global_trace.buffer, enabled);
2914#ifdef CONFIG_TRACER_MAX_TRACE
2915 ring_buffer_change_overwrite(max_tr.buffer, enabled);
2916#endif
2917 }
2876 2918
2877 if (mask == TRACE_ITER_PRINTK) 2919 if (mask == TRACE_ITER_PRINTK)
2878 trace_printk_start_stop_comm(enabled); 2920 trace_printk_start_stop_comm(enabled);
2921
2922 return 0;
2879} 2923}
2880 2924
2881static int trace_set_options(char *option) 2925static int trace_set_options(char *option)
2882{ 2926{
2883 char *cmp; 2927 char *cmp;
2884 int neg = 0; 2928 int neg = 0;
2885 int ret = 0; 2929 int ret = -ENODEV;
2886 int i; 2930 int i;
2887 2931
2888 cmp = strstrip(option); 2932 cmp = strstrip(option);
@@ -2892,19 +2936,20 @@ static int trace_set_options(char *option)
2892 cmp += 2; 2936 cmp += 2;
2893 } 2937 }
2894 2938
2939 mutex_lock(&trace_types_lock);
2940
2895 for (i = 0; trace_options[i]; i++) { 2941 for (i = 0; trace_options[i]; i++) {
2896 if (strcmp(cmp, trace_options[i]) == 0) { 2942 if (strcmp(cmp, trace_options[i]) == 0) {
2897 set_tracer_flags(1 << i, !neg); 2943 ret = set_tracer_flag(1 << i, !neg);
2898 break; 2944 break;
2899 } 2945 }
2900 } 2946 }
2901 2947
2902 /* If no option could be set, test the specific tracer options */ 2948 /* If no option could be set, test the specific tracer options */
2903 if (!trace_options[i]) { 2949 if (!trace_options[i])
2904 mutex_lock(&trace_types_lock);
2905 ret = set_tracer_option(current_trace, cmp, neg); 2950 ret = set_tracer_option(current_trace, cmp, neg);
2906 mutex_unlock(&trace_types_lock); 2951
2907 } 2952 mutex_unlock(&trace_types_lock);
2908 2953
2909 return ret; 2954 return ret;
2910} 2955}
@@ -2914,6 +2959,7 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf,
2914 size_t cnt, loff_t *ppos) 2959 size_t cnt, loff_t *ppos)
2915{ 2960{
2916 char buf[64]; 2961 char buf[64];
2962 int ret;
2917 2963
2918 if (cnt >= sizeof(buf)) 2964 if (cnt >= sizeof(buf))
2919 return -EINVAL; 2965 return -EINVAL;
@@ -2923,7 +2969,9 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf,
2923 2969
2924 buf[cnt] = 0; 2970 buf[cnt] = 0;
2925 2971
2926 trace_set_options(buf); 2972 ret = trace_set_options(buf);
2973 if (ret < 0)
2974 return ret;
2927 2975
2928 *ppos += cnt; 2976 *ppos += cnt;
2929 2977
@@ -3227,6 +3275,9 @@ static int tracing_set_tracer(const char *buf)
3227 goto out; 3275 goto out;
3228 3276
3229 trace_branch_disable(); 3277 trace_branch_disable();
3278
3279 current_trace->enabled = false;
3280
3230 if (current_trace->reset) 3281 if (current_trace->reset)
3231 current_trace->reset(tr); 3282 current_trace->reset(tr);
3232 3283
@@ -3271,6 +3322,7 @@ static int tracing_set_tracer(const char *buf)
3271 } 3322 }
3272 3323
3273 current_trace = t; 3324 current_trace = t;
3325 current_trace->enabled = true;
3274 trace_branch_enable(tr); 3326 trace_branch_enable(tr);
3275 out: 3327 out:
3276 mutex_unlock(&trace_types_lock); 3328 mutex_unlock(&trace_types_lock);
@@ -4144,8 +4196,6 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt,
4144 default: 4196 default:
4145 if (current_trace->allocated_snapshot) 4197 if (current_trace->allocated_snapshot)
4146 tracing_reset_online_cpus(&max_tr); 4198 tracing_reset_online_cpus(&max_tr);
4147 else
4148 ret = -EINVAL;
4149 break; 4199 break;
4150 } 4200 }
4151 4201
@@ -4759,7 +4809,13 @@ trace_options_core_write(struct file *filp, const char __user *ubuf, size_t cnt,
4759 4809
4760 if (val != 0 && val != 1) 4810 if (val != 0 && val != 1)
4761 return -EINVAL; 4811 return -EINVAL;
4762 set_tracer_flags(1 << index, val); 4812
4813 mutex_lock(&trace_types_lock);
4814 ret = set_tracer_flag(1 << index, val);
4815 mutex_unlock(&trace_types_lock);
4816
4817 if (ret < 0)
4818 return ret;
4763 4819
4764 *ppos += cnt; 4820 *ppos += cnt;
4765 4821