diff options
Diffstat (limited to 'kernel/trace')
| -rw-r--r-- | kernel/trace/Kconfig | 4 | ||||
| -rw-r--r-- | kernel/trace/blktrace.c | 10 | ||||
| -rw-r--r-- | kernel/trace/trace.c | 37 | ||||
| -rw-r--r-- | kernel/trace/trace_branch.c | 8 | ||||
| -rw-r--r-- | kernel/trace/trace_events.c | 12 | ||||
| -rw-r--r-- | kernel/trace/trace_events_filter.c | 14 | ||||
| -rw-r--r-- | kernel/trace/trace_events_stage_2.h | 4 | ||||
| -rw-r--r-- | kernel/trace/trace_power.c | 7 | ||||
| -rw-r--r-- | kernel/trace/trace_syscalls.c | 2 |
9 files changed, 65 insertions, 33 deletions
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 2246141bda4d..417d1985e299 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig | |||
| @@ -312,7 +312,7 @@ config KMEMTRACE | |||
| 312 | and profile kernel code. | 312 | and profile kernel code. |
| 313 | 313 | ||
| 314 | This requires an userspace application to use. See | 314 | This requires an userspace application to use. See |
| 315 | Documentation/vm/kmemtrace.txt for more information. | 315 | Documentation/trace/kmemtrace.txt for more information. |
| 316 | 316 | ||
| 317 | Saying Y will make the kernel somewhat larger and slower. However, | 317 | Saying Y will make the kernel somewhat larger and slower. However, |
| 318 | if you disable kmemtrace at run-time or boot-time, the performance | 318 | if you disable kmemtrace at run-time or boot-time, the performance |
| @@ -403,7 +403,7 @@ config MMIOTRACE | |||
| 403 | implementation and works via page faults. Tracing is disabled by | 403 | implementation and works via page faults. Tracing is disabled by |
| 404 | default and can be enabled at run-time. | 404 | default and can be enabled at run-time. |
| 405 | 405 | ||
| 406 | See Documentation/tracers/mmiotrace.txt. | 406 | See Documentation/trace/mmiotrace.txt. |
| 407 | If you are not helping to develop drivers, say N. | 407 | If you are not helping to develop drivers, say N. |
| 408 | 408 | ||
| 409 | config MMIOTRACE_TEST | 409 | config MMIOTRACE_TEST |
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index b32ff446c3fb..921ef5d1f0ba 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c | |||
| @@ -1377,12 +1377,12 @@ static int blk_trace_str2mask(const char *str) | |||
| 1377 | { | 1377 | { |
| 1378 | int i; | 1378 | int i; |
| 1379 | int mask = 0; | 1379 | int mask = 0; |
| 1380 | char *s, *token; | 1380 | char *buf, *s, *token; |
| 1381 | 1381 | ||
| 1382 | s = kstrdup(str, GFP_KERNEL); | 1382 | buf = kstrdup(str, GFP_KERNEL); |
| 1383 | if (s == NULL) | 1383 | if (buf == NULL) |
| 1384 | return -ENOMEM; | 1384 | return -ENOMEM; |
| 1385 | s = strstrip(s); | 1385 | s = strstrip(buf); |
| 1386 | 1386 | ||
| 1387 | while (1) { | 1387 | while (1) { |
| 1388 | token = strsep(&s, ","); | 1388 | token = strsep(&s, ","); |
| @@ -1403,7 +1403,7 @@ static int blk_trace_str2mask(const char *str) | |||
| 1403 | break; | 1403 | break; |
| 1404 | } | 1404 | } |
| 1405 | } | 1405 | } |
| 1406 | kfree(s); | 1406 | kfree(buf); |
| 1407 | 1407 | ||
| 1408 | return mask; | 1408 | return mask; |
| 1409 | } | 1409 | } |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 9d28476a9851..a884c09006c4 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -3277,19 +3277,13 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp) | |||
| 3277 | 3277 | ||
| 3278 | info->tr = &global_trace; | 3278 | info->tr = &global_trace; |
| 3279 | info->cpu = cpu; | 3279 | info->cpu = cpu; |
| 3280 | info->spare = ring_buffer_alloc_read_page(info->tr->buffer); | 3280 | info->spare = NULL; |
| 3281 | /* Force reading ring buffer for first read */ | 3281 | /* Force reading ring buffer for first read */ |
| 3282 | info->read = (unsigned int)-1; | 3282 | info->read = (unsigned int)-1; |
| 3283 | if (!info->spare) | ||
| 3284 | goto out; | ||
| 3285 | 3283 | ||
| 3286 | filp->private_data = info; | 3284 | filp->private_data = info; |
| 3287 | 3285 | ||
| 3288 | return 0; | 3286 | return nonseekable_open(inode, filp); |
| 3289 | |||
| 3290 | out: | ||
| 3291 | kfree(info); | ||
| 3292 | return -ENOMEM; | ||
| 3293 | } | 3287 | } |
| 3294 | 3288 | ||
| 3295 | static ssize_t | 3289 | static ssize_t |
| @@ -3304,6 +3298,11 @@ tracing_buffers_read(struct file *filp, char __user *ubuf, | |||
| 3304 | if (!count) | 3298 | if (!count) |
| 3305 | return 0; | 3299 | return 0; |
| 3306 | 3300 | ||
| 3301 | if (!info->spare) | ||
| 3302 | info->spare = ring_buffer_alloc_read_page(info->tr->buffer); | ||
| 3303 | if (!info->spare) | ||
| 3304 | return -ENOMEM; | ||
| 3305 | |||
| 3307 | /* Do we have previous read data to read? */ | 3306 | /* Do we have previous read data to read? */ |
| 3308 | if (info->read < PAGE_SIZE) | 3307 | if (info->read < PAGE_SIZE) |
| 3309 | goto read; | 3308 | goto read; |
| @@ -3342,7 +3341,8 @@ static int tracing_buffers_release(struct inode *inode, struct file *file) | |||
| 3342 | { | 3341 | { |
| 3343 | struct ftrace_buffer_info *info = file->private_data; | 3342 | struct ftrace_buffer_info *info = file->private_data; |
| 3344 | 3343 | ||
| 3345 | ring_buffer_free_read_page(info->tr->buffer, info->spare); | 3344 | if (info->spare) |
| 3345 | ring_buffer_free_read_page(info->tr->buffer, info->spare); | ||
| 3346 | kfree(info); | 3346 | kfree(info); |
| 3347 | 3347 | ||
| 3348 | return 0; | 3348 | return 0; |
| @@ -3428,14 +3428,19 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
| 3428 | int size, i; | 3428 | int size, i; |
| 3429 | size_t ret; | 3429 | size_t ret; |
| 3430 | 3430 | ||
| 3431 | /* | 3431 | if (*ppos & (PAGE_SIZE - 1)) { |
| 3432 | * We can't seek on a buffer input | 3432 | WARN_ONCE(1, "Ftrace: previous read must page-align\n"); |
| 3433 | */ | 3433 | return -EINVAL; |
| 3434 | if (unlikely(*ppos)) | 3434 | } |
| 3435 | return -ESPIPE; | ||
| 3436 | 3435 | ||
| 3436 | if (len & (PAGE_SIZE - 1)) { | ||
| 3437 | WARN_ONCE(1, "Ftrace: splice_read should page-align\n"); | ||
| 3438 | if (len < PAGE_SIZE) | ||
| 3439 | return -EINVAL; | ||
| 3440 | len &= PAGE_MASK; | ||
| 3441 | } | ||
| 3437 | 3442 | ||
| 3438 | for (i = 0; i < PIPE_BUFFERS && len; i++, len -= size) { | 3443 | for (i = 0; i < PIPE_BUFFERS && len; i++, len -= PAGE_SIZE) { |
| 3439 | struct page *page; | 3444 | struct page *page; |
| 3440 | int r; | 3445 | int r; |
| 3441 | 3446 | ||
| @@ -3443,6 +3448,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
| 3443 | if (!ref) | 3448 | if (!ref) |
| 3444 | break; | 3449 | break; |
| 3445 | 3450 | ||
| 3451 | ref->ref = 1; | ||
| 3446 | ref->buffer = info->tr->buffer; | 3452 | ref->buffer = info->tr->buffer; |
| 3447 | ref->page = ring_buffer_alloc_read_page(ref->buffer); | 3453 | ref->page = ring_buffer_alloc_read_page(ref->buffer); |
| 3448 | if (!ref->page) { | 3454 | if (!ref->page) { |
| @@ -3474,6 +3480,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
| 3474 | spd.partial[i].offset = 0; | 3480 | spd.partial[i].offset = 0; |
| 3475 | spd.partial[i].private = (unsigned long)ref; | 3481 | spd.partial[i].private = (unsigned long)ref; |
| 3476 | spd.nr_pages++; | 3482 | spd.nr_pages++; |
| 3483 | *ppos += PAGE_SIZE; | ||
| 3477 | } | 3484 | } |
| 3478 | 3485 | ||
| 3479 | spd.nr_pages = i; | 3486 | spd.nr_pages = i; |
diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c index ad8c22efff41..8333715e4066 100644 --- a/kernel/trace/trace_branch.c +++ b/kernel/trace/trace_branch.c | |||
| @@ -155,6 +155,13 @@ static enum print_line_t trace_branch_print(struct trace_iterator *iter, | |||
| 155 | return TRACE_TYPE_HANDLED; | 155 | return TRACE_TYPE_HANDLED; |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | static void branch_print_header(struct seq_file *s) | ||
| 159 | { | ||
| 160 | seq_puts(s, "# TASK-PID CPU# TIMESTAMP CORRECT" | ||
| 161 | " FUNC:FILE:LINE\n"); | ||
| 162 | seq_puts(s, "# | | | | | " | ||
| 163 | " |\n"); | ||
| 164 | } | ||
| 158 | 165 | ||
| 159 | static struct trace_event trace_branch_event = { | 166 | static struct trace_event trace_branch_event = { |
| 160 | .type = TRACE_BRANCH, | 167 | .type = TRACE_BRANCH, |
| @@ -169,6 +176,7 @@ static struct tracer branch_trace __read_mostly = | |||
| 169 | #ifdef CONFIG_FTRACE_SELFTEST | 176 | #ifdef CONFIG_FTRACE_SELFTEST |
| 170 | .selftest = trace_selftest_startup_branch, | 177 | .selftest = trace_selftest_startup_branch, |
| 171 | #endif /* CONFIG_FTRACE_SELFTEST */ | 178 | #endif /* CONFIG_FTRACE_SELFTEST */ |
| 179 | .print_header = branch_print_header, | ||
| 172 | }; | 180 | }; |
| 173 | 181 | ||
| 174 | __init static int init_branch_tracer(void) | 182 | __init static int init_branch_tracer(void) |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 64ec4d278ffb..576f4fa2af0d 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
| @@ -503,6 +503,7 @@ event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt, | |||
| 503 | 503 | ||
| 504 | if (copy_from_user(&buf, ubuf, cnt)) | 504 | if (copy_from_user(&buf, ubuf, cnt)) |
| 505 | return -EFAULT; | 505 | return -EFAULT; |
| 506 | buf[cnt] = '\0'; | ||
| 506 | 507 | ||
| 507 | pred = kzalloc(sizeof(*pred), GFP_KERNEL); | 508 | pred = kzalloc(sizeof(*pred), GFP_KERNEL); |
| 508 | if (!pred) | 509 | if (!pred) |
| @@ -520,9 +521,10 @@ event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt, | |||
| 520 | return cnt; | 521 | return cnt; |
| 521 | } | 522 | } |
| 522 | 523 | ||
| 523 | if (filter_add_pred(call, pred)) { | 524 | err = filter_add_pred(call, pred); |
| 525 | if (err < 0) { | ||
| 524 | filter_free_pred(pred); | 526 | filter_free_pred(pred); |
| 525 | return -EINVAL; | 527 | return err; |
| 526 | } | 528 | } |
| 527 | 529 | ||
| 528 | *ppos += cnt; | 530 | *ppos += cnt; |
| @@ -569,6 +571,7 @@ subsystem_filter_write(struct file *filp, const char __user *ubuf, size_t cnt, | |||
| 569 | 571 | ||
| 570 | if (copy_from_user(&buf, ubuf, cnt)) | 572 | if (copy_from_user(&buf, ubuf, cnt)) |
| 571 | return -EFAULT; | 573 | return -EFAULT; |
| 574 | buf[cnt] = '\0'; | ||
| 572 | 575 | ||
| 573 | pred = kzalloc(sizeof(*pred), GFP_KERNEL); | 576 | pred = kzalloc(sizeof(*pred), GFP_KERNEL); |
| 574 | if (!pred) | 577 | if (!pred) |
| @@ -586,10 +589,11 @@ subsystem_filter_write(struct file *filp, const char __user *ubuf, size_t cnt, | |||
| 586 | return cnt; | 589 | return cnt; |
| 587 | } | 590 | } |
| 588 | 591 | ||
| 589 | if (filter_add_subsystem_pred(system, pred)) { | 592 | err = filter_add_subsystem_pred(system, pred); |
| 593 | if (err < 0) { | ||
| 590 | filter_free_subsystem_preds(system); | 594 | filter_free_subsystem_preds(system); |
| 591 | filter_free_pred(pred); | 595 | filter_free_pred(pred); |
| 592 | return -EINVAL; | 596 | return err; |
| 593 | } | 597 | } |
| 594 | 598 | ||
| 595 | *ppos += cnt; | 599 | *ppos += cnt; |
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 026be412f356..e03cbf1e38f3 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c | |||
| @@ -215,7 +215,7 @@ static int __filter_add_pred(struct ftrace_event_call *call, | |||
| 215 | } | 215 | } |
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | return -ENOMEM; | 218 | return -ENOSPC; |
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | static int is_string_field(const char *type) | 221 | static int is_string_field(const char *type) |
| @@ -319,7 +319,7 @@ int filter_add_subsystem_pred(struct event_subsystem *system, | |||
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | if (i == MAX_FILTER_PRED) | 321 | if (i == MAX_FILTER_PRED) |
| 322 | return -EINVAL; | 322 | return -ENOSPC; |
| 323 | 323 | ||
| 324 | events_for_each(call) { | 324 | events_for_each(call) { |
| 325 | int err; | 325 | int err; |
| @@ -410,16 +410,22 @@ int filter_parse(char **pbuf, struct filter_pred *pred) | |||
| 410 | } | 410 | } |
| 411 | } | 411 | } |
| 412 | 412 | ||
| 413 | if (!val_str) { | ||
| 414 | pred->field_name = NULL; | ||
| 415 | return -EINVAL; | ||
| 416 | } | ||
| 417 | |||
| 413 | pred->field_name = kstrdup(pred->field_name, GFP_KERNEL); | 418 | pred->field_name = kstrdup(pred->field_name, GFP_KERNEL); |
| 414 | if (!pred->field_name) | 419 | if (!pred->field_name) |
| 415 | return -ENOMEM; | 420 | return -ENOMEM; |
| 416 | 421 | ||
| 417 | pred->val = simple_strtoull(val_str, &tmp, 10); | 422 | pred->val = simple_strtoull(val_str, &tmp, 0); |
| 418 | if (tmp == val_str) { | 423 | if (tmp == val_str) { |
| 419 | pred->str_val = kstrdup(val_str, GFP_KERNEL); | 424 | pred->str_val = kstrdup(val_str, GFP_KERNEL); |
| 420 | if (!pred->str_val) | 425 | if (!pred->str_val) |
| 421 | return -ENOMEM; | 426 | return -ENOMEM; |
| 422 | } | 427 | } else if (*tmp != '\0') |
| 428 | return -EINVAL; | ||
| 423 | 429 | ||
| 424 | return 0; | 430 | return 0; |
| 425 | } | 431 | } |
diff --git a/kernel/trace/trace_events_stage_2.h b/kernel/trace/trace_events_stage_2.h index 30743f7d4110..d363c6672c6c 100644 --- a/kernel/trace/trace_events_stage_2.h +++ b/kernel/trace/trace_events_stage_2.h | |||
| @@ -105,10 +105,10 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ | |||
| 105 | return 0; | 105 | return 0; |
| 106 | 106 | ||
| 107 | #undef __entry | 107 | #undef __entry |
| 108 | #define __entry "REC" | 108 | #define __entry REC |
| 109 | 109 | ||
| 110 | #undef TP_printk | 110 | #undef TP_printk |
| 111 | #define TP_printk(fmt, args...) "%s, %s\n", #fmt, #args | 111 | #define TP_printk(fmt, args...) "%s, %s\n", #fmt, __stringify(args) |
| 112 | 112 | ||
| 113 | #undef TP_fast_assign | 113 | #undef TP_fast_assign |
| 114 | #define TP_fast_assign(args...) args | 114 | #define TP_fast_assign(args...) args |
diff --git a/kernel/trace/trace_power.c b/kernel/trace/trace_power.c index bae791ebcc51..118439709fb7 100644 --- a/kernel/trace/trace_power.c +++ b/kernel/trace/trace_power.c | |||
| @@ -186,6 +186,12 @@ static enum print_line_t power_print_line(struct trace_iterator *iter) | |||
| 186 | return TRACE_TYPE_UNHANDLED; | 186 | return TRACE_TYPE_UNHANDLED; |
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | static void power_print_header(struct seq_file *s) | ||
| 190 | { | ||
| 191 | seq_puts(s, "# TIMESTAMP STATE EVENT\n"); | ||
| 192 | seq_puts(s, "# | | |\n"); | ||
| 193 | } | ||
| 194 | |||
| 189 | static struct tracer power_tracer __read_mostly = | 195 | static struct tracer power_tracer __read_mostly = |
| 190 | { | 196 | { |
| 191 | .name = "power", | 197 | .name = "power", |
| @@ -194,6 +200,7 @@ static struct tracer power_tracer __read_mostly = | |||
| 194 | .stop = stop_power_trace, | 200 | .stop = stop_power_trace, |
| 195 | .reset = power_trace_reset, | 201 | .reset = power_trace_reset, |
| 196 | .print_line = power_print_line, | 202 | .print_line = power_print_line, |
| 203 | .print_header = power_print_header, | ||
| 197 | }; | 204 | }; |
| 198 | 205 | ||
| 199 | static int init_power_trace(void) | 206 | static int init_power_trace(void) |
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index a2a3af29c943..5e579645ac86 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #include <trace/syscall.h> | ||
| 1 | #include <linux/kernel.h> | 2 | #include <linux/kernel.h> |
| 2 | #include <linux/ftrace.h> | ||
| 3 | #include <asm/syscall.h> | 3 | #include <asm/syscall.h> |
| 4 | 4 | ||
| 5 | #include "trace_output.h" | 5 | #include "trace_output.h" |
