diff options
-rw-r--r-- | Documentation/ftrace.txt | 46 | ||||
-rw-r--r-- | kernel/trace/ftrace.c | 3 | ||||
-rw-r--r-- | kernel/trace/ring_buffer.c | 6 | ||||
-rw-r--r-- | kernel/trace/trace.c | 43 | ||||
-rw-r--r-- | kernel/trace/trace.h | 1 |
5 files changed, 55 insertions, 44 deletions
diff --git a/Documentation/ftrace.txt b/Documentation/ftrace.txt index 9cc4d685dde5..753f4de4b175 100644 --- a/Documentation/ftrace.txt +++ b/Documentation/ftrace.txt | |||
@@ -82,7 +82,7 @@ of ftrace. Here is a list of some of the key files: | |||
82 | tracer is not adding more data, they will display | 82 | tracer is not adding more data, they will display |
83 | the same information every time they are read. | 83 | the same information every time they are read. |
84 | 84 | ||
85 | iter_ctrl: This file lets the user control the amount of data | 85 | trace_options: This file lets the user control the amount of data |
86 | that is displayed in one of the above output | 86 | that is displayed in one of the above output |
87 | files. | 87 | files. |
88 | 88 | ||
@@ -94,10 +94,10 @@ of ftrace. Here is a list of some of the key files: | |||
94 | only be recorded if the latency is greater than | 94 | only be recorded if the latency is greater than |
95 | the value in this file. (in microseconds) | 95 | the value in this file. (in microseconds) |
96 | 96 | ||
97 | trace_entries: This sets or displays the number of bytes each CPU | 97 | buffer_size_kb: This sets or displays the number of kilobytes each CPU |
98 | buffer can hold. The tracer buffers are the same size | 98 | buffer can hold. The tracer buffers are the same size |
99 | for each CPU. The displayed number is the size of the | 99 | for each CPU. The displayed number is the size of the |
100 | CPU buffer and not total size of all buffers. The | 100 | CPU buffer and not total size of all buffers. The |
101 | trace buffers are allocated in pages (blocks of memory | 101 | trace buffers are allocated in pages (blocks of memory |
102 | that the kernel uses for allocation, usually 4 KB in size). | 102 | that the kernel uses for allocation, usually 4 KB in size). |
103 | If the last page allocated has room for more bytes | 103 | If the last page allocated has room for more bytes |
@@ -316,23 +316,23 @@ The above is mostly meaningful for kernel developers. | |||
316 | The rest is the same as the 'trace' file. | 316 | The rest is the same as the 'trace' file. |
317 | 317 | ||
318 | 318 | ||
319 | iter_ctrl | 319 | trace_options |
320 | --------- | 320 | ------------- |
321 | 321 | ||
322 | The iter_ctrl file is used to control what gets printed in the trace | 322 | The trace_options file is used to control what gets printed in the trace |
323 | output. To see what is available, simply cat the file: | 323 | output. To see what is available, simply cat the file: |
324 | 324 | ||
325 | cat /debug/tracing/iter_ctrl | 325 | cat /debug/tracing/trace_options |
326 | print-parent nosym-offset nosym-addr noverbose noraw nohex nobin \ | 326 | print-parent nosym-offset nosym-addr noverbose noraw nohex nobin \ |
327 | noblock nostacktrace nosched-tree | 327 | noblock nostacktrace nosched-tree |
328 | 328 | ||
329 | To disable one of the options, echo in the option prepended with "no". | 329 | To disable one of the options, echo in the option prepended with "no". |
330 | 330 | ||
331 | echo noprint-parent > /debug/tracing/iter_ctrl | 331 | echo noprint-parent > /debug/tracing/trace_options |
332 | 332 | ||
333 | To enable an option, leave off the "no". | 333 | To enable an option, leave off the "no". |
334 | 334 | ||
335 | echo sym-offset > /debug/tracing/iter_ctrl | 335 | echo sym-offset > /debug/tracing/trace_options |
336 | 336 | ||
337 | Here are the available options: | 337 | Here are the available options: |
338 | 338 | ||
@@ -1299,41 +1299,29 @@ trace entries | |||
1299 | ------------- | 1299 | ------------- |
1300 | 1300 | ||
1301 | Having too much or not enough data can be troublesome in diagnosing | 1301 | Having too much or not enough data can be troublesome in diagnosing |
1302 | an issue in the kernel. The file trace_entries is used to modify | 1302 | an issue in the kernel. The file buffer_size_kb is used to modify |
1303 | the size of the internal trace buffers. The number listed | 1303 | the size of the internal trace buffers. The number listed |
1304 | is the number of entries that can be recorded per CPU. To know | 1304 | is the number of entries that can be recorded per CPU. To know |
1305 | the full size, multiply the number of possible CPUS with the | 1305 | the full size, multiply the number of possible CPUS with the |
1306 | number of entries. | 1306 | number of entries. |
1307 | 1307 | ||
1308 | # cat /debug/tracing/trace_entries | 1308 | # cat /debug/tracing/buffer_size_kb |
1309 | 65620 | 1309 | 1408 (units kilobytes) |
1310 | 1310 | ||
1311 | Note, to modify this, you must have tracing completely disabled. To do that, | 1311 | Note, to modify this, you must have tracing completely disabled. To do that, |
1312 | echo "nop" into the current_tracer. If the current_tracer is not set | 1312 | echo "nop" into the current_tracer. If the current_tracer is not set |
1313 | to "nop", an EINVAL error will be returned. | 1313 | to "nop", an EINVAL error will be returned. |
1314 | 1314 | ||
1315 | # echo nop > /debug/tracing/current_tracer | 1315 | # echo nop > /debug/tracing/current_tracer |
1316 | # echo 100000 > /debug/tracing/trace_entries | 1316 | # echo 10000 > /debug/tracing/buffer_size_kb |
1317 | # cat /debug/tracing/trace_entries | 1317 | # cat /debug/tracing/buffer_size_kb |
1318 | 100045 | 1318 | 10000 (units kilobytes) |
1319 | |||
1320 | |||
1321 | Notice that we echoed in 100,000 but the size is 100,045. The entries | ||
1322 | are held in individual pages. It allocates the number of pages it takes | ||
1323 | to fulfill the request. If more entries may fit on the last page | ||
1324 | then they will be added. | ||
1325 | |||
1326 | # echo 1 > /debug/tracing/trace_entries | ||
1327 | # cat /debug/tracing/trace_entries | ||
1328 | 85 | ||
1329 | |||
1330 | This shows us that 85 entries can fit in a single page. | ||
1331 | 1319 | ||
1332 | The number of pages which will be allocated is limited to a percentage | 1320 | The number of pages which will be allocated is limited to a percentage |
1333 | of available memory. Allocating too much will produce an error. | 1321 | of available memory. Allocating too much will produce an error. |
1334 | 1322 | ||
1335 | # echo 1000000000000 > /debug/tracing/trace_entries | 1323 | # echo 1000000000000 > /debug/tracing/buffer_size_kb |
1336 | -bash: echo: write error: Cannot allocate memory | 1324 | -bash: echo: write error: Cannot allocate memory |
1337 | # cat /debug/tracing/trace_entries | 1325 | # cat /debug/tracing/buffer_size_kb |
1338 | 85 | 1326 | 85 |
1339 | 1327 | ||
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index beb21a51e1ef..54cb9a7d15e5 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -179,8 +179,7 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops) | |||
179 | 179 | ||
180 | if (ftrace_enabled) { | 180 | if (ftrace_enabled) { |
181 | /* If we only have one func left, then call that directly */ | 181 | /* If we only have one func left, then call that directly */ |
182 | if (ftrace_list == &ftrace_list_end || | 182 | if (ftrace_list->next == &ftrace_list_end) |
183 | ftrace_list->next == &ftrace_list_end) | ||
184 | ftrace_trace_function = ftrace_list->func; | 183 | ftrace_trace_function = ftrace_list->func; |
185 | } | 184 | } |
186 | 185 | ||
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 2d6c2cf0c3bc..caa4fda50f8a 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -533,6 +533,12 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size) | |||
533 | LIST_HEAD(pages); | 533 | LIST_HEAD(pages); |
534 | int i, cpu; | 534 | int i, cpu; |
535 | 535 | ||
536 | /* | ||
537 | * Always succeed at resizing a non-existent buffer: | ||
538 | */ | ||
539 | if (!buffer) | ||
540 | return size; | ||
541 | |||
536 | size = DIV_ROUND_UP(size, BUF_PAGE_SIZE); | 542 | size = DIV_ROUND_UP(size, BUF_PAGE_SIZE); |
537 | size *= BUF_PAGE_SIZE; | 543 | size *= BUF_PAGE_SIZE; |
538 | buffer_size = buffer->pages * BUF_PAGE_SIZE; | 544 | buffer_size = buffer->pages * BUF_PAGE_SIZE; |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 4bf070bb5272..4a904623e05d 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -204,8 +204,9 @@ static DEFINE_MUTEX(trace_types_lock); | |||
204 | /* trace_wait is a waitqueue for tasks blocked on trace_poll */ | 204 | /* trace_wait is a waitqueue for tasks blocked on trace_poll */ |
205 | static DECLARE_WAIT_QUEUE_HEAD(trace_wait); | 205 | static DECLARE_WAIT_QUEUE_HEAD(trace_wait); |
206 | 206 | ||
207 | /* trace_flags holds iter_ctrl options */ | 207 | /* trace_flags holds trace_options default values */ |
208 | unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK; | 208 | unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK | |
209 | TRACE_ITER_ANNOTATE; | ||
209 | 210 | ||
210 | /** | 211 | /** |
211 | * trace_wake_up - wake up tasks waiting for trace input | 212 | * trace_wake_up - wake up tasks waiting for trace input |
@@ -261,6 +262,7 @@ static const char *trace_options[] = { | |||
261 | #ifdef CONFIG_BRANCH_TRACER | 262 | #ifdef CONFIG_BRANCH_TRACER |
262 | "branch", | 263 | "branch", |
263 | #endif | 264 | #endif |
265 | "annotate", | ||
264 | NULL | 266 | NULL |
265 | }; | 267 | }; |
266 | 268 | ||
@@ -1113,6 +1115,7 @@ void tracing_stop_function_trace(void) | |||
1113 | 1115 | ||
1114 | enum trace_file_type { | 1116 | enum trace_file_type { |
1115 | TRACE_FILE_LAT_FMT = 1, | 1117 | TRACE_FILE_LAT_FMT = 1, |
1118 | TRACE_FILE_ANNOTATE = 2, | ||
1116 | }; | 1119 | }; |
1117 | 1120 | ||
1118 | static void trace_iterator_increment(struct trace_iterator *iter, int cpu) | 1121 | static void trace_iterator_increment(struct trace_iterator *iter, int cpu) |
@@ -1532,6 +1535,12 @@ static void test_cpu_buff_start(struct trace_iterator *iter) | |||
1532 | { | 1535 | { |
1533 | struct trace_seq *s = &iter->seq; | 1536 | struct trace_seq *s = &iter->seq; |
1534 | 1537 | ||
1538 | if (!(trace_flags & TRACE_ITER_ANNOTATE)) | ||
1539 | return; | ||
1540 | |||
1541 | if (!(iter->iter_flags & TRACE_FILE_ANNOTATE)) | ||
1542 | return; | ||
1543 | |||
1535 | if (cpu_isset(iter->cpu, iter->started)) | 1544 | if (cpu_isset(iter->cpu, iter->started)) |
1536 | return; | 1545 | return; |
1537 | 1546 | ||
@@ -2132,6 +2141,11 @@ __tracing_open(struct inode *inode, struct file *file, int *ret) | |||
2132 | iter->trace = current_trace; | 2141 | iter->trace = current_trace; |
2133 | iter->pos = -1; | 2142 | iter->pos = -1; |
2134 | 2143 | ||
2144 | /* Annotate start of buffers if we had overruns */ | ||
2145 | if (ring_buffer_overruns(iter->tr->buffer)) | ||
2146 | iter->iter_flags |= TRACE_FILE_ANNOTATE; | ||
2147 | |||
2148 | |||
2135 | for_each_tracing_cpu(cpu) { | 2149 | for_each_tracing_cpu(cpu) { |
2136 | 2150 | ||
2137 | iter->buffer_iter[cpu] = | 2151 | iter->buffer_iter[cpu] = |
@@ -2411,7 +2425,7 @@ static struct file_operations tracing_cpumask_fops = { | |||
2411 | }; | 2425 | }; |
2412 | 2426 | ||
2413 | static ssize_t | 2427 | static ssize_t |
2414 | tracing_iter_ctrl_read(struct file *filp, char __user *ubuf, | 2428 | tracing_trace_options_read(struct file *filp, char __user *ubuf, |
2415 | size_t cnt, loff_t *ppos) | 2429 | size_t cnt, loff_t *ppos) |
2416 | { | 2430 | { |
2417 | char *buf; | 2431 | char *buf; |
@@ -2448,7 +2462,7 @@ tracing_iter_ctrl_read(struct file *filp, char __user *ubuf, | |||
2448 | } | 2462 | } |
2449 | 2463 | ||
2450 | static ssize_t | 2464 | static ssize_t |
2451 | tracing_iter_ctrl_write(struct file *filp, const char __user *ubuf, | 2465 | tracing_trace_options_write(struct file *filp, const char __user *ubuf, |
2452 | size_t cnt, loff_t *ppos) | 2466 | size_t cnt, loff_t *ppos) |
2453 | { | 2467 | { |
2454 | char buf[64]; | 2468 | char buf[64]; |
@@ -2493,8 +2507,8 @@ tracing_iter_ctrl_write(struct file *filp, const char __user *ubuf, | |||
2493 | 2507 | ||
2494 | static struct file_operations tracing_iter_fops = { | 2508 | static struct file_operations tracing_iter_fops = { |
2495 | .open = tracing_open_generic, | 2509 | .open = tracing_open_generic, |
2496 | .read = tracing_iter_ctrl_read, | 2510 | .read = tracing_trace_options_read, |
2497 | .write = tracing_iter_ctrl_write, | 2511 | .write = tracing_trace_options_write, |
2498 | }; | 2512 | }; |
2499 | 2513 | ||
2500 | static const char readme_msg[] = | 2514 | static const char readme_msg[] = |
@@ -2508,9 +2522,9 @@ static const char readme_msg[] = | |||
2508 | "# echo sched_switch > /debug/tracing/current_tracer\n" | 2522 | "# echo sched_switch > /debug/tracing/current_tracer\n" |
2509 | "# cat /debug/tracing/current_tracer\n" | 2523 | "# cat /debug/tracing/current_tracer\n" |
2510 | "sched_switch\n" | 2524 | "sched_switch\n" |
2511 | "# cat /debug/tracing/iter_ctrl\n" | 2525 | "# cat /debug/tracing/trace_options\n" |
2512 | "noprint-parent nosym-offset nosym-addr noverbose\n" | 2526 | "noprint-parent nosym-offset nosym-addr noverbose\n" |
2513 | "# echo print-parent > /debug/tracing/iter_ctrl\n" | 2527 | "# echo print-parent > /debug/tracing/trace_options\n" |
2514 | "# echo 1 > /debug/tracing/tracing_enabled\n" | 2528 | "# echo 1 > /debug/tracing/tracing_enabled\n" |
2515 | "# cat /debug/tracing/trace > /tmp/trace.txt\n" | 2529 | "# cat /debug/tracing/trace > /tmp/trace.txt\n" |
2516 | "echo 0 > /debug/tracing/tracing_enabled\n" | 2530 | "echo 0 > /debug/tracing/tracing_enabled\n" |
@@ -2905,7 +2919,7 @@ tracing_entries_read(struct file *filp, char __user *ubuf, | |||
2905 | char buf[64]; | 2919 | char buf[64]; |
2906 | int r; | 2920 | int r; |
2907 | 2921 | ||
2908 | r = sprintf(buf, "%lu\n", tr->entries); | 2922 | r = sprintf(buf, "%lu\n", tr->entries >> 10); |
2909 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); | 2923 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); |
2910 | } | 2924 | } |
2911 | 2925 | ||
@@ -2945,6 +2959,9 @@ tracing_entries_write(struct file *filp, const char __user *ubuf, | |||
2945 | atomic_inc(&max_tr.data[cpu]->disabled); | 2959 | atomic_inc(&max_tr.data[cpu]->disabled); |
2946 | } | 2960 | } |
2947 | 2961 | ||
2962 | /* value is in KB */ | ||
2963 | val <<= 10; | ||
2964 | |||
2948 | if (val != global_trace.entries) { | 2965 | if (val != global_trace.entries) { |
2949 | ret = ring_buffer_resize(global_trace.buffer, val); | 2966 | ret = ring_buffer_resize(global_trace.buffer, val); |
2950 | if (ret < 0) { | 2967 | if (ret < 0) { |
@@ -3145,10 +3162,10 @@ static __init int tracer_init_debugfs(void) | |||
3145 | if (!entry) | 3162 | if (!entry) |
3146 | pr_warning("Could not create debugfs 'tracing_enabled' entry\n"); | 3163 | pr_warning("Could not create debugfs 'tracing_enabled' entry\n"); |
3147 | 3164 | ||
3148 | entry = debugfs_create_file("iter_ctrl", 0644, d_tracer, | 3165 | entry = debugfs_create_file("trace_options", 0644, d_tracer, |
3149 | NULL, &tracing_iter_fops); | 3166 | NULL, &tracing_iter_fops); |
3150 | if (!entry) | 3167 | if (!entry) |
3151 | pr_warning("Could not create debugfs 'iter_ctrl' entry\n"); | 3168 | pr_warning("Could not create debugfs 'trace_options' entry\n"); |
3152 | 3169 | ||
3153 | entry = debugfs_create_file("tracing_cpumask", 0644, d_tracer, | 3170 | entry = debugfs_create_file("tracing_cpumask", 0644, d_tracer, |
3154 | NULL, &tracing_cpumask_fops); | 3171 | NULL, &tracing_cpumask_fops); |
@@ -3198,11 +3215,11 @@ static __init int tracer_init_debugfs(void) | |||
3198 | pr_warning("Could not create debugfs " | 3215 | pr_warning("Could not create debugfs " |
3199 | "'trace_pipe' entry\n"); | 3216 | "'trace_pipe' entry\n"); |
3200 | 3217 | ||
3201 | entry = debugfs_create_file("trace_entries", 0644, d_tracer, | 3218 | entry = debugfs_create_file("buffer_size_kb", 0644, d_tracer, |
3202 | &global_trace, &tracing_entries_fops); | 3219 | &global_trace, &tracing_entries_fops); |
3203 | if (!entry) | 3220 | if (!entry) |
3204 | pr_warning("Could not create debugfs " | 3221 | pr_warning("Could not create debugfs " |
3205 | "'trace_entries' entry\n"); | 3222 | "'buffer_size_kb' entry\n"); |
3206 | 3223 | ||
3207 | entry = debugfs_create_file("trace_marker", 0220, d_tracer, | 3224 | entry = debugfs_create_file("trace_marker", 0220, d_tracer, |
3208 | NULL, &tracing_mark_fops); | 3225 | NULL, &tracing_mark_fops); |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 9e015f5bea1d..790ea8c0e1f3 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -473,6 +473,7 @@ enum trace_iterator_flags { | |||
473 | #ifdef CONFIG_BRANCH_TRACER | 473 | #ifdef CONFIG_BRANCH_TRACER |
474 | TRACE_ITER_BRANCH = 0x1000, | 474 | TRACE_ITER_BRANCH = 0x1000, |
475 | #endif | 475 | #endif |
476 | TRACE_ITER_ANNOTATE = 0x2000, | ||
476 | }; | 477 | }; |
477 | 478 | ||
478 | /* | 479 | /* |