hc
2024-05-10 61598093bbdd283a7edc367d900f223070ead8d2
kernel/kernel/trace/trace.c
....@@ -1883,9 +1883,10 @@
18831883 * place on this CPU. We fail to record, but we reset
18841884 * the max trace buffer (no one writes directly to it)
18851885 * and flag that it failed.
1886
+ * Another reason is resize is in progress.
18861887 */
18871888 trace_array_printk_buf(tr->max_buffer.buffer, _THIS_IP_,
1888
- "Failed to swap buffers due to commit in progress\n");
1889
+ "Failed to swap buffers due to commit or resize in progress\n");
18891890 }
18901891
18911892 WARN_ON_ONCE(ret && ret != -EAGAIN && ret != -EBUSY);
....@@ -2179,9 +2180,11 @@
21792180 }
21802181
21812182 /* Must have trace_types_lock held */
2182
-void tracing_reset_all_online_cpus(void)
2183
+void tracing_reset_all_online_cpus_unlocked(void)
21832184 {
21842185 struct trace_array *tr;
2186
+
2187
+ lockdep_assert_held(&trace_types_lock);
21852188
21862189 list_for_each_entry(tr, &ftrace_trace_arrays, list) {
21872190 if (!tr->clear_trace)
....@@ -2192,6 +2195,13 @@
21922195 tracing_reset_online_cpus(&tr->max_buffer);
21932196 #endif
21942197 }
2198
+}
2199
+
2200
+void tracing_reset_all_online_cpus(void)
2201
+{
2202
+ mutex_lock(&trace_types_lock);
2203
+ tracing_reset_all_online_cpus_unlocked();
2204
+ mutex_unlock(&trace_types_lock);
21952205 }
21962206
21972207 /*
....@@ -3717,8 +3727,15 @@
37173727 * will point to the same string as current_trace->name.
37183728 */
37193729 mutex_lock(&trace_types_lock);
3720
- if (unlikely(tr->current_trace && iter->trace->name != tr->current_trace->name))
3730
+ if (unlikely(tr->current_trace && iter->trace->name != tr->current_trace->name)) {
3731
+ /* Close iter->trace before switching to the new current tracer */
3732
+ if (iter->trace->close)
3733
+ iter->trace->close(iter);
37213734 *iter->trace = *tr->current_trace;
3735
+ /* Reopen the new current tracer */
3736
+ if (iter->trace->open)
3737
+ iter->trace->open(iter);
3738
+ }
37223739 mutex_unlock(&trace_types_lock);
37233740
37243741 #ifdef CONFIG_TRACER_MAX_TRACE
....@@ -4477,6 +4494,33 @@
44774494 return 0;
44784495 }
44794496
4497
+/*
4498
+ * The private pointer of the inode is the trace_event_file.
4499
+ * Update the tr ref count associated to it.
4500
+ */
4501
+int tracing_open_file_tr(struct inode *inode, struct file *filp)
4502
+{
4503
+ struct trace_event_file *file = inode->i_private;
4504
+ int ret;
4505
+
4506
+ ret = tracing_check_open_get_tr(file->tr);
4507
+ if (ret)
4508
+ return ret;
4509
+
4510
+ filp->private_data = inode->i_private;
4511
+
4512
+ return 0;
4513
+}
4514
+
4515
+int tracing_release_file_tr(struct inode *inode, struct file *filp)
4516
+{
4517
+ struct trace_event_file *file = inode->i_private;
4518
+
4519
+ trace_array_put(file->tr);
4520
+
4521
+ return 0;
4522
+}
4523
+
44804524 static int tracing_release(struct inode *inode, struct file *file)
44814525 {
44824526 struct trace_array *tr = inode->i_private;
....@@ -4706,6 +4750,8 @@
47064750 static const struct file_operations tracing_fops = {
47074751 .open = tracing_open,
47084752 .read = seq_read,
4753
+ .read_iter = seq_read_iter,
4754
+ .splice_read = generic_file_splice_read,
47094755 .write = tracing_write_stub,
47104756 .llseek = tracing_lseek,
47114757 .release = tracing_release,
....@@ -4765,11 +4811,17 @@
47654811 !cpumask_test_cpu(cpu, tracing_cpumask_new)) {
47664812 atomic_inc(&per_cpu_ptr(tr->array_buffer.data, cpu)->disabled);
47674813 ring_buffer_record_disable_cpu(tr->array_buffer.buffer, cpu);
4814
+#ifdef CONFIG_TRACER_MAX_TRACE
4815
+ ring_buffer_record_disable_cpu(tr->max_buffer.buffer, cpu);
4816
+#endif
47684817 }
47694818 if (!cpumask_test_cpu(cpu, tr->tracing_cpumask) &&
47704819 cpumask_test_cpu(cpu, tracing_cpumask_new)) {
47714820 atomic_dec(&per_cpu_ptr(tr->array_buffer.data, cpu)->disabled);
47724821 ring_buffer_record_enable_cpu(tr->array_buffer.buffer, cpu);
4822
+#ifdef CONFIG_TRACER_MAX_TRACE
4823
+ ring_buffer_record_enable_cpu(tr->max_buffer.buffer, cpu);
4824
+#endif
47734825 }
47744826 }
47754827 arch_spin_unlock(&tr->max_lock);
....@@ -6240,6 +6292,7 @@
62406292 mutex_unlock(&trace_types_lock);
62416293
62426294 free_cpumask_var(iter->started);
6295
+ kfree(iter->temp);
62436296 mutex_destroy(&iter->mutex);
62446297 kfree(iter);
62456298
....@@ -6372,7 +6425,20 @@
63726425
63736426 ret = print_trace_line(iter);
63746427 if (ret == TRACE_TYPE_PARTIAL_LINE) {
6375
- /* don't print partial lines */
6428
+ /*
6429
+ * If one print_trace_line() fills entire trace_seq in one shot,
6430
+ * trace_seq_to_user() will returns -EBUSY because save_len == 0,
6431
+ * In this case, we need to consume it, otherwise, loop will peek
6432
+ * this event next time, resulting in an infinite loop.
6433
+ */
6434
+ if (save_len == 0) {
6435
+ iter->seq.full = 0;
6436
+ trace_seq_puts(&iter->seq, "[LINE TOO BIG]\n");
6437
+ trace_consume(iter);
6438
+ break;
6439
+ }
6440
+
6441
+ /* In other cases, don't print partial lines */
63766442 iter->seq.seq.len = save_len;
63776443 break;
63786444 }
....@@ -7027,6 +7093,11 @@
70277093 return ret;
70287094 }
70297095
7096
+static void tracing_swap_cpu_buffer(void *tr)
7097
+{
7098
+ update_max_tr_single((struct trace_array *)tr, current, smp_processor_id());
7099
+}
7100
+
70307101 static ssize_t
70317102 tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt,
70327103 loff_t *ppos)
....@@ -7085,13 +7156,15 @@
70857156 ret = tracing_alloc_snapshot_instance(tr);
70867157 if (ret < 0)
70877158 break;
7088
- local_irq_disable();
70897159 /* Now, we're going to swap */
7090
- if (iter->cpu_file == RING_BUFFER_ALL_CPUS)
7160
+ if (iter->cpu_file == RING_BUFFER_ALL_CPUS) {
7161
+ local_irq_disable();
70917162 update_max_tr(tr, current, smp_processor_id(), NULL);
7092
- else
7093
- update_max_tr_single(tr, current, iter->cpu_file);
7094
- local_irq_enable();
7163
+ local_irq_enable();
7164
+ } else {
7165
+ smp_call_function_single(iter->cpu_file, tracing_swap_cpu_buffer,
7166
+ (void *)tr, 1);
7167
+ }
70957168 break;
70967169 default:
70977170 if (tr->allocated_snapshot) {
....@@ -7180,10 +7253,11 @@
71807253 #endif
71817254
71827255 static const struct file_operations set_tracer_fops = {
7183
- .open = tracing_open_generic,
7256
+ .open = tracing_open_generic_tr,
71847257 .read = tracing_set_trace_read,
71857258 .write = tracing_set_trace_write,
71867259 .llseek = generic_file_llseek,
7260
+ .release = tracing_release_generic_tr,
71877261 };
71887262
71897263 static const struct file_operations tracing_pipe_fops = {
....@@ -7506,7 +7580,7 @@
75067580 .open = tracing_err_log_open,
75077581 .write = tracing_err_log_write,
75087582 .read = seq_read,
7509
- .llseek = seq_lseek,
7583
+ .llseek = tracing_lseek,
75107584 .release = tracing_err_log_release,
75117585 };
75127586
....@@ -8222,12 +8296,33 @@
82228296 return cnt;
82238297 }
82248298
8299
+static int tracing_open_options(struct inode *inode, struct file *filp)
8300
+{
8301
+ struct trace_option_dentry *topt = inode->i_private;
8302
+ int ret;
8303
+
8304
+ ret = tracing_check_open_get_tr(topt->tr);
8305
+ if (ret)
8306
+ return ret;
8307
+
8308
+ filp->private_data = inode->i_private;
8309
+ return 0;
8310
+}
8311
+
8312
+static int tracing_release_options(struct inode *inode, struct file *file)
8313
+{
8314
+ struct trace_option_dentry *topt = file->private_data;
8315
+
8316
+ trace_array_put(topt->tr);
8317
+ return 0;
8318
+}
82258319
82268320 static const struct file_operations trace_options_fops = {
8227
- .open = tracing_open_generic,
8321
+ .open = tracing_open_options,
82288322 .read = trace_options_read,
82298323 .write = trace_options_write,
82308324 .llseek = generic_file_llseek,
8325
+ .release = tracing_release_options,
82318326 };
82328327
82338328 /*
....@@ -8557,9 +8652,6 @@
85578652 if (val > 100)
85588653 return -EINVAL;
85598654
8560
- if (!val)
8561
- val = 1;
8562
-
85638655 tr->buffer_percent = val;
85648656
85658657 (*ppos)++;
....@@ -8884,6 +8976,7 @@
88848976 ftrace_destroy_function_files(tr);
88858977 tracefs_remove(tr->dir);
88868978 free_trace_buffers(tr);
8979
+ clear_tracing_err_log(tr);
88878980
88888981 for (i = 0; i < tr->nr_topts; i++) {
88898982 kfree(tr->topts[i].topts);
....@@ -9706,6 +9799,8 @@
97069799 static_key_enable(&tracepoint_printk_key.key);
97079800 }
97089801 tracer_alloc_buffers();
9802
+
9803
+ init_events();
97099804 }
97109805
97119806 void __init trace_init(void)