diff options
Diffstat (limited to 'kernel/trace')
| -rw-r--r-- | kernel/trace/Kconfig | 2 | ||||
| -rw-r--r-- | kernel/trace/blktrace.c | 39 | ||||
| -rw-r--r-- | kernel/trace/ftrace.c | 58 | ||||
| -rw-r--r-- | kernel/trace/kmemtrace.c | 2 | ||||
| -rw-r--r-- | kernel/trace/trace.c | 13 | ||||
| -rw-r--r-- | kernel/trace/trace_branch.c | 8 | ||||
| -rw-r--r-- | kernel/trace/trace_event_profile.c | 15 | ||||
| -rw-r--r-- | kernel/trace/trace_events.c | 7 | ||||
| -rw-r--r-- | kernel/trace/trace_hw_branches.c | 10 | ||||
| -rw-r--r-- | kernel/trace/trace_output.c | 18 | ||||
| -rw-r--r-- | kernel/trace/trace_stack.c | 4 | ||||
| -rw-r--r-- | kernel/trace/trace_syscalls.c | 10 |
12 files changed, 115 insertions, 71 deletions
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index e7163460440..b416512ad17 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig | |||
| @@ -83,7 +83,7 @@ config RING_BUFFER_ALLOW_SWAP | |||
| 83 | # This allows those options to appear when no other tracer is selected. But the | 83 | # This allows those options to appear when no other tracer is selected. But the |
| 84 | # options do not appear when something else selects it. We need the two options | 84 | # options do not appear when something else selects it. We need the two options |
| 85 | # GENERIC_TRACER and TRACING to avoid circular dependencies to accomplish the | 85 | # GENERIC_TRACER and TRACING to avoid circular dependencies to accomplish the |
| 86 | # hidding of the automatic options options. | 86 | # hidding of the automatic options. |
| 87 | 87 | ||
| 88 | config TRACING | 88 | config TRACING |
| 89 | bool | 89 | bool |
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 3eb159c277c..d9d6206e0b1 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c | |||
| @@ -856,6 +856,37 @@ static void blk_add_trace_remap(struct request_queue *q, struct bio *bio, | |||
| 856 | } | 856 | } |
| 857 | 857 | ||
| 858 | /** | 858 | /** |
| 859 | * blk_add_trace_rq_remap - Add a trace for a request-remap operation | ||
| 860 | * @q: queue the io is for | ||
| 861 | * @rq: the source request | ||
| 862 | * @dev: target device | ||
| 863 | * @from: source sector | ||
| 864 | * | ||
| 865 | * Description: | ||
| 866 | * Device mapper remaps request to other devices. | ||
| 867 | * Add a trace for that action. | ||
| 868 | * | ||
| 869 | **/ | ||
| 870 | static void blk_add_trace_rq_remap(struct request_queue *q, | ||
| 871 | struct request *rq, dev_t dev, | ||
| 872 | sector_t from) | ||
| 873 | { | ||
| 874 | struct blk_trace *bt = q->blk_trace; | ||
| 875 | struct blk_io_trace_remap r; | ||
| 876 | |||
| 877 | if (likely(!bt)) | ||
| 878 | return; | ||
| 879 | |||
| 880 | r.device_from = cpu_to_be32(dev); | ||
| 881 | r.device_to = cpu_to_be32(disk_devt(rq->rq_disk)); | ||
| 882 | r.sector_from = cpu_to_be64(from); | ||
| 883 | |||
| 884 | __blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq), | ||
| 885 | rq_data_dir(rq), BLK_TA_REMAP, !!rq->errors, | ||
| 886 | sizeof(r), &r); | ||
| 887 | } | ||
| 888 | |||
| 889 | /** | ||
| 859 | * blk_add_driver_data - Add binary message with driver-specific data | 890 | * blk_add_driver_data - Add binary message with driver-specific data |
| 860 | * @q: queue the io is for | 891 | * @q: queue the io is for |
| 861 | * @rq: io request | 892 | * @rq: io request |
| @@ -922,10 +953,13 @@ static void blk_register_tracepoints(void) | |||
| 922 | WARN_ON(ret); | 953 | WARN_ON(ret); |
| 923 | ret = register_trace_block_remap(blk_add_trace_remap); | 954 | ret = register_trace_block_remap(blk_add_trace_remap); |
| 924 | WARN_ON(ret); | 955 | WARN_ON(ret); |
| 956 | ret = register_trace_block_rq_remap(blk_add_trace_rq_remap); | ||
| 957 | WARN_ON(ret); | ||
| 925 | } | 958 | } |
| 926 | 959 | ||
| 927 | static void blk_unregister_tracepoints(void) | 960 | static void blk_unregister_tracepoints(void) |
| 928 | { | 961 | { |
| 962 | unregister_trace_block_rq_remap(blk_add_trace_rq_remap); | ||
| 929 | unregister_trace_block_remap(blk_add_trace_remap); | 963 | unregister_trace_block_remap(blk_add_trace_remap); |
| 930 | unregister_trace_block_split(blk_add_trace_split); | 964 | unregister_trace_block_split(blk_add_trace_split); |
| 931 | unregister_trace_block_unplug_io(blk_add_trace_unplug_io); | 965 | unregister_trace_block_unplug_io(blk_add_trace_unplug_io); |
| @@ -1657,6 +1691,11 @@ int blk_trace_init_sysfs(struct device *dev) | |||
| 1657 | return sysfs_create_group(&dev->kobj, &blk_trace_attr_group); | 1691 | return sysfs_create_group(&dev->kobj, &blk_trace_attr_group); |
| 1658 | } | 1692 | } |
| 1659 | 1693 | ||
| 1694 | void blk_trace_remove_sysfs(struct device *dev) | ||
| 1695 | { | ||
| 1696 | sysfs_remove_group(&dev->kobj, &blk_trace_attr_group); | ||
| 1697 | } | ||
| 1698 | |||
| 1660 | #endif /* CONFIG_BLK_DEV_IO_TRACE */ | 1699 | #endif /* CONFIG_BLK_DEV_IO_TRACE */ |
| 1661 | 1700 | ||
| 1662 | #ifdef CONFIG_EVENT_TRACING | 1701 | #ifdef CONFIG_EVENT_TRACING |
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index c71e91bf737..37ba67e3326 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
| @@ -225,7 +225,11 @@ static void ftrace_update_pid_func(void) | |||
| 225 | if (ftrace_trace_function == ftrace_stub) | 225 | if (ftrace_trace_function == ftrace_stub) |
| 226 | return; | 226 | return; |
| 227 | 227 | ||
| 228 | #ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST | ||
| 228 | func = ftrace_trace_function; | 229 | func = ftrace_trace_function; |
| 230 | #else | ||
| 231 | func = __ftrace_trace_function; | ||
| 232 | #endif | ||
| 229 | 233 | ||
| 230 | if (ftrace_pid_trace) { | 234 | if (ftrace_pid_trace) { |
| 231 | set_ftrace_pid_function(func); | 235 | set_ftrace_pid_function(func); |
| @@ -1074,14 +1078,9 @@ static void ftrace_replace_code(int enable) | |||
| 1074 | failed = __ftrace_replace_code(rec, enable); | 1078 | failed = __ftrace_replace_code(rec, enable); |
| 1075 | if (failed) { | 1079 | if (failed) { |
| 1076 | rec->flags |= FTRACE_FL_FAILED; | 1080 | rec->flags |= FTRACE_FL_FAILED; |
| 1077 | if ((system_state == SYSTEM_BOOTING) || | 1081 | ftrace_bug(failed, rec->ip); |
| 1078 | !core_kernel_text(rec->ip)) { | 1082 | /* Stop processing */ |
| 1079 | ftrace_free_rec(rec); | 1083 | return; |
| 1080 | } else { | ||
| 1081 | ftrace_bug(failed, rec->ip); | ||
| 1082 | /* Stop processing */ | ||
| 1083 | return; | ||
| 1084 | } | ||
| 1085 | } | 1084 | } |
| 1086 | } while_for_each_ftrace_rec(); | 1085 | } while_for_each_ftrace_rec(); |
| 1087 | } | 1086 | } |
| @@ -1520,7 +1519,7 @@ static int t_show(struct seq_file *m, void *v) | |||
| 1520 | return 0; | 1519 | return 0; |
| 1521 | } | 1520 | } |
| 1522 | 1521 | ||
| 1523 | static struct seq_operations show_ftrace_seq_ops = { | 1522 | static const struct seq_operations show_ftrace_seq_ops = { |
| 1524 | .start = t_start, | 1523 | .start = t_start, |
| 1525 | .next = t_next, | 1524 | .next = t_next, |
| 1526 | .stop = t_stop, | 1525 | .stop = t_stop, |
| @@ -1621,8 +1620,10 @@ ftrace_regex_open(struct inode *inode, struct file *file, int enable) | |||
| 1621 | if (!ret) { | 1620 | if (!ret) { |
| 1622 | struct seq_file *m = file->private_data; | 1621 | struct seq_file *m = file->private_data; |
| 1623 | m->private = iter; | 1622 | m->private = iter; |
| 1624 | } else | 1623 | } else { |
| 1624 | trace_parser_put(&iter->parser); | ||
| 1625 | kfree(iter); | 1625 | kfree(iter); |
| 1626 | } | ||
| 1626 | } else | 1627 | } else |
| 1627 | file->private_data = iter; | 1628 | file->private_data = iter; |
| 1628 | mutex_unlock(&ftrace_regex_lock); | 1629 | mutex_unlock(&ftrace_regex_lock); |
| @@ -2202,7 +2203,7 @@ ftrace_regex_write(struct file *file, const char __user *ubuf, | |||
| 2202 | struct trace_parser *parser; | 2203 | struct trace_parser *parser; |
| 2203 | ssize_t ret, read; | 2204 | ssize_t ret, read; |
| 2204 | 2205 | ||
| 2205 | if (!cnt || cnt < 0) | 2206 | if (!cnt) |
| 2206 | return 0; | 2207 | return 0; |
| 2207 | 2208 | ||
| 2208 | mutex_lock(&ftrace_regex_lock); | 2209 | mutex_lock(&ftrace_regex_lock); |
| @@ -2216,7 +2217,7 @@ ftrace_regex_write(struct file *file, const char __user *ubuf, | |||
| 2216 | parser = &iter->parser; | 2217 | parser = &iter->parser; |
| 2217 | read = trace_get_user(parser, ubuf, cnt, ppos); | 2218 | read = trace_get_user(parser, ubuf, cnt, ppos); |
| 2218 | 2219 | ||
| 2219 | if (trace_parser_loaded(parser) && | 2220 | if (read >= 0 && trace_parser_loaded(parser) && |
| 2220 | !trace_parser_cont(parser)) { | 2221 | !trace_parser_cont(parser)) { |
| 2221 | ret = ftrace_process_regex(parser->buffer, | 2222 | ret = ftrace_process_regex(parser->buffer, |
| 2222 | parser->idx, enable); | 2223 | parser->idx, enable); |
| @@ -2459,7 +2460,7 @@ static int g_show(struct seq_file *m, void *v) | |||
| 2459 | return 0; | 2460 | return 0; |
| 2460 | } | 2461 | } |
| 2461 | 2462 | ||
| 2462 | static struct seq_operations ftrace_graph_seq_ops = { | 2463 | static const struct seq_operations ftrace_graph_seq_ops = { |
| 2463 | .start = g_start, | 2464 | .start = g_start, |
| 2464 | .next = g_next, | 2465 | .next = g_next, |
| 2465 | .stop = g_stop, | 2466 | .stop = g_stop, |
| @@ -2552,8 +2553,7 @@ ftrace_graph_write(struct file *file, const char __user *ubuf, | |||
| 2552 | size_t cnt, loff_t *ppos) | 2553 | size_t cnt, loff_t *ppos) |
| 2553 | { | 2554 | { |
| 2554 | struct trace_parser parser; | 2555 | struct trace_parser parser; |
| 2555 | size_t read = 0; | 2556 | ssize_t read, ret; |
| 2556 | ssize_t ret; | ||
| 2557 | 2557 | ||
| 2558 | if (!cnt || cnt < 0) | 2558 | if (!cnt || cnt < 0) |
| 2559 | return 0; | 2559 | return 0; |
| @@ -2562,29 +2562,31 @@ ftrace_graph_write(struct file *file, const char __user *ubuf, | |||
| 2562 | 2562 | ||
| 2563 | if (ftrace_graph_count >= FTRACE_GRAPH_MAX_FUNCS) { | 2563 | if (ftrace_graph_count >= FTRACE_GRAPH_MAX_FUNCS) { |
| 2564 | ret = -EBUSY; | 2564 | ret = -EBUSY; |
| 2565 | goto out; | 2565 | goto out_unlock; |
| 2566 | } | 2566 | } |
| 2567 | 2567 | ||
| 2568 | if (trace_parser_get_init(&parser, FTRACE_BUFF_MAX)) { | 2568 | if (trace_parser_get_init(&parser, FTRACE_BUFF_MAX)) { |
| 2569 | ret = -ENOMEM; | 2569 | ret = -ENOMEM; |
| 2570 | goto out; | 2570 | goto out_unlock; |
| 2571 | } | 2571 | } |
| 2572 | 2572 | ||
| 2573 | read = trace_get_user(&parser, ubuf, cnt, ppos); | 2573 | read = trace_get_user(&parser, ubuf, cnt, ppos); |
| 2574 | 2574 | ||
| 2575 | if (trace_parser_loaded((&parser))) { | 2575 | if (read >= 0 && trace_parser_loaded((&parser))) { |
| 2576 | parser.buffer[parser.idx] = 0; | 2576 | parser.buffer[parser.idx] = 0; |
| 2577 | 2577 | ||
| 2578 | /* we allow only one expression at a time */ | 2578 | /* we allow only one expression at a time */ |
| 2579 | ret = ftrace_set_func(ftrace_graph_funcs, &ftrace_graph_count, | 2579 | ret = ftrace_set_func(ftrace_graph_funcs, &ftrace_graph_count, |
| 2580 | parser.buffer); | 2580 | parser.buffer); |
| 2581 | if (ret) | 2581 | if (ret) |
| 2582 | goto out; | 2582 | goto out_free; |
| 2583 | } | 2583 | } |
| 2584 | 2584 | ||
| 2585 | ret = read; | 2585 | ret = read; |
| 2586 | out: | 2586 | |
| 2587 | out_free: | ||
| 2587 | trace_parser_put(&parser); | 2588 | trace_parser_put(&parser); |
| 2589 | out_unlock: | ||
| 2588 | mutex_unlock(&graph_lock); | 2590 | mutex_unlock(&graph_lock); |
| 2589 | 2591 | ||
| 2590 | return ret; | 2592 | return ret; |
| @@ -2655,19 +2657,17 @@ static int ftrace_convert_nops(struct module *mod, | |||
| 2655 | } | 2657 | } |
| 2656 | 2658 | ||
| 2657 | #ifdef CONFIG_MODULES | 2659 | #ifdef CONFIG_MODULES |
| 2658 | void ftrace_release(void *start, void *end) | 2660 | void ftrace_release_mod(struct module *mod) |
| 2659 | { | 2661 | { |
| 2660 | struct dyn_ftrace *rec; | 2662 | struct dyn_ftrace *rec; |
| 2661 | struct ftrace_page *pg; | 2663 | struct ftrace_page *pg; |
| 2662 | unsigned long s = (unsigned long)start; | ||
| 2663 | unsigned long e = (unsigned long)end; | ||
| 2664 | 2664 | ||
| 2665 | if (ftrace_disabled || !start || start == end) | 2665 | if (ftrace_disabled) |
| 2666 | return; | 2666 | return; |
| 2667 | 2667 | ||
| 2668 | mutex_lock(&ftrace_lock); | 2668 | mutex_lock(&ftrace_lock); |
| 2669 | do_for_each_ftrace_rec(pg, rec) { | 2669 | do_for_each_ftrace_rec(pg, rec) { |
| 2670 | if ((rec->ip >= s) && (rec->ip < e)) { | 2670 | if (within_module_core(rec->ip, mod)) { |
| 2671 | /* | 2671 | /* |
| 2672 | * rec->ip is changed in ftrace_free_rec() | 2672 | * rec->ip is changed in ftrace_free_rec() |
| 2673 | * It should not between s and e if record was freed. | 2673 | * It should not between s and e if record was freed. |
| @@ -2699,9 +2699,7 @@ static int ftrace_module_notify(struct notifier_block *self, | |||
| 2699 | mod->num_ftrace_callsites); | 2699 | mod->num_ftrace_callsites); |
| 2700 | break; | 2700 | break; |
| 2701 | case MODULE_STATE_GOING: | 2701 | case MODULE_STATE_GOING: |
| 2702 | ftrace_release(mod->ftrace_callsites, | 2702 | ftrace_release_mod(mod); |
| 2703 | mod->ftrace_callsites + | ||
| 2704 | mod->num_ftrace_callsites); | ||
| 2705 | break; | 2703 | break; |
| 2706 | } | 2704 | } |
| 2707 | 2705 | ||
| @@ -3015,7 +3013,7 @@ int unregister_ftrace_function(struct ftrace_ops *ops) | |||
| 3015 | 3013 | ||
| 3016 | int | 3014 | int |
| 3017 | ftrace_enable_sysctl(struct ctl_table *table, int write, | 3015 | ftrace_enable_sysctl(struct ctl_table *table, int write, |
| 3018 | struct file *file, void __user *buffer, size_t *lenp, | 3016 | void __user *buffer, size_t *lenp, |
| 3019 | loff_t *ppos) | 3017 | loff_t *ppos) |
| 3020 | { | 3018 | { |
| 3021 | int ret; | 3019 | int ret; |
| @@ -3025,7 +3023,7 @@ ftrace_enable_sysctl(struct ctl_table *table, int write, | |||
| 3025 | 3023 | ||
| 3026 | mutex_lock(&ftrace_lock); | 3024 | mutex_lock(&ftrace_lock); |
| 3027 | 3025 | ||
| 3028 | ret = proc_dointvec(table, write, file, buffer, lenp, ppos); | 3026 | ret = proc_dointvec(table, write, buffer, lenp, ppos); |
| 3029 | 3027 | ||
| 3030 | if (ret || !write || (last_ftrace_enabled == !!ftrace_enabled)) | 3028 | if (ret || !write || (last_ftrace_enabled == !!ftrace_enabled)) |
| 3031 | goto out; | 3029 | goto out; |
diff --git a/kernel/trace/kmemtrace.c b/kernel/trace/kmemtrace.c index 81b1645c854..a91da69f153 100644 --- a/kernel/trace/kmemtrace.c +++ b/kernel/trace/kmemtrace.c | |||
| @@ -501,7 +501,7 @@ static int __init init_kmem_tracer(void) | |||
| 501 | return 1; | 501 | return 1; |
| 502 | } | 502 | } |
| 503 | 503 | ||
| 504 | if (!register_tracer(&kmem_tracer)) { | 504 | if (register_tracer(&kmem_tracer) != 0) { |
| 505 | pr_warning("Warning: could not register the kmem tracer\n"); | 505 | pr_warning("Warning: could not register the kmem tracer\n"); |
| 506 | return 1; | 506 | return 1; |
| 507 | } | 507 | } |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index a35925d222b..45068269ebb 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -415,7 +415,7 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, | |||
| 415 | 415 | ||
| 416 | /* read the non-space input */ | 416 | /* read the non-space input */ |
| 417 | while (cnt && !isspace(ch)) { | 417 | while (cnt && !isspace(ch)) { |
| 418 | if (parser->idx < parser->size) | 418 | if (parser->idx < parser->size - 1) |
| 419 | parser->buffer[parser->idx++] = ch; | 419 | parser->buffer[parser->idx++] = ch; |
| 420 | else { | 420 | else { |
| 421 | ret = -EINVAL; | 421 | ret = -EINVAL; |
| @@ -1949,7 +1949,7 @@ static int s_show(struct seq_file *m, void *v) | |||
| 1949 | return 0; | 1949 | return 0; |
| 1950 | } | 1950 | } |
| 1951 | 1951 | ||
| 1952 | static struct seq_operations tracer_seq_ops = { | 1952 | static const struct seq_operations tracer_seq_ops = { |
| 1953 | .start = s_start, | 1953 | .start = s_start, |
| 1954 | .next = s_next, | 1954 | .next = s_next, |
| 1955 | .stop = s_stop, | 1955 | .stop = s_stop, |
| @@ -1984,11 +1984,9 @@ __tracing_open(struct inode *inode, struct file *file) | |||
| 1984 | if (current_trace) | 1984 | if (current_trace) |
| 1985 | *iter->trace = *current_trace; | 1985 | *iter->trace = *current_trace; |
| 1986 | 1986 | ||
| 1987 | if (!alloc_cpumask_var(&iter->started, GFP_KERNEL)) | 1987 | if (!zalloc_cpumask_var(&iter->started, GFP_KERNEL)) |
| 1988 | goto fail; | 1988 | goto fail; |
| 1989 | 1989 | ||
| 1990 | cpumask_clear(iter->started); | ||
| 1991 | |||
| 1992 | if (current_trace && current_trace->print_max) | 1990 | if (current_trace && current_trace->print_max) |
| 1993 | iter->tr = &max_tr; | 1991 | iter->tr = &max_tr; |
| 1994 | else | 1992 | else |
| @@ -2163,7 +2161,7 @@ static int t_show(struct seq_file *m, void *v) | |||
| 2163 | return 0; | 2161 | return 0; |
| 2164 | } | 2162 | } |
| 2165 | 2163 | ||
| 2166 | static struct seq_operations show_traces_seq_ops = { | 2164 | static const struct seq_operations show_traces_seq_ops = { |
| 2167 | .start = t_start, | 2165 | .start = t_start, |
| 2168 | .next = t_next, | 2166 | .next = t_next, |
| 2169 | .stop = t_stop, | 2167 | .stop = t_stop, |
| @@ -4389,7 +4387,7 @@ __init static int tracer_alloc_buffers(void) | |||
| 4389 | if (!alloc_cpumask_var(&tracing_cpumask, GFP_KERNEL)) | 4387 | if (!alloc_cpumask_var(&tracing_cpumask, GFP_KERNEL)) |
| 4390 | goto out_free_buffer_mask; | 4388 | goto out_free_buffer_mask; |
| 4391 | 4389 | ||
| 4392 | if (!alloc_cpumask_var(&tracing_reader_cpumask, GFP_KERNEL)) | 4390 | if (!zalloc_cpumask_var(&tracing_reader_cpumask, GFP_KERNEL)) |
| 4393 | goto out_free_tracing_cpumask; | 4391 | goto out_free_tracing_cpumask; |
| 4394 | 4392 | ||
| 4395 | /* To save memory, keep the ring buffer size to its minimum */ | 4393 | /* To save memory, keep the ring buffer size to its minimum */ |
| @@ -4400,7 +4398,6 @@ __init static int tracer_alloc_buffers(void) | |||
| 4400 | 4398 | ||
| 4401 | cpumask_copy(tracing_buffer_mask, cpu_possible_mask); | 4399 | cpumask_copy(tracing_buffer_mask, cpu_possible_mask); |
| 4402 | cpumask_copy(tracing_cpumask, cpu_all_mask); | 4400 | cpumask_copy(tracing_cpumask, cpu_all_mask); |
| 4403 | cpumask_clear(tracing_reader_cpumask); | ||
| 4404 | 4401 | ||
| 4405 | /* TODO: make the number of buffers hot pluggable with CPUS */ | 4402 | /* TODO: make the number of buffers hot pluggable with CPUS */ |
| 4406 | global_trace.buffer = ring_buffer_alloc(ring_buf_size, | 4403 | global_trace.buffer = ring_buffer_alloc(ring_buf_size, |
diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c index 7a7a9fd249a..4a194f08f88 100644 --- a/kernel/trace/trace_branch.c +++ b/kernel/trace/trace_branch.c | |||
| @@ -34,6 +34,7 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect) | |||
| 34 | struct trace_array *tr = branch_tracer; | 34 | struct trace_array *tr = branch_tracer; |
| 35 | struct ring_buffer_event *event; | 35 | struct ring_buffer_event *event; |
| 36 | struct trace_branch *entry; | 36 | struct trace_branch *entry; |
| 37 | struct ring_buffer *buffer; | ||
| 37 | unsigned long flags; | 38 | unsigned long flags; |
| 38 | int cpu, pc; | 39 | int cpu, pc; |
| 39 | const char *p; | 40 | const char *p; |
| @@ -54,7 +55,8 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect) | |||
| 54 | goto out; | 55 | goto out; |
| 55 | 56 | ||
| 56 | pc = preempt_count(); | 57 | pc = preempt_count(); |
| 57 | event = trace_buffer_lock_reserve(tr, TRACE_BRANCH, | 58 | buffer = tr->buffer; |
| 59 | event = trace_buffer_lock_reserve(buffer, TRACE_BRANCH, | ||
| 58 | sizeof(*entry), flags, pc); | 60 | sizeof(*entry), flags, pc); |
| 59 | if (!event) | 61 | if (!event) |
| 60 | goto out; | 62 | goto out; |
| @@ -74,8 +76,8 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect) | |||
| 74 | entry->line = f->line; | 76 | entry->line = f->line; |
| 75 | entry->correct = val == expect; | 77 | entry->correct = val == expect; |
| 76 | 78 | ||
| 77 | if (!filter_check_discard(call, entry, tr->buffer, event)) | 79 | if (!filter_check_discard(call, entry, buffer, event)) |
| 78 | ring_buffer_unlock_commit(tr->buffer, event); | 80 | ring_buffer_unlock_commit(buffer, event); |
| 79 | 81 | ||
| 80 | out: | 82 | out: |
| 81 | atomic_dec(&tr->data[cpu]->disabled); | 83 | atomic_dec(&tr->data[cpu]->disabled); |
diff --git a/kernel/trace/trace_event_profile.c b/kernel/trace/trace_event_profile.c index dd44b876886..8d5c171cc99 100644 --- a/kernel/trace/trace_event_profile.c +++ b/kernel/trace/trace_event_profile.c | |||
| @@ -31,7 +31,7 @@ static int ftrace_profile_enable_event(struct ftrace_event_call *event) | |||
| 31 | if (atomic_inc_return(&event->profile_count)) | 31 | if (atomic_inc_return(&event->profile_count)) |
| 32 | return 0; | 32 | return 0; |
| 33 | 33 | ||
| 34 | if (!total_profile_count++) { | 34 | if (!total_profile_count) { |
| 35 | buf = (char *)alloc_percpu(profile_buf_t); | 35 | buf = (char *)alloc_percpu(profile_buf_t); |
| 36 | if (!buf) | 36 | if (!buf) |
| 37 | goto fail_buf; | 37 | goto fail_buf; |
| @@ -46,14 +46,19 @@ static int ftrace_profile_enable_event(struct ftrace_event_call *event) | |||
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | ret = event->profile_enable(); | 48 | ret = event->profile_enable(); |
| 49 | if (!ret) | 49 | if (!ret) { |
| 50 | total_profile_count++; | ||
| 50 | return 0; | 51 | return 0; |
| 52 | } | ||
| 51 | 53 | ||
| 52 | kfree(trace_profile_buf_nmi); | ||
| 53 | fail_buf_nmi: | 54 | fail_buf_nmi: |
| 54 | kfree(trace_profile_buf); | 55 | if (!total_profile_count) { |
| 56 | free_percpu(trace_profile_buf_nmi); | ||
| 57 | free_percpu(trace_profile_buf); | ||
| 58 | trace_profile_buf_nmi = NULL; | ||
| 59 | trace_profile_buf = NULL; | ||
| 60 | } | ||
| 55 | fail_buf: | 61 | fail_buf: |
| 56 | total_profile_count--; | ||
| 57 | atomic_dec(&event->profile_count); | 62 | atomic_dec(&event->profile_count); |
| 58 | 63 | ||
| 59 | return ret; | 64 | return ret; |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 6f03c8a1105..d128f65778e 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
| @@ -232,10 +232,9 @@ ftrace_event_write(struct file *file, const char __user *ubuf, | |||
| 232 | size_t cnt, loff_t *ppos) | 232 | size_t cnt, loff_t *ppos) |
| 233 | { | 233 | { |
| 234 | struct trace_parser parser; | 234 | struct trace_parser parser; |
| 235 | size_t read = 0; | 235 | ssize_t read, ret; |
| 236 | ssize_t ret; | ||
| 237 | 236 | ||
| 238 | if (!cnt || cnt < 0) | 237 | if (!cnt) |
| 239 | return 0; | 238 | return 0; |
| 240 | 239 | ||
| 241 | ret = tracing_update_buffers(); | 240 | ret = tracing_update_buffers(); |
| @@ -247,7 +246,7 @@ ftrace_event_write(struct file *file, const char __user *ubuf, | |||
| 247 | 246 | ||
| 248 | read = trace_get_user(&parser, ubuf, cnt, ppos); | 247 | read = trace_get_user(&parser, ubuf, cnt, ppos); |
| 249 | 248 | ||
| 250 | if (trace_parser_loaded((&parser))) { | 249 | if (read >= 0 && trace_parser_loaded((&parser))) { |
| 251 | int set = 1; | 250 | int set = 1; |
| 252 | 251 | ||
| 253 | if (*parser.buffer == '!') | 252 | if (*parser.buffer == '!') |
diff --git a/kernel/trace/trace_hw_branches.c b/kernel/trace/trace_hw_branches.c index ca7d7c4d0c2..69543a905cd 100644 --- a/kernel/trace/trace_hw_branches.c +++ b/kernel/trace/trace_hw_branches.c | |||
| @@ -155,7 +155,7 @@ static enum print_line_t bts_trace_print_line(struct trace_iterator *iter) | |||
| 155 | seq_print_ip_sym(seq, it->from, symflags) && | 155 | seq_print_ip_sym(seq, it->from, symflags) && |
| 156 | trace_seq_printf(seq, "\n")) | 156 | trace_seq_printf(seq, "\n")) |
| 157 | return TRACE_TYPE_HANDLED; | 157 | return TRACE_TYPE_HANDLED; |
| 158 | return TRACE_TYPE_PARTIAL_LINE;; | 158 | return TRACE_TYPE_PARTIAL_LINE; |
| 159 | } | 159 | } |
| 160 | return TRACE_TYPE_UNHANDLED; | 160 | return TRACE_TYPE_UNHANDLED; |
| 161 | } | 161 | } |
| @@ -165,6 +165,7 @@ void trace_hw_branch(u64 from, u64 to) | |||
| 165 | struct ftrace_event_call *call = &event_hw_branch; | 165 | struct ftrace_event_call *call = &event_hw_branch; |
| 166 | struct trace_array *tr = hw_branch_trace; | 166 | struct trace_array *tr = hw_branch_trace; |
| 167 | struct ring_buffer_event *event; | 167 | struct ring_buffer_event *event; |
| 168 | struct ring_buffer *buf; | ||
| 168 | struct hw_branch_entry *entry; | 169 | struct hw_branch_entry *entry; |
| 169 | unsigned long irq1; | 170 | unsigned long irq1; |
| 170 | int cpu; | 171 | int cpu; |
| @@ -180,7 +181,8 @@ void trace_hw_branch(u64 from, u64 to) | |||
| 180 | if (atomic_inc_return(&tr->data[cpu]->disabled) != 1) | 181 | if (atomic_inc_return(&tr->data[cpu]->disabled) != 1) |
| 181 | goto out; | 182 | goto out; |
| 182 | 183 | ||
| 183 | event = trace_buffer_lock_reserve(tr, TRACE_HW_BRANCHES, | 184 | buf = tr->buffer; |
| 185 | event = trace_buffer_lock_reserve(buf, TRACE_HW_BRANCHES, | ||
| 184 | sizeof(*entry), 0, 0); | 186 | sizeof(*entry), 0, 0); |
| 185 | if (!event) | 187 | if (!event) |
| 186 | goto out; | 188 | goto out; |
| @@ -189,8 +191,8 @@ void trace_hw_branch(u64 from, u64 to) | |||
| 189 | entry->ent.type = TRACE_HW_BRANCHES; | 191 | entry->ent.type = TRACE_HW_BRANCHES; |
| 190 | entry->from = from; | 192 | entry->from = from; |
| 191 | entry->to = to; | 193 | entry->to = to; |
| 192 | if (!filter_check_discard(call, entry, tr->buffer, event)) | 194 | if (!filter_check_discard(call, entry, buf, event)) |
| 193 | trace_buffer_unlock_commit(tr, event, 0, 0); | 195 | trace_buffer_unlock_commit(buf, event, 0, 0); |
| 194 | 196 | ||
| 195 | out: | 197 | out: |
| 196 | atomic_dec(&tr->data[cpu]->disabled); | 198 | atomic_dec(&tr->data[cpu]->disabled); |
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index f572f44c6e1..ed17565826b 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c | |||
| @@ -486,16 +486,18 @@ int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry) | |||
| 486 | hardirq ? 'h' : softirq ? 's' : '.')) | 486 | hardirq ? 'h' : softirq ? 's' : '.')) |
| 487 | return 0; | 487 | return 0; |
| 488 | 488 | ||
| 489 | if (entry->lock_depth < 0) | 489 | if (entry->preempt_count) |
| 490 | ret = trace_seq_putc(s, '.'); | 490 | ret = trace_seq_printf(s, "%x", entry->preempt_count); |
| 491 | else | 491 | else |
| 492 | ret = trace_seq_printf(s, "%d", entry->lock_depth); | 492 | ret = trace_seq_putc(s, '.'); |
| 493 | |||
| 493 | if (!ret) | 494 | if (!ret) |
| 494 | return 0; | 495 | return 0; |
| 495 | 496 | ||
| 496 | if (entry->preempt_count) | 497 | if (entry->lock_depth < 0) |
| 497 | return trace_seq_printf(s, "%x", entry->preempt_count); | 498 | return trace_seq_putc(s, '.'); |
| 498 | return trace_seq_putc(s, '.'); | 499 | |
| 500 | return trace_seq_printf(s, "%d", entry->lock_depth); | ||
| 499 | } | 501 | } |
| 500 | 502 | ||
| 501 | static int | 503 | static int |
| @@ -883,7 +885,7 @@ static int trace_ctxwake_raw(struct trace_iterator *iter, char S) | |||
| 883 | trace_assign_type(field, iter->ent); | 885 | trace_assign_type(field, iter->ent); |
| 884 | 886 | ||
| 885 | if (!S) | 887 | if (!S) |
| 886 | task_state_char(field->prev_state); | 888 | S = task_state_char(field->prev_state); |
| 887 | T = task_state_char(field->next_state); | 889 | T = task_state_char(field->next_state); |
| 888 | if (!trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n", | 890 | if (!trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n", |
| 889 | field->prev_pid, | 891 | field->prev_pid, |
| @@ -918,7 +920,7 @@ static int trace_ctxwake_hex(struct trace_iterator *iter, char S) | |||
| 918 | trace_assign_type(field, iter->ent); | 920 | trace_assign_type(field, iter->ent); |
| 919 | 921 | ||
| 920 | if (!S) | 922 | if (!S) |
| 921 | task_state_char(field->prev_state); | 923 | S = task_state_char(field->prev_state); |
| 922 | T = task_state_char(field->next_state); | 924 | T = task_state_char(field->next_state); |
| 923 | 925 | ||
| 924 | SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid); | 926 | SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid); |
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c index 0f6facb050a..8504ac71e4e 100644 --- a/kernel/trace/trace_stack.c +++ b/kernel/trace/trace_stack.c | |||
| @@ -296,14 +296,14 @@ static const struct file_operations stack_trace_fops = { | |||
| 296 | 296 | ||
| 297 | int | 297 | int |
| 298 | stack_trace_sysctl(struct ctl_table *table, int write, | 298 | stack_trace_sysctl(struct ctl_table *table, int write, |
| 299 | struct file *file, void __user *buffer, size_t *lenp, | 299 | void __user *buffer, size_t *lenp, |
| 300 | loff_t *ppos) | 300 | loff_t *ppos) |
| 301 | { | 301 | { |
| 302 | int ret; | 302 | int ret; |
| 303 | 303 | ||
| 304 | mutex_lock(&stack_sysctl_mutex); | 304 | mutex_lock(&stack_sysctl_mutex); |
| 305 | 305 | ||
| 306 | ret = proc_dointvec(table, write, file, buffer, lenp, ppos); | 306 | ret = proc_dointvec(table, write, buffer, lenp, ppos); |
| 307 | 307 | ||
| 308 | if (ret || !write || | 308 | if (ret || !write || |
| 309 | (last_stack_tracer_enabled == !!stack_tracer_enabled)) | 309 | (last_stack_tracer_enabled == !!stack_tracer_enabled)) |
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index 7a3550cf259..527e17eae57 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | #include <trace/events/syscalls.h> | 2 | #include <trace/events/syscalls.h> |
| 3 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
| 4 | #include <linux/ftrace.h> | 4 | #include <linux/ftrace.h> |
| 5 | #include <linux/perf_counter.h> | 5 | #include <linux/perf_event.h> |
| 6 | #include <asm/syscall.h> | 6 | #include <asm/syscall.h> |
| 7 | 7 | ||
| 8 | #include "trace_output.h" | 8 | #include "trace_output.h" |
| @@ -166,7 +166,7 @@ int syscall_exit_format(struct ftrace_event_call *call, struct trace_seq *s) | |||
| 166 | "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n" | 166 | "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n" |
| 167 | "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n", | 167 | "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n", |
| 168 | SYSCALL_FIELD(int, nr), | 168 | SYSCALL_FIELD(int, nr), |
| 169 | SYSCALL_FIELD(unsigned long, ret)); | 169 | SYSCALL_FIELD(long, ret)); |
| 170 | if (!ret) | 170 | if (!ret) |
| 171 | return 0; | 171 | return 0; |
| 172 | 172 | ||
| @@ -212,7 +212,7 @@ int syscall_exit_define_fields(struct ftrace_event_call *call) | |||
| 212 | if (ret) | 212 | if (ret) |
| 213 | return ret; | 213 | return ret; |
| 214 | 214 | ||
| 215 | ret = trace_define_field(call, SYSCALL_FIELD(unsigned long, ret), 0, | 215 | ret = trace_define_field(call, SYSCALL_FIELD(long, ret), 0, |
| 216 | FILTER_OTHER); | 216 | FILTER_OTHER); |
| 217 | 217 | ||
| 218 | return ret; | 218 | return ret; |
| @@ -433,7 +433,7 @@ static void prof_syscall_enter(struct pt_regs *regs, long id) | |||
| 433 | rec->nr = syscall_nr; | 433 | rec->nr = syscall_nr; |
| 434 | syscall_get_arguments(current, regs, 0, sys_data->nb_args, | 434 | syscall_get_arguments(current, regs, 0, sys_data->nb_args, |
| 435 | (unsigned long *)&rec->args); | 435 | (unsigned long *)&rec->args); |
| 436 | perf_tpcounter_event(sys_data->enter_id, 0, 1, rec, size); | 436 | perf_tp_event(sys_data->enter_id, 0, 1, rec, size); |
| 437 | 437 | ||
| 438 | end: | 438 | end: |
| 439 | local_irq_restore(flags); | 439 | local_irq_restore(flags); |
| @@ -532,7 +532,7 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret) | |||
| 532 | rec->nr = syscall_nr; | 532 | rec->nr = syscall_nr; |
| 533 | rec->ret = syscall_get_return_value(current, regs); | 533 | rec->ret = syscall_get_return_value(current, regs); |
| 534 | 534 | ||
| 535 | perf_tpcounter_event(sys_data->exit_id, 0, 1, rec, size); | 535 | perf_tp_event(sys_data->exit_id, 0, 1, rec, size); |
| 536 | 536 | ||
| 537 | end: | 537 | end: |
| 538 | local_irq_restore(flags); | 538 | local_irq_restore(flags); |
