diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/trace/Kconfig | 4 | ||||
| -rw-r--r-- | kernel/trace/ring_buffer.c | 24 | ||||
| -rw-r--r-- | kernel/trace/trace.c | 5 |
3 files changed, 27 insertions, 6 deletions
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 6c22d8a2f289..60e2ce0181ee 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig | |||
| @@ -27,9 +27,7 @@ config HAVE_FUNCTION_GRAPH_TRACER | |||
| 27 | config HAVE_FUNCTION_GRAPH_FP_TEST | 27 | config HAVE_FUNCTION_GRAPH_FP_TEST |
| 28 | bool | 28 | bool |
| 29 | help | 29 | help |
| 30 | An arch may pass in a unique value (frame pointer) to both the | 30 | See Documentation/trace/ftrace-design.txt |
| 31 | entering and exiting of a function. On exit, the value is compared | ||
| 32 | and if it does not match, then it will panic the kernel. | ||
| 33 | 31 | ||
| 34 | config HAVE_FUNCTION_TRACE_MCOUNT_TEST | 32 | config HAVE_FUNCTION_TRACE_MCOUNT_TEST |
| 35 | bool | 33 | bool |
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index edefe3b2801b..8c1b2d290718 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
| @@ -464,6 +464,8 @@ struct ring_buffer_iter { | |||
| 464 | struct ring_buffer_per_cpu *cpu_buffer; | 464 | struct ring_buffer_per_cpu *cpu_buffer; |
| 465 | unsigned long head; | 465 | unsigned long head; |
| 466 | struct buffer_page *head_page; | 466 | struct buffer_page *head_page; |
| 467 | struct buffer_page *cache_reader_page; | ||
| 468 | unsigned long cache_read; | ||
| 467 | u64 read_stamp; | 469 | u64 read_stamp; |
| 468 | }; | 470 | }; |
| 469 | 471 | ||
| @@ -2716,6 +2718,8 @@ static void rb_iter_reset(struct ring_buffer_iter *iter) | |||
| 2716 | iter->read_stamp = cpu_buffer->read_stamp; | 2718 | iter->read_stamp = cpu_buffer->read_stamp; |
| 2717 | else | 2719 | else |
| 2718 | iter->read_stamp = iter->head_page->page->time_stamp; | 2720 | iter->read_stamp = iter->head_page->page->time_stamp; |
| 2721 | iter->cache_reader_page = cpu_buffer->reader_page; | ||
| 2722 | iter->cache_read = cpu_buffer->read; | ||
| 2719 | } | 2723 | } |
| 2720 | 2724 | ||
| 2721 | /** | 2725 | /** |
| @@ -3060,13 +3064,22 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) | |||
| 3060 | struct ring_buffer_event *event; | 3064 | struct ring_buffer_event *event; |
| 3061 | int nr_loops = 0; | 3065 | int nr_loops = 0; |
| 3062 | 3066 | ||
| 3063 | if (ring_buffer_iter_empty(iter)) | ||
| 3064 | return NULL; | ||
| 3065 | |||
| 3066 | cpu_buffer = iter->cpu_buffer; | 3067 | cpu_buffer = iter->cpu_buffer; |
| 3067 | buffer = cpu_buffer->buffer; | 3068 | buffer = cpu_buffer->buffer; |
| 3068 | 3069 | ||
| 3070 | /* | ||
| 3071 | * Check if someone performed a consuming read to | ||
| 3072 | * the buffer. A consuming read invalidates the iterator | ||
| 3073 | * and we need to reset the iterator in this case. | ||
| 3074 | */ | ||
| 3075 | if (unlikely(iter->cache_read != cpu_buffer->read || | ||
| 3076 | iter->cache_reader_page != cpu_buffer->reader_page)) | ||
| 3077 | rb_iter_reset(iter); | ||
| 3078 | |||
| 3069 | again: | 3079 | again: |
| 3080 | if (ring_buffer_iter_empty(iter)) | ||
| 3081 | return NULL; | ||
| 3082 | |||
| 3070 | /* | 3083 | /* |
| 3071 | * We repeat when a timestamp is encountered. | 3084 | * We repeat when a timestamp is encountered. |
| 3072 | * We can get multiple timestamps by nested interrupts or also | 3085 | * We can get multiple timestamps by nested interrupts or also |
| @@ -3081,6 +3094,11 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) | |||
| 3081 | if (rb_per_cpu_empty(cpu_buffer)) | 3094 | if (rb_per_cpu_empty(cpu_buffer)) |
| 3082 | return NULL; | 3095 | return NULL; |
| 3083 | 3096 | ||
| 3097 | if (iter->head >= local_read(&iter->head_page->page->commit)) { | ||
| 3098 | rb_inc_iter(iter); | ||
| 3099 | goto again; | ||
| 3100 | } | ||
| 3101 | |||
| 3084 | event = rb_iter_head_event(iter); | 3102 | event = rb_iter_head_event(iter); |
| 3085 | 3103 | ||
| 3086 | switch (event->type_len) { | 3104 | switch (event->type_len) { |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 0df1b0f2cb9e..eac6875cb990 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -951,6 +951,11 @@ void trace_find_cmdline(int pid, char comm[]) | |||
| 951 | return; | 951 | return; |
| 952 | } | 952 | } |
| 953 | 953 | ||
| 954 | if (WARN_ON_ONCE(pid < 0)) { | ||
| 955 | strcpy(comm, "<XXX>"); | ||
| 956 | return; | ||
| 957 | } | ||
| 958 | |||
| 954 | if (pid > PID_MAX_DEFAULT) { | 959 | if (pid > PID_MAX_DEFAULT) { |
| 955 | strcpy(comm, "<...>"); | 960 | strcpy(comm, "<...>"); |
| 956 | return; | 961 | return; |
