diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-11 20:01:32 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-11 20:01:32 -0400 |
| commit | 6cdfa54cd22984ae785b0d496b53405d6da9ad1d (patch) | |
| tree | 6d5d58d21eccdfebf93a5835258d7f333ef21c13 /kernel | |
| parent | a089e4fed5c5e8717f233d71bb750fbf9e1f38e0 (diff) | |
| parent | 85f726a35e504418607b77c5e7da165dc1ea63ce (diff) | |
Merge tag 'trace-v5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull tracing updates from Steven Rostedt:
"The biggest change for this release is in the histogram code:
- Add "onchange(var)" histogram handler that executes a action when
$var changes.
- Add new "snapshot()" action for histogram handlers, that causes a
snapshot of the ring buffer when triggered. ie.
onchange(var).snapshot() will trigger a snapshot if var changes.
- Add alternative for "trace()" action. Currently, to trigger a
synthetic event, the name of that event is used as the handler
name, which is inconsistent with the other actions.
onchange(var).synthetic(param) where it can now be
onchange(var).trace(synthetic, param). The older method will still
be allowed, as long as the synthetic events do not overlap with
other handler names.
- The histogram documentation at testcases were updated for the new
changes.
Outside of the histogram code, we have:
- Added a quicker way to enable set_ftrace_filter files, that will
make it much quicker to bisect tracing a function that shouldn't be
traced and crashes the kernel. (You can echo in numbers to
set_ftrace_filter, and it will select the corresponding function
that is in available_filter_functions).
- Some better displaying of the tracing data (and more information
was added).
The rest are small fixes and more clean ups to the code"
* tag 'trace-v5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: (37 commits)
tracing: Use strncpy instead of memcpy when copying comm in trace.c
tracing: Use strncpy instead of memcpy when copying comm for hist triggers
tracing: Use strncpy instead of memcpy for string keys in hist triggers
tracing: Use str_has_prefix() in synth_event_create()
x86/ftrace: Fix warning and considate ftrace_jmp_replace() and ftrace_call_replace()
tracing/perf: Use strndup_user() instead of buggy open-coded version
doc: trace: Fix documentation for uprobe_profile
tracing: Fix spelling mistake: "analagous" -> "analogous"
tracing: Comment why cond_snapshot is checked outside of max_lock protection
tracing: Add hist trigger action 'expected fail' test case
tracing: Add alternative synthetic event trace action test case
tracing: Add hist trigger onchange() handler test case
tracing: Add hist trigger snapshot() action test case
tracing: Add SPDX license GPL-2.0 license identifier to inter-event testcases
tracing: Add alternative synthetic event trace action syntax
tracing: Add hist trigger onchange() handler Documentation
tracing: Add hist trigger onchange() handler
tracing: Add hist trigger snapshot() action Documentation
tracing: Add hist trigger snapshot() action
tracing: Add conditional snapshot
...
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_ | ||
