Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

tracing: Make the backup instance non-reusable

Since there is no reason to reuse the backup instance, make it readonly
(but erasable). Note that only backup instances are readonly, because
other trace instances will be empty unless it is writable. Only backup
instances have copy entries from the original.

With this change, most of the trace control files are removed from the
backup instance, including eventfs enable/filter etc.

# find /sys/kernel/tracing/instances/backup/events/ | wc -l
4093
# find /sys/kernel/tracing/instances/boot_map/events/ | wc -l
9573

Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Link: https://patch.msgid.link/177502546939.1311542.1826814401724828930.stgit@mhiramat.tok.corp.google.com
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

authored by

Masami Hiramatsu (Google) and committed by
Steven Rostedt (Google)
2c79da09 20ad8b08

+108 -69
+51 -32
kernel/trace/trace.c
··· 4022 4022 if (ret) 4023 4023 return ret; 4024 4024 4025 + if ((filp->f_mode & FMODE_WRITE) && trace_array_is_readonly(tr)) { 4026 + trace_array_put(tr); 4027 + return -EACCES; 4028 + } 4029 + 4025 4030 filp->private_data = inode->i_private; 4026 4031 4027 4032 return 0; ··· 7102 7097 if (ret) 7103 7098 return ret; 7104 7099 7100 + if ((file->f_mode & FMODE_WRITE) && trace_array_is_readonly(tr)) { 7101 + trace_array_put(tr); 7102 + return -EACCES; 7103 + } 7104 + 7105 7105 ret = single_open(file, tracing_clock_show, inode->i_private); 7106 7106 if (ret < 0) 7107 7107 trace_array_put(tr); ··· 9876 9866 static void 9877 9867 init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer) 9878 9868 { 9869 + umode_t writable_mode = TRACE_MODE_WRITE; 9879 9870 int cpu; 9880 9871 9872 + if (trace_array_is_readonly(tr)) 9873 + writable_mode = TRACE_MODE_READ; 9874 + 9881 9875 trace_create_file("available_tracers", TRACE_MODE_READ, d_tracer, 9882 - tr, &show_traces_fops); 9876 + tr, &show_traces_fops); 9883 9877 9884 - trace_create_file("current_tracer", TRACE_MODE_WRITE, d_tracer, 9885 - tr, &set_tracer_fops); 9878 + trace_create_file("current_tracer", writable_mode, d_tracer, 9879 + tr, &set_tracer_fops); 9886 9880 9887 - trace_create_file("tracing_cpumask", TRACE_MODE_WRITE, d_tracer, 9881 + trace_create_file("tracing_cpumask", writable_mode, d_tracer, 9888 9882 tr, &tracing_cpumask_fops); 9889 9883 9884 + /* Options are used for changing print-format even for readonly instance. */ 9890 9885 trace_create_file("trace_options", TRACE_MODE_WRITE, d_tracer, 9891 9886 tr, &tracing_iter_fops); 9892 9887 ··· 9901 9886 trace_create_file("trace_pipe", TRACE_MODE_READ, d_tracer, 9902 9887 tr, &tracing_pipe_fops); 9903 9888 9904 - trace_create_file("buffer_size_kb", TRACE_MODE_WRITE, d_tracer, 9889 + trace_create_file("buffer_size_kb", writable_mode, d_tracer, 9905 9890 tr, &tracing_entries_fops); 9906 9891 9907 9892 trace_create_file("buffer_total_size_kb", TRACE_MODE_READ, d_tracer, 9908 9893 tr, &tracing_total_entries_fops); 9894 + 9895 + trace_create_file("trace_clock", writable_mode, d_tracer, tr, 9896 + &trace_clock_fops); 9897 + 9898 + trace_create_file("timestamp_mode", TRACE_MODE_READ, d_tracer, tr, 9899 + &trace_time_stamp_mode_fops); 9900 + 9901 + tr->buffer_percent = 50; 9902 + 9903 + trace_create_file("buffer_subbuf_size_kb", writable_mode, d_tracer, 9904 + tr, &buffer_subbuf_size_fops); 9905 + 9906 + create_trace_options_dir(tr); 9907 + 9908 + if (tr->range_addr_start) 9909 + trace_create_file("last_boot_info", TRACE_MODE_READ, d_tracer, 9910 + tr, &last_boot_fops); 9911 + 9912 + for_each_tracing_cpu(cpu) 9913 + tracing_init_tracefs_percpu(tr, cpu); 9914 + 9915 + /* Read-only instance has above files only. */ 9916 + if (trace_array_is_readonly(tr)) 9917 + return; 9909 9918 9910 9919 trace_create_file("free_buffer", 0200, d_tracer, 9911 9920 tr, &tracing_free_buffer_fops); ··· 9942 9903 trace_create_file("trace_marker_raw", 0220, d_tracer, 9943 9904 tr, &tracing_mark_raw_fops); 9944 9905 9945 - trace_create_file("trace_clock", TRACE_MODE_WRITE, d_tracer, tr, 9946 - &trace_clock_fops); 9906 + trace_create_file("buffer_percent", TRACE_MODE_WRITE, d_tracer, 9907 + tr, &buffer_percent_fops); 9908 + 9909 + trace_create_file("syscall_user_buf_size", TRACE_MODE_WRITE, d_tracer, 9910 + tr, &tracing_syscall_buf_fops); 9947 9911 9948 9912 trace_create_file("tracing_on", TRACE_MODE_WRITE, d_tracer, 9949 9913 tr, &rb_simple_fops); 9950 - 9951 - trace_create_file("timestamp_mode", TRACE_MODE_READ, d_tracer, tr, 9952 - &trace_time_stamp_mode_fops); 9953 - 9954 - tr->buffer_percent = 50; 9955 - 9956 - trace_create_file("buffer_percent", TRACE_MODE_WRITE, d_tracer, 9957 - tr, &buffer_percent_fops); 9958 - 9959 - trace_create_file("buffer_subbuf_size_kb", TRACE_MODE_WRITE, d_tracer, 9960 - tr, &buffer_subbuf_size_fops); 9961 - 9962 - trace_create_file("syscall_user_buf_size", TRACE_MODE_WRITE, d_tracer, 9963 - tr, &tracing_syscall_buf_fops); 9964 - 9965 - create_trace_options_dir(tr); 9966 9914 9967 9915 trace_create_maxlat_file(tr, d_tracer); 9968 9916 9969 9917 if (ftrace_create_function_files(tr, d_tracer)) 9970 9918 MEM_FAIL(1, "Could not allocate function filter files"); 9971 9919 9972 - if (tr->range_addr_start) { 9973 - trace_create_file("last_boot_info", TRACE_MODE_READ, d_tracer, 9974 - tr, &last_boot_fops); 9975 9920 #ifdef CONFIG_TRACER_SNAPSHOT 9976 - } else { 9921 + if (!tr->range_addr_start) 9977 9922 trace_create_file("snapshot", TRACE_MODE_WRITE, d_tracer, 9978 9923 tr, &snapshot_fops); 9979 9924 #endif 9980 - } 9981 9925 9982 9926 trace_create_file("error_log", TRACE_MODE_WRITE, d_tracer, 9983 9927 tr, &tracing_err_log_fops); 9984 - 9985 - for_each_tracing_cpu(cpu) 9986 - tracing_init_tracefs_percpu(tr, cpu); 9987 9928 9988 9929 ftrace_init_tracefs(tr, d_tracer); 9989 9930 } ··· 10791 10772 * Backup buffers can be freed but need vfree(). 10792 10773 */ 10793 10774 if (backup) 10794 - tr->flags |= TRACE_ARRAY_FL_VMALLOC; 10775 + tr->flags |= TRACE_ARRAY_FL_VMALLOC | TRACE_ARRAY_FL_RDONLY; 10795 10776 10796 10777 if (start || backup) { 10797 10778 tr->flags |= TRACE_ARRAY_FL_BOOT | TRACE_ARRAY_FL_LAST_BOOT;
+7
kernel/trace/trace.h
··· 462 462 TRACE_ARRAY_FL_MOD_INIT = BIT(3), 463 463 TRACE_ARRAY_FL_MEMMAP = BIT(4), 464 464 TRACE_ARRAY_FL_VMALLOC = BIT(5), 465 + TRACE_ARRAY_FL_RDONLY = BIT(6), 465 466 }; 466 467 467 468 #ifdef CONFIG_MODULES ··· 491 490 extern unsigned long trace_adjust_address(struct trace_array *tr, unsigned long addr); 492 491 493 492 extern struct trace_array *printk_trace; 493 + 494 + static inline bool trace_array_is_readonly(struct trace_array *tr) 495 + { 496 + /* backup instance is read only. */ 497 + return tr->flags & TRACE_ARRAY_FL_RDONLY; 498 + } 494 499 495 500 /* 496 501 * The global tracer (top) should be the first trace array added,
+3 -2
kernel/trace/trace_boot.c
··· 61 61 v = memparse(p, NULL); 62 62 if (v < PAGE_SIZE) 63 63 pr_err("Buffer size is too small: %s\n", p); 64 - if (tracing_resize_ring_buffer(tr, v, RING_BUFFER_ALL_CPUS) < 0) 64 + if (trace_array_is_readonly(tr) || 65 + tracing_resize_ring_buffer(tr, v, RING_BUFFER_ALL_CPUS) < 0) 65 66 pr_err("Failed to resize trace buffer to %s\n", p); 66 67 } 67 68 ··· 598 597 599 598 p = xbc_node_find_value(node, "tracer", NULL); 600 599 if (p && *p != '\0') { 601 - if (tracing_set_tracer(tr, p) < 0) 600 + if (trace_array_is_readonly(tr) || tracing_set_tracer(tr, p) < 0) 602 601 pr_err("Failed to set given tracer: %s\n", p); 603 602 } 604 603
+47 -35
kernel/trace/trace_events.c
··· 1401 1401 { 1402 1402 int ret; 1403 1403 1404 + if (trace_array_is_readonly(tr)) 1405 + return -EACCES; 1406 + 1404 1407 mutex_lock(&event_mutex); 1405 1408 ret = __ftrace_set_clr_event_nolock(tr, match, sub, event, set, mod); 1406 1409 mutex_unlock(&event_mutex); ··· 2976 2973 } else 2977 2974 __get_system(system); 2978 2975 2979 - /* ftrace only has directories no files */ 2980 - if (strcmp(name, "ftrace") == 0) 2976 + /* ftrace only has directories no files, readonly instance too. */ 2977 + if (strcmp(name, "ftrace") == 0 || trace_array_is_readonly(tr)) 2981 2978 nr_entries = 0; 2982 2979 else 2983 2980 nr_entries = ARRAY_SIZE(system_entries); ··· 3142 3139 int ret; 3143 3140 static struct eventfs_entry event_entries[] = { 3144 3141 { 3142 + .name = "format", 3143 + .callback = event_callback, 3144 + }, 3145 + #ifdef CONFIG_PERF_EVENTS 3146 + { 3147 + .name = "id", 3148 + .callback = event_callback, 3149 + }, 3150 + #endif 3151 + #define NR_RO_EVENT_ENTRIES (1 + IS_ENABLED(CONFIG_PERF_EVENTS)) 3152 + /* Readonly files must be above this line and counted by NR_RO_EVENT_ENTRIES. */ 3153 + { 3145 3154 .name = "enable", 3146 3155 .callback = event_callback, 3147 3156 .release = event_release, ··· 3166 3151 .name = "trigger", 3167 3152 .callback = event_callback, 3168 3153 }, 3169 - { 3170 - .name = "format", 3171 - .callback = event_callback, 3172 - }, 3173 - #ifdef CONFIG_PERF_EVENTS 3174 - { 3175 - .name = "id", 3176 - .callback = event_callback, 3177 - }, 3178 - #endif 3179 3154 #ifdef CONFIG_HIST_TRIGGERS 3180 3155 { 3181 3156 .name = "hist", ··· 3198 3193 if (!e_events) 3199 3194 return -ENOMEM; 3200 3195 3201 - nr_entries = ARRAY_SIZE(event_entries); 3196 + if (trace_array_is_readonly(tr)) 3197 + nr_entries = NR_RO_EVENT_ENTRIES; 3198 + else 3199 + nr_entries = ARRAY_SIZE(event_entries); 3202 3200 3203 3201 name = trace_event_name(call); 3204 3202 ei = eventfs_create_dir(name, e_events, event_entries, nr_entries, file); ··· 4544 4536 int nr_entries; 4545 4537 static struct eventfs_entry events_entries[] = { 4546 4538 { 4547 - .name = "enable", 4548 - .callback = events_callback, 4549 - }, 4550 - { 4551 4539 .name = "header_page", 4552 4540 .callback = events_callback, 4553 4541 }, ··· 4551 4547 .name = "header_event", 4552 4548 .callback = events_callback, 4553 4549 }, 4550 + #define NR_RO_TOP_ENTRIES 2 4551 + /* Readonly files must be above this line and counted by NR_RO_TOP_ENTRIES. */ 4552 + { 4553 + .name = "enable", 4554 + .callback = events_callback, 4555 + }, 4554 4556 }; 4555 4557 4556 - entry = trace_create_file("set_event", TRACE_MODE_WRITE, parent, 4557 - tr, &ftrace_set_event_fops); 4558 - if (!entry) 4559 - return -ENOMEM; 4558 + if (!trace_array_is_readonly(tr)) { 4559 + entry = trace_create_file("set_event", TRACE_MODE_WRITE, parent, 4560 + tr, &ftrace_set_event_fops); 4561 + if (!entry) 4562 + return -ENOMEM; 4560 4563 4561 - trace_create_file("show_event_filters", TRACE_MODE_READ, parent, tr, 4562 - &ftrace_show_event_filters_fops); 4564 + /* There are not as crucial, just warn if they are not created */ 4565 + trace_create_file("show_event_filters", TRACE_MODE_READ, parent, tr, 4566 + &ftrace_show_event_filters_fops); 4563 4567 4564 - trace_create_file("show_event_triggers", TRACE_MODE_READ, parent, tr, 4565 - &ftrace_show_event_triggers_fops); 4568 + trace_create_file("show_event_triggers", TRACE_MODE_READ, parent, tr, 4569 + &ftrace_show_event_triggers_fops); 4566 4570 4567 - nr_entries = ARRAY_SIZE(events_entries); 4571 + trace_create_file("set_event_pid", TRACE_MODE_WRITE, parent, 4572 + tr, &ftrace_set_event_pid_fops); 4573 + 4574 + trace_create_file("set_event_notrace_pid", 4575 + TRACE_MODE_WRITE, parent, tr, 4576 + &ftrace_set_event_notrace_pid_fops); 4577 + nr_entries = ARRAY_SIZE(events_entries); 4578 + } else { 4579 + nr_entries = NR_RO_TOP_ENTRIES; 4580 + } 4568 4581 4569 4582 e_events = eventfs_create_events_dir("events", parent, events_entries, 4570 4583 nr_entries, tr); ··· 4589 4568 pr_warn("Could not create tracefs 'events' directory\n"); 4590 4569 return -ENOMEM; 4591 4570 } 4592 - 4593 - /* There are not as crucial, just warn if they are not created */ 4594 - 4595 - trace_create_file("set_event_pid", TRACE_MODE_WRITE, parent, 4596 - tr, &ftrace_set_event_pid_fops); 4597 - 4598 - trace_create_file("set_event_notrace_pid", 4599 - TRACE_MODE_WRITE, parent, tr, 4600 - &ftrace_set_event_notrace_pid_fops); 4601 4571 4602 4572 tr->event_dir = e_events; 4603 4573