diff options
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r-- | kernel/trace/trace.c | 386 |
1 files changed, 255 insertions, 131 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 1ce5dc6372b8..8acd9b81a5d7 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -171,6 +171,13 @@ static struct trace_array global_trace; | |||
171 | 171 | ||
172 | static DEFINE_PER_CPU(struct trace_array_cpu, global_trace_cpu); | 172 | static DEFINE_PER_CPU(struct trace_array_cpu, global_trace_cpu); |
173 | 173 | ||
174 | int filter_current_check_discard(struct ftrace_event_call *call, void *rec, | ||
175 | struct ring_buffer_event *event) | ||
176 | { | ||
177 | return filter_check_discard(call, rec, global_trace.buffer, event); | ||
178 | } | ||
179 | EXPORT_SYMBOL_GPL(filter_current_check_discard); | ||
180 | |||
174 | cycle_t ftrace_now(int cpu) | 181 | cycle_t ftrace_now(int cpu) |
175 | { | 182 | { |
176 | u64 ts; | 183 | u64 ts; |
@@ -255,7 +262,8 @@ static DECLARE_WAIT_QUEUE_HEAD(trace_wait); | |||
255 | 262 | ||
256 | /* trace_flags holds trace_options default values */ | 263 | /* trace_flags holds trace_options default values */ |
257 | unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK | | 264 | unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK | |
258 | TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | TRACE_ITER_SLEEP_TIME; | 265 | TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | TRACE_ITER_SLEEP_TIME | |
266 | TRACE_ITER_GRAPH_TIME; | ||
259 | 267 | ||
260 | /** | 268 | /** |
261 | * trace_wake_up - wake up tasks waiting for trace input | 269 | * trace_wake_up - wake up tasks waiting for trace input |
@@ -317,6 +325,7 @@ static const char *trace_options[] = { | |||
317 | "latency-format", | 325 | "latency-format", |
318 | "global-clock", | 326 | "global-clock", |
319 | "sleep-time", | 327 | "sleep-time", |
328 | "graph-time", | ||
320 | NULL | 329 | NULL |
321 | }; | 330 | }; |
322 | 331 | ||
@@ -402,17 +411,6 @@ static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt) | |||
402 | return cnt; | 411 | return cnt; |
403 | } | 412 | } |
404 | 413 | ||
405 | static void | ||
406 | trace_print_seq(struct seq_file *m, struct trace_seq *s) | ||
407 | { | ||
408 | int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len; | ||
409 | |||
410 | s->buffer[len] = 0; | ||
411 | seq_puts(m, s->buffer); | ||
412 | |||
413 | trace_seq_init(s); | ||
414 | } | ||
415 | |||
416 | /** | 414 | /** |
417 | * update_max_tr - snapshot all trace buffers from global_trace to max_tr | 415 | * update_max_tr - snapshot all trace buffers from global_trace to max_tr |
418 | * @tr: tracer | 416 | * @tr: tracer |
@@ -641,6 +639,16 @@ void tracing_reset_online_cpus(struct trace_array *tr) | |||
641 | tracing_reset(tr, cpu); | 639 | tracing_reset(tr, cpu); |
642 | } | 640 | } |
643 | 641 | ||
642 | void tracing_reset_current(int cpu) | ||
643 | { | ||
644 | tracing_reset(&global_trace, cpu); | ||
645 | } | ||
646 | |||
647 | void tracing_reset_current_online_cpus(void) | ||
648 | { | ||
649 | tracing_reset_online_cpus(&global_trace); | ||
650 | } | ||
651 | |||
644 | #define SAVED_CMDLINES 128 | 652 | #define SAVED_CMDLINES 128 |
645 | #define NO_CMDLINE_MAP UINT_MAX | 653 | #define NO_CMDLINE_MAP UINT_MAX |
646 | static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; | 654 | static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; |
@@ -800,6 +808,7 @@ void trace_find_cmdline(int pid, char comm[]) | |||
800 | return; | 808 | return; |
801 | } | 809 | } |
802 | 810 | ||
811 | preempt_disable(); | ||
803 | __raw_spin_lock(&trace_cmdline_lock); | 812 | __raw_spin_lock(&trace_cmdline_lock); |
804 | map = map_pid_to_cmdline[pid]; | 813 | map = map_pid_to_cmdline[pid]; |
805 | if (map != NO_CMDLINE_MAP) | 814 | if (map != NO_CMDLINE_MAP) |
@@ -808,6 +817,7 @@ void trace_find_cmdline(int pid, char comm[]) | |||
808 | strcpy(comm, "<...>"); | 817 | strcpy(comm, "<...>"); |
809 | 818 | ||
810 | __raw_spin_unlock(&trace_cmdline_lock); | 819 | __raw_spin_unlock(&trace_cmdline_lock); |
820 | preempt_enable(); | ||
811 | } | 821 | } |
812 | 822 | ||
813 | void tracing_record_cmdline(struct task_struct *tsk) | 823 | void tracing_record_cmdline(struct task_struct *tsk) |
@@ -840,7 +850,7 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags, | |||
840 | } | 850 | } |
841 | 851 | ||
842 | struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr, | 852 | struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr, |
843 | unsigned char type, | 853 | int type, |
844 | unsigned long len, | 854 | unsigned long len, |
845 | unsigned long flags, int pc) | 855 | unsigned long flags, int pc) |
846 | { | 856 | { |
@@ -883,30 +893,40 @@ void trace_buffer_unlock_commit(struct trace_array *tr, | |||
883 | } | 893 | } |
884 | 894 | ||
885 | struct ring_buffer_event * | 895 | struct ring_buffer_event * |
886 | trace_current_buffer_lock_reserve(unsigned char type, unsigned long len, | 896 | trace_current_buffer_lock_reserve(int type, unsigned long len, |
887 | unsigned long flags, int pc) | 897 | unsigned long flags, int pc) |
888 | { | 898 | { |
889 | return trace_buffer_lock_reserve(&global_trace, | 899 | return trace_buffer_lock_reserve(&global_trace, |
890 | type, len, flags, pc); | 900 | type, len, flags, pc); |
891 | } | 901 | } |
902 | EXPORT_SYMBOL_GPL(trace_current_buffer_lock_reserve); | ||
892 | 903 | ||
893 | void trace_current_buffer_unlock_commit(struct ring_buffer_event *event, | 904 | void trace_current_buffer_unlock_commit(struct ring_buffer_event *event, |
894 | unsigned long flags, int pc) | 905 | unsigned long flags, int pc) |
895 | { | 906 | { |
896 | return __trace_buffer_unlock_commit(&global_trace, event, flags, pc, 1); | 907 | __trace_buffer_unlock_commit(&global_trace, event, flags, pc, 1); |
897 | } | 908 | } |
909 | EXPORT_SYMBOL_GPL(trace_current_buffer_unlock_commit); | ||
898 | 910 | ||
899 | void trace_nowake_buffer_unlock_commit(struct ring_buffer_event *event, | 911 | void trace_nowake_buffer_unlock_commit(struct ring_buffer_event *event, |
900 | unsigned long flags, int pc) | 912 | unsigned long flags, int pc) |
901 | { | 913 | { |
902 | return __trace_buffer_unlock_commit(&global_trace, event, flags, pc, 0); | 914 | __trace_buffer_unlock_commit(&global_trace, event, flags, pc, 0); |
915 | } | ||
916 | EXPORT_SYMBOL_GPL(trace_nowake_buffer_unlock_commit); | ||
917 | |||
918 | void trace_current_buffer_discard_commit(struct ring_buffer_event *event) | ||
919 | { | ||
920 | ring_buffer_discard_commit(global_trace.buffer, event); | ||
903 | } | 921 | } |
922 | EXPORT_SYMBOL_GPL(trace_current_buffer_discard_commit); | ||
904 | 923 | ||
905 | void | 924 | void |
906 | trace_function(struct trace_array *tr, | 925 | trace_function(struct trace_array *tr, |
907 | unsigned long ip, unsigned long parent_ip, unsigned long flags, | 926 | unsigned long ip, unsigned long parent_ip, unsigned long flags, |
908 | int pc) | 927 | int pc) |
909 | { | 928 | { |
929 | struct ftrace_event_call *call = &event_function; | ||
910 | struct ring_buffer_event *event; | 930 | struct ring_buffer_event *event; |
911 | struct ftrace_entry *entry; | 931 | struct ftrace_entry *entry; |
912 | 932 | ||
@@ -921,7 +941,9 @@ trace_function(struct trace_array *tr, | |||
921 | entry = ring_buffer_event_data(event); | 941 | entry = ring_buffer_event_data(event); |
922 | entry->ip = ip; | 942 | entry->ip = ip; |
923 | entry->parent_ip = parent_ip; | 943 | entry->parent_ip = parent_ip; |
924 | ring_buffer_unlock_commit(tr->buffer, event); | 944 | |
945 | if (!filter_check_discard(call, entry, tr->buffer, event)) | ||
946 | ring_buffer_unlock_commit(tr->buffer, event); | ||
925 | } | 947 | } |
926 | 948 | ||
927 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 949 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
@@ -930,6 +952,7 @@ static int __trace_graph_entry(struct trace_array *tr, | |||
930 | unsigned long flags, | 952 | unsigned long flags, |
931 | int pc) | 953 | int pc) |
932 | { | 954 | { |
955 | struct ftrace_event_call *call = &event_funcgraph_entry; | ||
933 | struct ring_buffer_event *event; | 956 | struct ring_buffer_event *event; |
934 | struct ftrace_graph_ent_entry *entry; | 957 | struct ftrace_graph_ent_entry *entry; |
935 | 958 | ||
@@ -942,7 +965,8 @@ static int __trace_graph_entry(struct trace_array *tr, | |||
942 | return 0; | 965 | return 0; |
943 | entry = ring_buffer_event_data(event); | 966 | entry = ring_buffer_event_data(event); |
944 | entry->graph_ent = *trace; | 967 | entry->graph_ent = *trace; |
945 | ring_buffer_unlock_commit(global_trace.buffer, event); | 968 | if (!filter_current_check_discard(call, entry, event)) |
969 | ring_buffer_unlock_commit(global_trace.buffer, event); | ||
946 | 970 | ||
947 | return 1; | 971 | return 1; |
948 | } | 972 | } |
@@ -952,6 +976,7 @@ static void __trace_graph_return(struct trace_array *tr, | |||
952 | unsigned long flags, | 976 | unsigned long flags, |
953 | int pc) | 977 | int pc) |
954 | { | 978 | { |
979 | struct ftrace_event_call *call = &event_funcgraph_exit; | ||
955 | struct ring_buffer_event *event; | 980 | struct ring_buffer_event *event; |
956 | struct ftrace_graph_ret_entry *entry; | 981 | struct ftrace_graph_ret_entry *entry; |
957 | 982 | ||
@@ -964,7 +989,8 @@ static void __trace_graph_return(struct trace_array *tr, | |||
964 | return; | 989 | return; |
965 | entry = ring_buffer_event_data(event); | 990 | entry = ring_buffer_event_data(event); |
966 | entry->ret = *trace; | 991 | entry->ret = *trace; |
967 | ring_buffer_unlock_commit(global_trace.buffer, event); | 992 | if (!filter_current_check_discard(call, entry, event)) |
993 | ring_buffer_unlock_commit(global_trace.buffer, event); | ||
968 | } | 994 | } |
969 | #endif | 995 | #endif |
970 | 996 | ||
@@ -982,6 +1008,7 @@ static void __ftrace_trace_stack(struct trace_array *tr, | |||
982 | int skip, int pc) | 1008 | int skip, int pc) |
983 | { | 1009 | { |
984 | #ifdef CONFIG_STACKTRACE | 1010 | #ifdef CONFIG_STACKTRACE |
1011 | struct ftrace_event_call *call = &event_kernel_stack; | ||
985 | struct ring_buffer_event *event; | 1012 | struct ring_buffer_event *event; |
986 | struct stack_entry *entry; | 1013 | struct stack_entry *entry; |
987 | struct stack_trace trace; | 1014 | struct stack_trace trace; |
@@ -999,7 +1026,8 @@ static void __ftrace_trace_stack(struct trace_array *tr, | |||
999 | trace.entries = entry->caller; | 1026 | trace.entries = entry->caller; |
1000 | 1027 | ||
1001 | save_stack_trace(&trace); | 1028 | save_stack_trace(&trace); |
1002 | ring_buffer_unlock_commit(tr->buffer, event); | 1029 | if (!filter_check_discard(call, entry, tr->buffer, event)) |
1030 | ring_buffer_unlock_commit(tr->buffer, event); | ||
1003 | #endif | 1031 | #endif |
1004 | } | 1032 | } |
1005 | 1033 | ||
@@ -1024,6 +1052,7 @@ static void ftrace_trace_userstack(struct trace_array *tr, | |||
1024 | unsigned long flags, int pc) | 1052 | unsigned long flags, int pc) |
1025 | { | 1053 | { |
1026 | #ifdef CONFIG_STACKTRACE | 1054 | #ifdef CONFIG_STACKTRACE |
1055 | struct ftrace_event_call *call = &event_user_stack; | ||
1027 | struct ring_buffer_event *event; | 1056 | struct ring_buffer_event *event; |
1028 | struct userstack_entry *entry; | 1057 | struct userstack_entry *entry; |
1029 | struct stack_trace trace; | 1058 | struct stack_trace trace; |
@@ -1045,7 +1074,8 @@ static void ftrace_trace_userstack(struct trace_array *tr, | |||
1045 | trace.entries = entry->caller; | 1074 | trace.entries = entry->caller; |
1046 | 1075 | ||
1047 | save_stack_trace_user(&trace); | 1076 | save_stack_trace_user(&trace); |
1048 | ring_buffer_unlock_commit(tr->buffer, event); | 1077 | if (!filter_check_discard(call, entry, tr->buffer, event)) |
1078 | ring_buffer_unlock_commit(tr->buffer, event); | ||
1049 | #endif | 1079 | #endif |
1050 | } | 1080 | } |
1051 | 1081 | ||
@@ -1089,6 +1119,7 @@ tracing_sched_switch_trace(struct trace_array *tr, | |||
1089 | struct task_struct *next, | 1119 | struct task_struct *next, |
1090 | unsigned long flags, int pc) | 1120 | unsigned long flags, int pc) |
1091 | { | 1121 | { |
1122 | struct ftrace_event_call *call = &event_context_switch; | ||
1092 | struct ring_buffer_event *event; | 1123 | struct ring_buffer_event *event; |
1093 | struct ctx_switch_entry *entry; | 1124 | struct ctx_switch_entry *entry; |
1094 | 1125 | ||
@@ -1104,7 +1135,9 @@ tracing_sched_switch_trace(struct trace_array *tr, | |||
1104 | entry->next_prio = next->prio; | 1135 | entry->next_prio = next->prio; |
1105 | entry->next_state = next->state; | 1136 | entry->next_state = next->state; |
1106 | entry->next_cpu = task_cpu(next); | 1137 | entry->next_cpu = task_cpu(next); |
1107 | trace_buffer_unlock_commit(tr, event, flags, pc); | 1138 | |
1139 | if (!filter_check_discard(call, entry, tr->buffer, event)) | ||
1140 | trace_buffer_unlock_commit(tr, event, flags, pc); | ||
1108 | } | 1141 | } |
1109 | 1142 | ||
1110 | void | 1143 | void |
@@ -1113,6 +1146,7 @@ tracing_sched_wakeup_trace(struct trace_array *tr, | |||
1113 | struct task_struct *curr, | 1146 | struct task_struct *curr, |
1114 | unsigned long flags, int pc) | 1147 | unsigned long flags, int pc) |
1115 | { | 1148 | { |
1149 | struct ftrace_event_call *call = &event_wakeup; | ||
1116 | struct ring_buffer_event *event; | 1150 | struct ring_buffer_event *event; |
1117 | struct ctx_switch_entry *entry; | 1151 | struct ctx_switch_entry *entry; |
1118 | 1152 | ||
@@ -1129,7 +1163,8 @@ tracing_sched_wakeup_trace(struct trace_array *tr, | |||
1129 | entry->next_state = wakee->state; | 1163 | entry->next_state = wakee->state; |
1130 | entry->next_cpu = task_cpu(wakee); | 1164 | entry->next_cpu = task_cpu(wakee); |
1131 | 1165 | ||
1132 | ring_buffer_unlock_commit(tr->buffer, event); | 1166 | if (!filter_check_discard(call, entry, tr->buffer, event)) |
1167 | ring_buffer_unlock_commit(tr->buffer, event); | ||
1133 | ftrace_trace_stack(tr, flags, 6, pc); | 1168 | ftrace_trace_stack(tr, flags, 6, pc); |
1134 | ftrace_trace_userstack(tr, flags, pc); | 1169 | ftrace_trace_userstack(tr, flags, pc); |
1135 | } | 1170 | } |
@@ -1230,11 +1265,13 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args) | |||
1230 | (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; | 1265 | (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; |
1231 | static u32 trace_buf[TRACE_BUF_SIZE]; | 1266 | static u32 trace_buf[TRACE_BUF_SIZE]; |
1232 | 1267 | ||
1268 | struct ftrace_event_call *call = &event_bprint; | ||
1233 | struct ring_buffer_event *event; | 1269 | struct ring_buffer_event *event; |
1234 | struct trace_array *tr = &global_trace; | 1270 | struct trace_array *tr = &global_trace; |
1235 | struct trace_array_cpu *data; | 1271 | struct trace_array_cpu *data; |
1236 | struct bprint_entry *entry; | 1272 | struct bprint_entry *entry; |
1237 | unsigned long flags; | 1273 | unsigned long flags; |
1274 | int disable; | ||
1238 | int resched; | 1275 | int resched; |
1239 | int cpu, len = 0, size, pc; | 1276 | int cpu, len = 0, size, pc; |
1240 | 1277 | ||
@@ -1249,7 +1286,8 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args) | |||
1249 | cpu = raw_smp_processor_id(); | 1286 | cpu = raw_smp_processor_id(); |
1250 | data = tr->data[cpu]; | 1287 | data = tr->data[cpu]; |
1251 | 1288 | ||
1252 | if (unlikely(atomic_read(&data->disabled))) | 1289 | disable = atomic_inc_return(&data->disabled); |
1290 | if (unlikely(disable != 1)) | ||
1253 | goto out; | 1291 | goto out; |
1254 | 1292 | ||
1255 | /* Lockdep uses trace_printk for lock tracing */ | 1293 | /* Lockdep uses trace_printk for lock tracing */ |
@@ -1269,13 +1307,15 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args) | |||
1269 | entry->fmt = fmt; | 1307 | entry->fmt = fmt; |
1270 | 1308 | ||
1271 | memcpy(entry->buf, trace_buf, sizeof(u32) * len); | 1309 | memcpy(entry->buf, trace_buf, sizeof(u32) * len); |
1272 | ring_buffer_unlock_commit(tr->buffer, event); | 1310 | if (!filter_check_discard(call, entry, tr->buffer, event)) |
1311 | ring_buffer_unlock_commit(tr->buffer, event); | ||
1273 | 1312 | ||
1274 | out_unlock: | 1313 | out_unlock: |
1275 | __raw_spin_unlock(&trace_buf_lock); | 1314 | __raw_spin_unlock(&trace_buf_lock); |
1276 | local_irq_restore(flags); | 1315 | local_irq_restore(flags); |
1277 | 1316 | ||
1278 | out: | 1317 | out: |
1318 | atomic_dec_return(&data->disabled); | ||
1279 | ftrace_preempt_enable(resched); | 1319 | ftrace_preempt_enable(resched); |
1280 | unpause_graph_tracing(); | 1320 | unpause_graph_tracing(); |
1281 | 1321 | ||
@@ -1288,12 +1328,14 @@ int trace_vprintk(unsigned long ip, const char *fmt, va_list args) | |||
1288 | static raw_spinlock_t trace_buf_lock = __RAW_SPIN_LOCK_UNLOCKED; | 1328 | static raw_spinlock_t trace_buf_lock = __RAW_SPIN_LOCK_UNLOCKED; |
1289 | static char trace_buf[TRACE_BUF_SIZE]; | 1329 | static char trace_buf[TRACE_BUF_SIZE]; |
1290 | 1330 | ||
1331 | struct ftrace_event_call *call = &event_print; | ||
1291 | struct ring_buffer_event *event; | 1332 | struct ring_buffer_event *event; |
1292 | struct trace_array *tr = &global_trace; | 1333 | struct trace_array *tr = &global_trace; |
1293 | struct trace_array_cpu *data; | 1334 | struct trace_array_cpu *data; |
1294 | int cpu, len = 0, size, pc; | 1335 | int cpu, len = 0, size, pc; |
1295 | struct print_entry *entry; | 1336 | struct print_entry *entry; |
1296 | unsigned long irq_flags; | 1337 | unsigned long irq_flags; |
1338 | int disable; | ||
1297 | 1339 | ||
1298 | if (tracing_disabled || tracing_selftest_running) | 1340 | if (tracing_disabled || tracing_selftest_running) |
1299 | return 0; | 1341 | return 0; |
@@ -1303,7 +1345,8 @@ int trace_vprintk(unsigned long ip, const char *fmt, va_list args) | |||
1303 | cpu = raw_smp_processor_id(); | 1345 | cpu = raw_smp_processor_id(); |
1304 | data = tr->data[cpu]; | 1346 | data = tr->data[cpu]; |
1305 | 1347 | ||
1306 | if (unlikely(atomic_read(&data->disabled))) | 1348 | disable = atomic_inc_return(&data->disabled); |
1349 | if (unlikely(disable != 1)) | ||
1307 | goto out; | 1350 | goto out; |
1308 | 1351 | ||
1309 | pause_graph_tracing(); | 1352 | pause_graph_tracing(); |
@@ -1323,13 +1366,15 @@ int trace_vprintk(unsigned long ip, const char *fmt, va_list args) | |||
1323 | 1366 | ||
1324 | memcpy(&entry->buf, trace_buf, len); | 1367 | memcpy(&entry->buf, trace_buf, len); |
1325 | entry->buf[len] = 0; | 1368 | entry->buf[len] = 0; |
1326 | ring_buffer_unlock_commit(tr->buffer, event); | 1369 | if (!filter_check_discard(call, entry, tr->buffer, event)) |
1370 | ring_buffer_unlock_commit(tr->buffer, event); | ||
1327 | 1371 | ||
1328 | out_unlock: | 1372 | out_unlock: |
1329 | __raw_spin_unlock(&trace_buf_lock); | 1373 | __raw_spin_unlock(&trace_buf_lock); |
1330 | raw_local_irq_restore(irq_flags); | 1374 | raw_local_irq_restore(irq_flags); |
1331 | unpause_graph_tracing(); | 1375 | unpause_graph_tracing(); |
1332 | out: | 1376 | out: |
1377 | atomic_dec_return(&data->disabled); | ||
1333 | preempt_enable_notrace(); | 1378 | preempt_enable_notrace(); |
1334 | 1379 | ||
1335 | return len; | 1380 | return len; |
@@ -1526,12 +1571,14 @@ static void *s_start(struct seq_file *m, loff_t *pos) | |||
1526 | p = s_next(m, p, &l); | 1571 | p = s_next(m, p, &l); |
1527 | } | 1572 | } |
1528 | 1573 | ||
1574 | trace_event_read_lock(); | ||
1529 | return p; | 1575 | return p; |
1530 | } | 1576 | } |
1531 | 1577 | ||
1532 | static void s_stop(struct seq_file *m, void *p) | 1578 | static void s_stop(struct seq_file *m, void *p) |
1533 | { | 1579 | { |
1534 | atomic_dec(&trace_record_cmdline_disabled); | 1580 | atomic_dec(&trace_record_cmdline_disabled); |
1581 | trace_event_read_unlock(); | ||
1535 | } | 1582 | } |
1536 | 1583 | ||
1537 | static void print_lat_help_header(struct seq_file *m) | 1584 | static void print_lat_help_header(struct seq_file *m) |
@@ -1774,6 +1821,7 @@ static int trace_empty(struct trace_iterator *iter) | |||
1774 | return 1; | 1821 | return 1; |
1775 | } | 1822 | } |
1776 | 1823 | ||
1824 | /* Called with trace_event_read_lock() held. */ | ||
1777 | static enum print_line_t print_trace_line(struct trace_iterator *iter) | 1825 | static enum print_line_t print_trace_line(struct trace_iterator *iter) |
1778 | { | 1826 | { |
1779 | enum print_line_t ret; | 1827 | enum print_line_t ret; |
@@ -2380,7 +2428,7 @@ static const char readme_msg[] = | |||
2380 | "# echo print-parent > /debug/tracing/trace_options\n" | 2428 | "# echo print-parent > /debug/tracing/trace_options\n" |
2381 | "# echo 1 > /debug/tracing/tracing_enabled\n" | 2429 | "# echo 1 > /debug/tracing/tracing_enabled\n" |
2382 | "# cat /debug/tracing/trace > /tmp/trace.txt\n" | 2430 | "# cat /debug/tracing/trace > /tmp/trace.txt\n" |
2383 | "echo 0 > /debug/tracing/tracing_enabled\n" | 2431 | "# echo 0 > /debug/tracing/tracing_enabled\n" |
2384 | ; | 2432 | ; |
2385 | 2433 | ||
2386 | static ssize_t | 2434 | static ssize_t |
@@ -2397,6 +2445,56 @@ static const struct file_operations tracing_readme_fops = { | |||
2397 | }; | 2445 | }; |
2398 | 2446 | ||
2399 | static ssize_t | 2447 | static ssize_t |
2448 | tracing_saved_cmdlines_read(struct file *file, char __user *ubuf, | ||
2449 | size_t cnt, loff_t *ppos) | ||
2450 | { | ||
2451 | char *buf_comm; | ||
2452 | char *file_buf; | ||
2453 | char *buf; | ||
2454 | int len = 0; | ||
2455 | int pid; | ||
2456 | int i; | ||
2457 | |||
2458 | file_buf = kmalloc(SAVED_CMDLINES*(16+TASK_COMM_LEN), GFP_KERNEL); | ||
2459 | if (!file_buf) | ||
2460 | return -ENOMEM; | ||
2461 | |||
2462 | buf_comm = kmalloc(TASK_COMM_LEN, GFP_KERNEL); | ||
2463 | if (!buf_comm) { | ||
2464 | kfree(file_buf); | ||
2465 | return -ENOMEM; | ||
2466 | } | ||
2467 | |||
2468 | buf = file_buf; | ||
2469 | |||
2470 | for (i = 0; i < SAVED_CMDLINES; i++) { | ||
2471 | int r; | ||
2472 | |||
2473 | pid = map_cmdline_to_pid[i]; | ||
2474 | if (pid == -1 || pid == NO_CMDLINE_MAP) | ||
2475 | continue; | ||
2476 | |||
2477 | trace_find_cmdline(pid, buf_comm); | ||
2478 | r = sprintf(buf, "%d %s\n", pid, buf_comm); | ||
2479 | buf += r; | ||
2480 | len += r; | ||
2481 | } | ||
2482 | |||
2483 | len = simple_read_from_buffer(ubuf, cnt, ppos, | ||
2484 | file_buf, len); | ||
2485 | |||
2486 | kfree(file_buf); | ||
2487 | kfree(buf_comm); | ||
2488 | |||
2489 | return len; | ||
2490 | } | ||
2491 | |||
2492 | static const struct file_operations tracing_saved_cmdlines_fops = { | ||
2493 | .open = tracing_open_generic, | ||
2494 | .read = tracing_saved_cmdlines_read, | ||
2495 | }; | ||
2496 | |||
2497 | static ssize_t | ||
2400 | tracing_ctrl_read(struct file *filp, char __user *ubuf, | 2498 | tracing_ctrl_read(struct file *filp, char __user *ubuf, |
2401 | size_t cnt, loff_t *ppos) | 2499 | size_t cnt, loff_t *ppos) |
2402 | { | 2500 | { |
@@ -2728,6 +2826,9 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) | |||
2728 | /* trace pipe does not show start of buffer */ | 2826 | /* trace pipe does not show start of buffer */ |
2729 | cpumask_setall(iter->started); | 2827 | cpumask_setall(iter->started); |
2730 | 2828 | ||
2829 | if (trace_flags & TRACE_ITER_LATENCY_FMT) | ||
2830 | iter->iter_flags |= TRACE_FILE_LAT_FMT; | ||
2831 | |||
2731 | iter->cpu_file = cpu_file; | 2832 | iter->cpu_file = cpu_file; |
2732 | iter->tr = &global_trace; | 2833 | iter->tr = &global_trace; |
2733 | mutex_init(&iter->mutex); | 2834 | mutex_init(&iter->mutex); |
@@ -2915,6 +3016,7 @@ waitagain: | |||
2915 | offsetof(struct trace_iterator, seq)); | 3016 | offsetof(struct trace_iterator, seq)); |
2916 | iter->pos = -1; | 3017 | iter->pos = -1; |
2917 | 3018 | ||
3019 | trace_event_read_lock(); | ||
2918 | while (find_next_entry_inc(iter) != NULL) { | 3020 | while (find_next_entry_inc(iter) != NULL) { |
2919 | enum print_line_t ret; | 3021 | enum print_line_t ret; |
2920 | int len = iter->seq.len; | 3022 | int len = iter->seq.len; |
@@ -2931,6 +3033,7 @@ waitagain: | |||
2931 | if (iter->seq.len >= cnt) | 3033 | if (iter->seq.len >= cnt) |
2932 | break; | 3034 | break; |
2933 | } | 3035 | } |
3036 | trace_event_read_unlock(); | ||
2934 | 3037 | ||
2935 | /* Now copy what we have to the user */ | 3038 | /* Now copy what we have to the user */ |
2936 | sret = trace_seq_to_user(&iter->seq, ubuf, cnt); | 3039 | sret = trace_seq_to_user(&iter->seq, ubuf, cnt); |
@@ -3053,6 +3156,8 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, | |||
3053 | goto out_err; | 3156 | goto out_err; |
3054 | } | 3157 | } |
3055 | 3158 | ||
3159 | trace_event_read_lock(); | ||
3160 | |||
3056 | /* Fill as many pages as possible. */ | 3161 | /* Fill as many pages as possible. */ |
3057 | for (i = 0, rem = len; i < PIPE_BUFFERS && rem; i++) { | 3162 | for (i = 0, rem = len; i < PIPE_BUFFERS && rem; i++) { |
3058 | pages[i] = alloc_page(GFP_KERNEL); | 3163 | pages[i] = alloc_page(GFP_KERNEL); |
@@ -3075,6 +3180,7 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, | |||
3075 | trace_seq_init(&iter->seq); | 3180 | trace_seq_init(&iter->seq); |
3076 | } | 3181 | } |
3077 | 3182 | ||
3183 | trace_event_read_unlock(); | ||
3078 | mutex_unlock(&iter->mutex); | 3184 | mutex_unlock(&iter->mutex); |
3079 | 3185 | ||
3080 | spd.nr_pages = i; | 3186 | spd.nr_pages = i; |
@@ -3425,7 +3531,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
3425 | .spd_release = buffer_spd_release, | 3531 | .spd_release = buffer_spd_release, |
3426 | }; | 3532 | }; |
3427 | struct buffer_ref *ref; | 3533 | struct buffer_ref *ref; |
3428 | int size, i; | 3534 | int entries, size, i; |
3429 | size_t ret; | 3535 | size_t ret; |
3430 | 3536 | ||
3431 | if (*ppos & (PAGE_SIZE - 1)) { | 3537 | if (*ppos & (PAGE_SIZE - 1)) { |
@@ -3440,7 +3546,9 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
3440 | len &= PAGE_MASK; | 3546 | len &= PAGE_MASK; |
3441 | } | 3547 | } |
3442 | 3548 | ||
3443 | for (i = 0; i < PIPE_BUFFERS && len; i++, len -= PAGE_SIZE) { | 3549 | entries = ring_buffer_entries_cpu(info->tr->buffer, info->cpu); |
3550 | |||
3551 | for (i = 0; i < PIPE_BUFFERS && len && entries; i++, len -= PAGE_SIZE) { | ||
3444 | struct page *page; | 3552 | struct page *page; |
3445 | int r; | 3553 | int r; |
3446 | 3554 | ||
@@ -3448,6 +3556,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
3448 | if (!ref) | 3556 | if (!ref) |
3449 | break; | 3557 | break; |
3450 | 3558 | ||
3559 | ref->ref = 1; | ||
3451 | ref->buffer = info->tr->buffer; | 3560 | ref->buffer = info->tr->buffer; |
3452 | ref->page = ring_buffer_alloc_read_page(ref->buffer); | 3561 | ref->page = ring_buffer_alloc_read_page(ref->buffer); |
3453 | if (!ref->page) { | 3562 | if (!ref->page) { |
@@ -3456,7 +3565,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
3456 | } | 3565 | } |
3457 | 3566 | ||
3458 | r = ring_buffer_read_page(ref->buffer, &ref->page, | 3567 | r = ring_buffer_read_page(ref->buffer, &ref->page, |
3459 | len, info->cpu, 0); | 3568 | len, info->cpu, 1); |
3460 | if (r < 0) { | 3569 | if (r < 0) { |
3461 | ring_buffer_free_read_page(ref->buffer, | 3570 | ring_buffer_free_read_page(ref->buffer, |
3462 | ref->page); | 3571 | ref->page); |
@@ -3480,6 +3589,8 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
3480 | spd.partial[i].private = (unsigned long)ref; | 3589 | spd.partial[i].private = (unsigned long)ref; |
3481 | spd.nr_pages++; | 3590 | spd.nr_pages++; |
3482 | *ppos += PAGE_SIZE; | 3591 | *ppos += PAGE_SIZE; |
3592 | |||
3593 | entries = ring_buffer_entries_cpu(info->tr->buffer, info->cpu); | ||
3483 | } | 3594 | } |
3484 | 3595 | ||
3485 | spd.nr_pages = i; | 3596 | spd.nr_pages = i; |
@@ -3507,6 +3618,45 @@ static const struct file_operations tracing_buffers_fops = { | |||
3507 | .llseek = no_llseek, | 3618 | .llseek = no_llseek, |
3508 | }; | 3619 | }; |
3509 | 3620 | ||
3621 | static ssize_t | ||
3622 | tracing_stats_read(struct file *filp, char __user *ubuf, | ||
3623 | size_t count, loff_t *ppos) | ||
3624 | { | ||
3625 | unsigned long cpu = (unsigned long)filp->private_data; | ||
3626 | struct trace_array *tr = &global_trace; | ||
3627 | struct trace_seq *s; | ||
3628 | unsigned long cnt; | ||
3629 | |||
3630 | s = kmalloc(sizeof(*s), GFP_ATOMIC); | ||
3631 | if (!s) | ||
3632 | return ENOMEM; | ||
3633 | |||
3634 | trace_seq_init(s); | ||
3635 | |||
3636 | cnt = ring_buffer_entries_cpu(tr->buffer, cpu); | ||
3637 | trace_seq_printf(s, "entries: %ld\n", cnt); | ||
3638 | |||
3639 | cnt = ring_buffer_overrun_cpu(tr->buffer, cpu); | ||
3640 | trace_seq_printf(s, "overrun: %ld\n", cnt); | ||
3641 | |||
3642 | cnt = ring_buffer_commit_overrun_cpu(tr->buffer, cpu); | ||
3643 | trace_seq_printf(s, "commit overrun: %ld\n", cnt); | ||
3644 | |||
3645 | cnt = ring_buffer_nmi_dropped_cpu(tr->buffer, cpu); | ||
3646 | trace_seq_printf(s, "nmi dropped: %ld\n", cnt); | ||
3647 | |||
3648 | count = simple_read_from_buffer(ubuf, count, ppos, s->buffer, s->len); | ||
3649 | |||
3650 | kfree(s); | ||
3651 | |||
3652 | return count; | ||
3653 | } | ||
3654 | |||
3655 | static const struct file_operations tracing_stats_fops = { | ||
3656 | .open = tracing_open_generic, | ||
3657 | .read = tracing_stats_read, | ||
3658 | }; | ||
3659 | |||
3510 | #ifdef CONFIG_DYNAMIC_FTRACE | 3660 | #ifdef CONFIG_DYNAMIC_FTRACE |
3511 | 3661 | ||
3512 | int __weak ftrace_arch_read_dyn_info(char *buf, int size) | 3662 | int __weak ftrace_arch_read_dyn_info(char *buf, int size) |
@@ -3596,7 +3746,7 @@ struct dentry *tracing_dentry_percpu(void) | |||
3596 | static void tracing_init_debugfs_percpu(long cpu) | 3746 | static void tracing_init_debugfs_percpu(long cpu) |
3597 | { | 3747 | { |
3598 | struct dentry *d_percpu = tracing_dentry_percpu(); | 3748 | struct dentry *d_percpu = tracing_dentry_percpu(); |
3599 | struct dentry *entry, *d_cpu; | 3749 | struct dentry *d_cpu; |
3600 | /* strlen(cpu) + MAX(log10(cpu)) + '\0' */ | 3750 | /* strlen(cpu) + MAX(log10(cpu)) + '\0' */ |
3601 | char cpu_dir[7]; | 3751 | char cpu_dir[7]; |
3602 | 3752 | ||
@@ -3611,21 +3761,18 @@ static void tracing_init_debugfs_percpu(long cpu) | |||
3611 | } | 3761 | } |
3612 | 3762 | ||
3613 | /* per cpu trace_pipe */ | 3763 | /* per cpu trace_pipe */ |
3614 | entry = debugfs_create_file("trace_pipe", 0444, d_cpu, | 3764 | trace_create_file("trace_pipe", 0444, d_cpu, |
3615 | (void *) cpu, &tracing_pipe_fops); | 3765 | (void *) cpu, &tracing_pipe_fops); |
3616 | if (!entry) | ||
3617 | pr_warning("Could not create debugfs 'trace_pipe' entry\n"); | ||
3618 | 3766 | ||
3619 | /* per cpu trace */ | 3767 | /* per cpu trace */ |
3620 | entry = debugfs_create_file("trace", 0644, d_cpu, | 3768 | trace_create_file("trace", 0644, d_cpu, |
3621 | (void *) cpu, &tracing_fops); | 3769 | (void *) cpu, &tracing_fops); |
3622 | if (!entry) | 3770 | |
3623 | pr_warning("Could not create debugfs 'trace' entry\n"); | 3771 | trace_create_file("trace_pipe_raw", 0444, d_cpu, |
3772 | (void *) cpu, &tracing_buffers_fops); | ||
3624 | 3773 | ||
3625 | entry = debugfs_create_file("trace_pipe_raw", 0444, d_cpu, | 3774 | trace_create_file("stats", 0444, d_cpu, |
3626 | (void *) cpu, &tracing_buffers_fops); | 3775 | (void *) cpu, &tracing_stats_fops); |
3627 | if (!entry) | ||
3628 | pr_warning("Could not create debugfs 'trace_pipe_raw' entry\n"); | ||
3629 | } | 3776 | } |
3630 | 3777 | ||
3631 | #ifdef CONFIG_FTRACE_SELFTEST | 3778 | #ifdef CONFIG_FTRACE_SELFTEST |
@@ -3781,6 +3928,22 @@ static const struct file_operations trace_options_core_fops = { | |||
3781 | .write = trace_options_core_write, | 3928 | .write = trace_options_core_write, |
3782 | }; | 3929 | }; |
3783 | 3930 | ||
3931 | struct dentry *trace_create_file(const char *name, | ||
3932 | mode_t mode, | ||
3933 | struct dentry *parent, | ||
3934 | void *data, | ||
3935 | const struct file_operations *fops) | ||
3936 | { | ||
3937 | struct dentry *ret; | ||
3938 | |||
3939 | ret = debugfs_create_file(name, mode, parent, data, fops); | ||
3940 | if (!ret) | ||
3941 | pr_warning("Could not create debugfs '%s' entry\n", name); | ||
3942 | |||
3943 | return ret; | ||
3944 | } | ||
3945 | |||
3946 | |||
3784 | static struct dentry *trace_options_init_dentry(void) | 3947 | static struct dentry *trace_options_init_dentry(void) |
3785 | { | 3948 | { |
3786 | struct dentry *d_tracer; | 3949 | struct dentry *d_tracer; |
@@ -3808,7 +3971,6 @@ create_trace_option_file(struct trace_option_dentry *topt, | |||
3808 | struct tracer_opt *opt) | 3971 | struct tracer_opt *opt) |
3809 | { | 3972 | { |
3810 | struct dentry *t_options; | 3973 | struct dentry *t_options; |
3811 | struct dentry *entry; | ||
3812 | 3974 | ||
3813 | t_options = trace_options_init_dentry(); | 3975 | t_options = trace_options_init_dentry(); |
3814 | if (!t_options) | 3976 | if (!t_options) |
@@ -3817,11 +3979,9 @@ create_trace_option_file(struct trace_option_dentry *topt, | |||
3817 | topt->flags = flags; | 3979 | topt->flags = flags; |
3818 | topt->opt = opt; | 3980 | topt->opt = opt; |
3819 | 3981 | ||
3820 | entry = debugfs_create_file(opt->name, 0644, t_options, topt, | 3982 | topt->entry = trace_create_file(opt->name, 0644, t_options, topt, |
3821 | &trace_options_fops); | 3983 | &trace_options_fops); |
3822 | 3984 | ||
3823 | topt->entry = entry; | ||
3824 | |||
3825 | } | 3985 | } |
3826 | 3986 | ||
3827 | static struct trace_option_dentry * | 3987 | static struct trace_option_dentry * |
@@ -3876,123 +4036,84 @@ static struct dentry * | |||
3876 | create_trace_option_core_file(const char *option, long index) | 4036 | create_trace_option_core_file(const char *option, long index) |
3877 | { | 4037 | { |
3878 | struct dentry *t_options; | 4038 | struct dentry *t_options; |
3879 | struct dentry *entry; | ||
3880 | 4039 | ||
3881 | t_options = trace_options_init_dentry(); | 4040 | t_options = trace_options_init_dentry(); |
3882 | if (!t_options) | 4041 | if (!t_options) |
3883 | return NULL; | 4042 | return NULL; |
3884 | 4043 | ||
3885 | entry = debugfs_create_file(option, 0644, t_options, (void *)index, | 4044 | return trace_create_file(option, 0644, t_options, (void *)index, |
3886 | &trace_options_core_fops); | 4045 | &trace_options_core_fops); |
3887 | |||
3888 | return entry; | ||
3889 | } | 4046 | } |
3890 | 4047 | ||
3891 | static __init void create_trace_options_dir(void) | 4048 | static __init void create_trace_options_dir(void) |
3892 | { | 4049 | { |
3893 | struct dentry *t_options; | 4050 | struct dentry *t_options; |
3894 | struct dentry *entry; | ||
3895 | int i; | 4051 | int i; |
3896 | 4052 | ||
3897 | t_options = trace_options_init_dentry(); | 4053 | t_options = trace_options_init_dentry(); |
3898 | if (!t_options) | 4054 | if (!t_options) |
3899 | return; | 4055 | return; |
3900 | 4056 | ||
3901 | for (i = 0; trace_options[i]; i++) { | 4057 | for (i = 0; trace_options[i]; i++) |
3902 | entry = create_trace_option_core_file(trace_options[i], i); | 4058 | create_trace_option_core_file(trace_options[i], i); |
3903 | if (!entry) | ||
3904 | pr_warning("Could not create debugfs %s entry\n", | ||
3905 | trace_options[i]); | ||
3906 | } | ||
3907 | } | 4059 | } |
3908 | 4060 | ||
3909 | static __init int tracer_init_debugfs(void) | 4061 | static __init int tracer_init_debugfs(void) |
3910 | { | 4062 | { |
3911 | struct dentry *d_tracer; | 4063 | struct dentry *d_tracer; |
3912 | struct dentry *entry; | ||
3913 | int cpu; | 4064 | int cpu; |
3914 | 4065 | ||
3915 | d_tracer = tracing_init_dentry(); | 4066 | d_tracer = tracing_init_dentry(); |
3916 | 4067 | ||
3917 | entry = debugfs_create_file("tracing_enabled", 0644, d_tracer, | 4068 | trace_create_file("tracing_enabled", 0644, d_tracer, |
3918 | &global_trace, &tracing_ctrl_fops); | 4069 | &global_trace, &tracing_ctrl_fops); |
3919 | if (!entry) | ||
3920 | pr_warning("Could not create debugfs 'tracing_enabled' entry\n"); | ||
3921 | 4070 | ||
3922 | entry = debugfs_create_file("trace_options", 0644, d_tracer, | 4071 | trace_create_file("trace_options", 0644, d_tracer, |
3923 | NULL, &tracing_iter_fops); | 4072 | NULL, &tracing_iter_fops); |
3924 | if (!entry) | ||
3925 | pr_warning("Could not create debugfs 'trace_options' entry\n"); | ||
3926 | 4073 | ||
3927 | create_trace_options_dir(); | 4074 | trace_create_file("tracing_cpumask", 0644, d_tracer, |
4075 | NULL, &tracing_cpumask_fops); | ||
4076 | |||
4077 | trace_create_file("trace", 0644, d_tracer, | ||
4078 | (void *) TRACE_PIPE_ALL_CPU, &tracing_fops); | ||
3928 | 4079 | ||
3929 | entry = debugfs_create_file("tracing_cpumask", 0644, d_tracer, | 4080 | trace_create_file("available_tracers", 0444, d_tracer, |
3930 | NULL, &tracing_cpumask_fops); | 4081 | &global_trace, &show_traces_fops); |
3931 | if (!entry) | 4082 | |
3932 | pr_warning("Could not create debugfs 'tracing_cpumask' entry\n"); | 4083 | trace_create_file("current_tracer", 0644, d_tracer, |
3933 | 4084 | &global_trace, &set_tracer_fops); | |
3934 | entry = debugfs_create_file("trace", 0644, d_tracer, | 4085 | |
3935 | (void *) TRACE_PIPE_ALL_CPU, &tracing_fops); | 4086 | trace_create_file("tracing_max_latency", 0644, d_tracer, |
3936 | if (!entry) | 4087 | &tracing_max_latency, &tracing_max_lat_fops); |
3937 | pr_warning("Could not create debugfs 'trace' entry\n"); | 4088 | |
3938 | 4089 | trace_create_file("tracing_thresh", 0644, d_tracer, | |
3939 | entry = debugfs_create_file("available_tracers", 0444, d_tracer, | 4090 | &tracing_thresh, &tracing_max_lat_fops); |
3940 | &global_trace, &show_traces_fops); | 4091 | |
3941 | if (!entry) | 4092 | trace_create_file("README", 0444, d_tracer, |
3942 | pr_warning("Could not create debugfs 'available_tracers' entry\n"); | 4093 | NULL, &tracing_readme_fops); |
3943 | 4094 | ||
3944 | entry = debugfs_create_file("current_tracer", 0444, d_tracer, | 4095 | trace_create_file("trace_pipe", 0444, d_tracer, |
3945 | &global_trace, &set_tracer_fops); | ||
3946 | if (!entry) | ||
3947 | pr_warning("Could not create debugfs 'current_tracer' entry\n"); | ||
3948 | |||
3949 | entry = debugfs_create_file("tracing_max_latency", 0644, d_tracer, | ||
3950 | &tracing_max_latency, | ||
3951 | &tracing_max_lat_fops); | ||
3952 | if (!entry) | ||
3953 | pr_warning("Could not create debugfs " | ||
3954 | "'tracing_max_latency' entry\n"); | ||
3955 | |||
3956 | entry = debugfs_create_file("tracing_thresh", 0644, d_tracer, | ||
3957 | &tracing_thresh, &tracing_max_lat_fops); | ||
3958 | if (!entry) | ||
3959 | pr_warning("Could not create debugfs " | ||
3960 | "'tracing_thresh' entry\n"); | ||
3961 | entry = debugfs_create_file("README", 0644, d_tracer, | ||
3962 | NULL, &tracing_readme_fops); | ||
3963 | if (!entry) | ||
3964 | pr_warning("Could not create debugfs 'README' entry\n"); | ||
3965 | |||
3966 | entry = debugfs_create_file("trace_pipe", 0444, d_tracer, | ||
3967 | (void *) TRACE_PIPE_ALL_CPU, &tracing_pipe_fops); | 4096 | (void *) TRACE_PIPE_ALL_CPU, &tracing_pipe_fops); |
3968 | if (!entry) | 4097 | |
3969 | pr_warning("Could not create debugfs " | 4098 | trace_create_file("buffer_size_kb", 0644, d_tracer, |
3970 | "'trace_pipe' entry\n"); | 4099 | &global_trace, &tracing_entries_fops); |
3971 | 4100 | ||
3972 | entry = debugfs_create_file("buffer_size_kb", 0644, d_tracer, | 4101 | trace_create_file("trace_marker", 0220, d_tracer, |
3973 | &global_trace, &tracing_entries_fops); | 4102 | NULL, &tracing_mark_fops); |
3974 | if (!entry) | 4103 | |
3975 | pr_warning("Could not create debugfs " | 4104 | trace_create_file("saved_cmdlines", 0444, d_tracer, |
3976 | "'buffer_size_kb' entry\n"); | 4105 | NULL, &tracing_saved_cmdlines_fops); |
3977 | |||
3978 | entry = debugfs_create_file("trace_marker", 0220, d_tracer, | ||
3979 | NULL, &tracing_mark_fops); | ||
3980 | if (!entry) | ||
3981 | pr_warning("Could not create debugfs " | ||
3982 | "'trace_marker' entry\n"); | ||
3983 | 4106 | ||
3984 | #ifdef CONFIG_DYNAMIC_FTRACE | 4107 | #ifdef CONFIG_DYNAMIC_FTRACE |
3985 | entry = debugfs_create_file("dyn_ftrace_total_info", 0444, d_tracer, | 4108 | trace_create_file("dyn_ftrace_total_info", 0444, d_tracer, |
3986 | &ftrace_update_tot_cnt, | 4109 | &ftrace_update_tot_cnt, &tracing_dyn_info_fops); |
3987 | &tracing_dyn_info_fops); | ||
3988 | if (!entry) | ||
3989 | pr_warning("Could not create debugfs " | ||
3990 | "'dyn_ftrace_total_info' entry\n"); | ||
3991 | #endif | 4110 | #endif |
3992 | #ifdef CONFIG_SYSPROF_TRACER | 4111 | #ifdef CONFIG_SYSPROF_TRACER |
3993 | init_tracer_sysprof_debugfs(d_tracer); | 4112 | init_tracer_sysprof_debugfs(d_tracer); |
3994 | #endif | 4113 | #endif |
3995 | 4114 | ||
4115 | create_trace_options_dir(); | ||
4116 | |||
3996 | for_each_tracing_cpu(cpu) | 4117 | for_each_tracing_cpu(cpu) |
3997 | tracing_init_debugfs_percpu(cpu); | 4118 | tracing_init_debugfs_percpu(cpu); |
3998 | 4119 | ||
@@ -4063,7 +4184,8 @@ trace_printk_seq(struct trace_seq *s) | |||
4063 | 4184 | ||
4064 | static void __ftrace_dump(bool disable_tracing) | 4185 | static void __ftrace_dump(bool disable_tracing) |
4065 | { | 4186 | { |
4066 | static DEFINE_SPINLOCK(ftrace_dump_lock); | 4187 | static raw_spinlock_t ftrace_dump_lock = |
4188 | (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; | ||
4067 | /* use static because iter can be a bit big for the stack */ | 4189 | /* use static because iter can be a bit big for the stack */ |
4068 | static struct trace_iterator iter; | 4190 | static struct trace_iterator iter; |
4069 | unsigned int old_userobj; | 4191 | unsigned int old_userobj; |
@@ -4072,7 +4194,8 @@ static void __ftrace_dump(bool disable_tracing) | |||
4072 | int cnt = 0, cpu; | 4194 | int cnt = 0, cpu; |
4073 | 4195 | ||
4074 | /* only one dump */ | 4196 | /* only one dump */ |
4075 | spin_lock_irqsave(&ftrace_dump_lock, flags); | 4197 | local_irq_save(flags); |
4198 | __raw_spin_lock(&ftrace_dump_lock); | ||
4076 | if (dump_ran) | 4199 | if (dump_ran) |
4077 | goto out; | 4200 | goto out; |
4078 | 4201 | ||
@@ -4144,7 +4267,8 @@ static void __ftrace_dump(bool disable_tracing) | |||
4144 | } | 4267 | } |
4145 | 4268 | ||
4146 | out: | 4269 | out: |
4147 | spin_unlock_irqrestore(&ftrace_dump_lock, flags); | 4270 | __raw_spin_unlock(&ftrace_dump_lock); |
4271 | local_irq_restore(flags); | ||
4148 | } | 4272 | } |
4149 | 4273 | ||
4150 | /* By default: disable tracing after the dump */ | 4274 | /* By default: disable tracing after the dump */ |