diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/events/uprobes.c | 8 | ||||
| -rw-r--r-- | kernel/trace/ftrace.c | 30 | ||||
| -rw-r--r-- | kernel/trace/ring_buffer.c | 14 | ||||
| -rw-r--r-- | kernel/trace/trace.c | 223 | ||||
| -rw-r--r-- | kernel/trace/trace.h | 66 | ||||
| -rw-r--r-- | kernel/trace/trace_entries.h | 41 | ||||
| -rw-r--r-- | kernel/trace/trace_event_perf.c | 16 | ||||
| -rw-r--r-- | kernel/trace/trace_events_filter.c | 7 | ||||
| -rw-r--r-- | kernel/trace/trace_events_hist.c | 1059 | ||||
| -rw-r--r-- | kernel/trace/trace_functions_graph.c | 30 | ||||
| -rw-r--r-- | kernel/trace/trace_irqsoff.c | 2 | ||||
| -rw-r--r-- | kernel/trace/trace_probe.c | 1 | ||||
| -rw-r--r-- | kernel/trace/trace_sched_wakeup.c | 11 |
13 files changed, 1148 insertions, 360 deletions
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index affa830a198c..c5cde87329c7 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c | |||
| @@ -53,7 +53,7 @@ static struct percpu_rw_semaphore dup_mmap_sem; | |||
| 53 | 53 | ||
| 54 | struct uprobe { | 54 | struct uprobe { |
| 55 | struct rb_node rb_node; /* node in the rb tree */ | 55 | struct rb_node rb_node; /* node in the rb tree */ |
| 56 | atomic_t ref; | 56 | refcount_t ref; |
| 57 | struct rw_semaphore register_rwsem; | 57 | struct rw_semaphore register_rwsem; |
| 58 | struct rw_semaphore consumer_rwsem; | 58 | struct rw_semaphore consumer_rwsem; |
| 59 | struct list_head pending_list; | 59 | struct list_head pending_list; |
| @@ -547,13 +547,13 @@ set_orig_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long v | |||
| 547 | 547 | ||
| 548 | static struct uprobe *get_uprobe(struct uprobe *uprobe) | 548 | static struct uprobe *get_uprobe(struct uprobe *uprobe) |
| 549 | { | 549 | { |
| 550 | atomic_inc(&uprobe->ref); | 550 | refcount_inc(&uprobe->ref); |
| 551 | return uprobe; | 551 | return uprobe; |
| 552 | } | 552 | } |
| 553 | 553 | ||
| 554 | static void put_uprobe(struct uprobe *uprobe) | 554 | static void put_uprobe(struct uprobe *uprobe) |
| 555 | { | 555 | { |
| 556 | if (atomic_dec_and_test(&uprobe->ref)) { | 556 | if (refcount_dec_and_test(&uprobe->ref)) { |
| 557 | /* | 557 | /* |
| 558 | * If application munmap(exec_vma) before uprobe_unregister() | 558 | * If application munmap(exec_vma) before uprobe_unregister() |
| 559 | * gets called, we don't get a chance to remove uprobe from | 559 | * gets called, we don't get a chance to remove uprobe from |
| @@ -644,7 +644,7 @@ static struct uprobe *__insert_uprobe(struct uprobe *uprobe) | |||
| 644 | rb_link_node(&uprobe->rb_node, parent, p); | 644 | rb_link_node(&uprobe->rb_node, parent, p); |
| 645 | rb_insert_color(&uprobe->rb_node, &uprobes_tree); | 645 | rb_insert_color(&uprobe->rb_node, &uprobes_tree); |
| 646 | /* get access + creation ref */ | 646 | /* get access + creation ref */ |
| 647 | atomic_set(&uprobe->ref, 2); | 647 | refcount_set(&uprobe->ref, 2); |
| 648 | 648 | ||
| 649 | return u; | 649 | return u; |
| 650 | } | 650 | } |
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index aac7847c0214..fa79323331b2 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
| @@ -3702,6 +3702,31 @@ enter_record(struct ftrace_hash *hash, struct dyn_ftrace *rec, int clear_filter) | |||
| 3702 | } | 3702 | } |
| 3703 | 3703 | ||
| 3704 | static int | 3704 | static int |
| 3705 | add_rec_by_index(struct ftrace_hash *hash, struct ftrace_glob *func_g, | ||
| 3706 | int clear_filter) | ||
| 3707 | { | ||
| 3708 | long index = simple_strtoul(func_g->search, NULL, 0); | ||
| 3709 | struct ftrace_page *pg; | ||
| 3710 | struct dyn_ftrace *rec; | ||
| 3711 | |||
| 3712 | /* The index starts at 1 */ | ||
| 3713 | if (--index < 0) | ||
| 3714 | return 0; | ||
| 3715 | |||
| 3716 | do_for_each_ftrace_rec(pg, rec) { | ||
| 3717 | if (pg->index <= index) { | ||
| 3718 | index -= pg->index; | ||
| 3719 | /* this is a double loop, break goes to the next page */ | ||
| 3720 | break; | ||
| 3721 | } | ||
| 3722 | rec = &pg->records[index]; | ||
| 3723 | enter_record(hash, rec, clear_filter); | ||
| 3724 | return 1; | ||
| 3725 | } while_for_each_ftrace_rec(); | ||
| 3726 | return 0; | ||
| 3727 | } | ||
| 3728 | |||
| 3729 | static int | ||
| 3705 | ftrace_match_record(struct dyn_ftrace *rec, struct ftrace_glob *func_g, | 3730 | ftrace_match_record(struct dyn_ftrace *rec, struct ftrace_glob *func_g, |
| 3706 | struct ftrace_glob *mod_g, int exclude_mod) | 3731 | struct ftrace_glob *mod_g, int exclude_mod) |
| 3707 | { | 3732 | { |
| @@ -3769,6 +3794,11 @@ match_records(struct ftrace_hash *hash, char *func, int len, char *mod) | |||
| 3769 | if (unlikely(ftrace_disabled)) | 3794 | if (unlikely(ftrace_disabled)) |
| 3770 | goto out_unlock; | 3795 | goto out_unlock; |
| 3771 | 3796 | ||
| 3797 | if (func_g.type == MATCH_INDEX) { | ||
| 3798 | found = add_rec_by_index(hash, &func_g, clear_filter); | ||
| 3799 | goto out_unlock; | ||
| 3800 | } | ||
| 3801 | |||
| 3772 | do_for_each_ftrace_rec(pg, rec) { | 3802 | do_for_each_ftrace_rec(pg, rec) { |
| 3773 | 3803 | ||
| 3774 | if (rec->flags & FTRACE_FL_DISABLED) | 3804 | if (rec->flags & FTRACE_FL_DISABLED) |
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 06e864a334bb..9a91479bbbfe 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
| @@ -353,20 +353,6 @@ static void rb_init_page(struct buffer_data_page *bpage) | |||
| 353 | local_set(&bpage->commit, 0); | 353 | local_set(&bpage->commit, 0); |
| 354 | } | 354 | } |
| 355 | 355 | ||
| 356 | /** | ||
| 357 | * ring_buffer_page_len - the size of data on the page. | ||
| 358 | * @page: The page to read | ||
| 359 | * | ||
| 360 | * Returns the amount of data on the page, including buffer page header. | ||
| 361 | */ | ||
| 362 | size_t ring_buffer_page_len(void *page) | ||
| 363 | { | ||
| 364 | struct buffer_data_page *bpage = page; | ||
| 365 | |||
| 366 | return (local_read(&bpage->commit) & ~RB_MISSED_FLAGS) | ||
| 367 | + BUF_PAGE_HDR_SIZE; | ||
| 368 | } | ||
| 369 | |||
| 370 | /* | 356 | /* |
| 371 | * Also stolen from mm/slob.c. Thanks to Mathieu Desnoyers for pointing | 357 | * Also stolen from mm/slob.c. Thanks to Mathieu Desnoyers for pointing |
| 372 | * this issue out. | 358 | * this issue out. |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index c4238b441624..d7325eb1bc83 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -894,7 +894,7 @@ int __trace_bputs(unsigned long ip, const char *str) | |||
| 894 | EXPORT_SYMBOL_GPL(__trace_bputs); | 894 | EXPORT_SYMBOL_GPL(__trace_bputs); |
| 895 | 895 | ||
| 896 | #ifdef CONFIG_TRACER_SNAPSHOT | 896 | #ifdef CONFIG_TRACER_SNAPSHOT |
| 897 | void tracing_snapshot_instance(struct trace_array *tr) | 897 | void tracing_snapshot_instance_cond(struct trace_array *tr, void *cond_data) |
| 898 | { | 898 | { |
| 899 | struct tracer *tracer = tr->current_trace; | 899 | struct tracer *tracer = tr->current_trace; |
| 900 | unsigned long flags; | 900 | unsigned long flags; |
| @@ -920,10 +920,15 @@ void tracing_snapshot_instance(struct trace_array *tr) | |||
| 920 | } | 920 | } |
| 921 | 921 | ||
| 922 | local_irq_save(flags); | 922 | local_irq_save(flags); |
| 923 | update_max_tr(tr, current, smp_processor_id()); | 923 | update_max_tr(tr, current, smp_processor_id(), cond_data); |
| 924 | local_irq_restore(flags); | 924 | local_irq_restore(flags); |
| 925 | } | 925 | } |
| 926 | 926 | ||
| 927 | void tracing_snapshot_instance(struct trace_array *tr) | ||
| 928 | { | ||
| 929 | tracing_snapshot_instance_cond(tr, NULL); | ||
| 930 | } | ||
| 931 | |||
| 927 | /** | 932 | /** |
| 928 | * tracing_snapshot - take a snapshot of the current buffer. | 933 | * tracing_snapshot - take a snapshot of the current buffer. |
| 929 | * | 934 | * |
| @@ -946,6 +951,54 @@ void tracing_snapshot(void) | |||
| 946 | } | 951 | } |
| 947 | EXPORT_SYMBOL_GPL(tracing_snapshot); | 952 | EXPORT_SYMBOL_GPL(tracing_snapshot); |
| 948 | 953 | ||
| 954 | /** | ||
| 955 | * tracing_snapshot_cond - conditionally take a snapshot of the current buffer. | ||
| 956 | * @tr: The tracing instance to snapshot | ||
| 957 | * @cond_data: The data to be tested conditionally, and possibly saved | ||
| 958 | * | ||
| 959 | * This is the same as tracing_snapshot() except that the snapshot is | ||
| 960 | * conditional - the snapshot will only happen if the | ||
| 961 | * cond_snapshot.update() implementation receiving the cond_data | ||
| 962 | * returns true, which means that the trace array's cond_snapshot | ||
| 963 | * update() operation used the cond_data to determine whether the | ||
| 964 | * snapshot should be taken, and if it was, presumably saved it along | ||
| 965 | * with the snapshot. | ||
| 966 | */ | ||
| 967 | void tracing_snapshot_cond(struct trace_array *tr, void *cond_data) | ||
| 968 | { | ||
| 969 | tracing_snapshot_instance_cond(tr, cond_data); | ||
| 970 | } | ||
| 971 | EXPORT_SYMBOL_GPL(tracing_snapshot_cond); | ||
| 972 | |||
| 973 | /** | ||
| 974 | * tracing_snapshot_cond_data - get the user data associated with a snapshot | ||
| 975 | * @tr: The tracing instance | ||
| 976 | * | ||
| 977 | * When the user enables a conditional snapshot using | ||
| 978 | * tracing_snapshot_cond_enable(), the user-defined cond_data is saved | ||
| 979 | * with the snapshot. This accessor is used to retrieve it. | ||
| 980 | * | ||
| 981 | * Should not be called from cond_snapshot.update(), since it takes | ||
| 982 | * the tr->max_lock lock, which the code calling | ||
| 983 | * cond_snapshot.update() has already done. | ||
| 984 | * | ||
| 985 | * Returns the cond_data associated with the trace array's snapshot. | ||
| 986 | */ | ||
| 987 | void *tracing_cond_snapshot_data(struct trace_array *tr) | ||
| 988 | { | ||
| 989 | void *cond_data = NULL; | ||
| 990 | |||
| 991 | arch_spin_lock(&tr->max_lo | ||
