diff options
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r-- | kernel/trace/trace.c | 44 |
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; | |||
1517 | static char *get_trace_buf(void) | 1526 | static 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 | ||
1543 | static int alloc_percpu_trace_buffer(void) | 1549 | static 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 | ||