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.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 3c13e46d7d24..d2a658349ca1 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -709,10 +709,14 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
709 return; 709 return;
710 710
711 WARN_ON_ONCE(!irqs_disabled()); 711 WARN_ON_ONCE(!irqs_disabled());
712 if (!current_trace->use_max_tr) { 712
713 WARN_ON_ONCE(1); 713 /* If we disabled the tracer, stop now */
714 if (current_trace == &nop_trace)
714 return; 715 return;
715 } 716
717 if (WARN_ON_ONCE(!current_trace->use_max_tr))
718 return;
719
716 arch_spin_lock(&ftrace_max_lock); 720 arch_spin_lock(&ftrace_max_lock);
717 721
718 tr->buffer = max_tr.buffer; 722 tr->buffer = max_tr.buffer;
@@ -922,6 +926,9 @@ void tracing_reset(struct trace_array *tr, int cpu)
922{ 926{
923 struct ring_buffer *buffer = tr->buffer; 927 struct ring_buffer *buffer = tr->buffer;
924 928
929 if (!buffer)
930 return;
931
925 ring_buffer_record_disable(buffer); 932 ring_buffer_record_disable(buffer);
926 933
927 /* Make sure all commits have finished */ 934 /* Make sure all commits have finished */
@@ -936,6 +943,9 @@ void tracing_reset_online_cpus(struct trace_array *tr)
936 struct ring_buffer *buffer = tr->buffer; 943 struct ring_buffer *buffer = tr->buffer;
937 int cpu; 944 int cpu;
938 945
946 if (!buffer)
947 return;
948
939 ring_buffer_record_disable(buffer); 949 ring_buffer_record_disable(buffer);
940 950
941 /* Make sure all commits have finished */ 951 /* Make sure all commits have finished */
@@ -1167,7 +1177,6 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags,
1167 1177
1168 entry->preempt_count = pc & 0xff; 1178 entry->preempt_count = pc & 0xff;
1169 entry->pid = (tsk) ? tsk->pid : 0; 1179 entry->pid = (tsk) ? tsk->pid : 0;
1170 entry->padding = 0;
1171 entry->flags = 1180 entry->flags =
1172#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT 1181#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
1173 (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) | 1182 (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) |
@@ -1517,7 +1526,6 @@ static struct trace_buffer_struct *trace_percpu_nmi_buffer;
1517static char *get_trace_buf(void) 1526static char *get_trace_buf(void)
1518{ 1527{
1519 struct trace_buffer_struct *percpu_buffer; 1528 struct trace_buffer_struct *percpu_buffer;
1520 struct trace_buffer_struct *buffer;
1521 1529
1522 /* 1530 /*
1523 * If we have allocated per cpu buffers, then we do not 1531 * If we have allocated per cpu buffers, then we do not
@@ -1535,9 +1543,7 @@ static char *get_trace_buf(void)
1535 if (!percpu_buffer) 1543 if (!percpu_buffer)
1536 return NULL; 1544 return NULL;
1537 1545
1538 buffer = per_cpu_ptr(percpu_buffer, smp_processor_id()); 1546 return this_cpu_ptr(&percpu_buffer->buffer[0]);
1539
1540 return buffer->buffer;
1541} 1547}
1542 1548
1543static int alloc_percpu_trace_buffer(void) 1549static int alloc_percpu_trace_buffer(void)
@@ -3183,6 +3189,7 @@ static int tracing_set_tracer(const char *buf)
3183 static struct trace_option_dentry *topts; 3189 static struct trace_option_dentry *topts;
3184 struct trace_array *tr = &global_trace; 3190 struct trace_array *tr = &global_trace;
3185 struct tracer *t; 3191 struct tracer *t;
3192 bool had_max_tr;
3186 int ret = 0; 3193 int ret = 0;
3187 3194
3188 mutex_lock(&trace_types_lock); 3195 mutex_lock(&trace_types_lock);
@@ -3209,7 +3216,19 @@ static int tracing_set_tracer(const char *buf)
3209 trace_branch_disable(); 3216 trace_branch_disable();
3210 if (current_trace && current_trace->reset) 3217 if (current_trace && current_trace->reset)
3211 current_trace->reset(tr); 3218 current_trace->reset(tr);
3212 if (current_trace && current_trace->use_max_tr) { 3219
3220 had_max_tr = current_trace && current_trace->use_max_tr;
3221 current_trace = &nop_trace;
3222
3223 if (had_max_tr && !t->use_max_tr) {
3224 /*
3225 * We need to make sure that the update_max_tr sees that
3226 * current_trace changed to nop_trace to keep it from
3227 * swapping the buffers after we resize it.
3228 * The update_max_tr is called from interrupts disabled
3229 * so a synchronized_sched() is sufficient.
3230 */
3231 synchronize_sched();
3213 /* 3232 /*
3214 * We don't free the ring buffer. instead, resize it because 3233 * We don't free the ring buffer. instead, resize it because
3215 * The max_tr ring buffer has some state (e.g. ring->clock) and 3234 * The max_tr ring buffer has some state (e.g. ring->clock) and
@@ -3220,10 +3239,8 @@ static int tracing_set_tracer(const char *buf)
3220 } 3239 }
3221 destroy_trace_option_files(topts); 3240 destroy_trace_option_files(topts);
3222 3241
3223 current_trace = &nop_trace;
3224
3225 topts = create_trace_option_files(t); 3242 topts = create_trace_option_files(t);
3226 if (t->use_max_tr) { 3243 if (t->use_max_tr && !had_max_tr) {
3227 /* we need to make per cpu buffer sizes equivalent */ 3244 /* we need to make per cpu buffer sizes equivalent */
3228 ret = resize_buffer_duplicate_size(&max_tr, &global_trace, 3245 ret = resize_buffer_duplicate_size(&max_tr, &global_trace,
3229 RING_BUFFER_ALL_CPUS); 3246 RING_BUFFER_ALL_CPUS);
@@ -4037,8 +4054,7 @@ static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf,
4037 * Reset the buffer so that it doesn't have incomparable timestamps. 4054 * Reset the buffer so that it doesn't have incomparable timestamps.
4038 */ 4055 */
4039 tracing_reset_online_cpus(&global_trace); 4056 tracing_reset_online_cpus(&global_trace);
4040 if (max_tr.buffer) 4057 tracing_reset_online_cpus(&max_tr);
4041 tracing_reset_online_cpus(&max_tr);
4042 4058
4043 mutex_unlock(&trace_types_lock); 4059 mutex_unlock(&trace_types_lock);
4044 4060