diff options
author | Tejun Heo <tj@kernel.org> | 2010-02-02 00:38:15 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2010-02-02 00:38:15 -0500 |
commit | ab386128f20c44c458a90039ab1bdc265ac474c9 (patch) | |
tree | 2ad188744922b1bb951fd10ff50dc04c83acce22 /kernel/trace/ring_buffer.c | |
parent | dbfc196a3cc1a2514ad0737a82f764de23bd65e6 (diff) | |
parent | ab658321f32770b903a4426e2a6fae0392757755 (diff) |
Merge branch 'master' into percpu
Diffstat (limited to 'kernel/trace/ring_buffer.c')
-rw-r--r-- | kernel/trace/ring_buffer.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index eb6c8988c31a..0287f9f52f5a 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -465,6 +465,8 @@ struct ring_buffer_iter { | |||
465 | struct ring_buffer_per_cpu *cpu_buffer; | 465 | struct ring_buffer_per_cpu *cpu_buffer; |
466 | unsigned long head; | 466 | unsigned long head; |
467 | struct buffer_page *head_page; | 467 | struct buffer_page *head_page; |
468 | struct buffer_page *cache_reader_page; | ||
469 | unsigned long cache_read; | ||
468 | u64 read_stamp; | 470 | u64 read_stamp; |
469 | }; | 471 | }; |
470 | 472 | ||
@@ -2717,6 +2719,8 @@ static void rb_iter_reset(struct ring_buffer_iter *iter) | |||
2717 | iter->read_stamp = cpu_buffer->read_stamp; | 2719 | iter->read_stamp = cpu_buffer->read_stamp; |
2718 | else | 2720 | else |
2719 | iter->read_stamp = iter->head_page->page->time_stamp; | 2721 | iter->read_stamp = iter->head_page->page->time_stamp; |
2722 | iter->cache_reader_page = cpu_buffer->reader_page; | ||
2723 | iter->cache_read = cpu_buffer->read; | ||
2720 | } | 2724 | } |
2721 | 2725 | ||
2722 | /** | 2726 | /** |
@@ -2870,7 +2874,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) | |||
2870 | * Splice the empty reader page into the list around the head. | 2874 | * Splice the empty reader page into the list around the head. |
2871 | */ | 2875 | */ |
2872 | reader = rb_set_head_page(cpu_buffer); | 2876 | reader = rb_set_head_page(cpu_buffer); |
2873 | cpu_buffer->reader_page->list.next = reader->list.next; | 2877 | cpu_buffer->reader_page->list.next = rb_list_head(reader->list.next); |
2874 | cpu_buffer->reader_page->list.prev = reader->list.prev; | 2878 | cpu_buffer->reader_page->list.prev = reader->list.prev; |
2875 | 2879 | ||
2876 | /* | 2880 | /* |
@@ -2907,7 +2911,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) | |||
2907 | * | 2911 | * |
2908 | * Now make the new head point back to the reader page. | 2912 | * Now make the new head point back to the reader page. |
2909 | */ | 2913 | */ |
2910 | reader->list.next->prev = &cpu_buffer->reader_page->list; | 2914 | rb_list_head(reader->list.next)->prev = &cpu_buffer->reader_page->list; |
2911 | rb_inc_page(cpu_buffer, &cpu_buffer->head_page); | 2915 | rb_inc_page(cpu_buffer, &cpu_buffer->head_page); |
2912 | 2916 | ||
2913 | /* Finally update the reader page to the new head */ | 2917 | /* Finally update the reader page to the new head */ |
@@ -3061,13 +3065,22 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) | |||
3061 | struct ring_buffer_event *event; | 3065 | struct ring_buffer_event *event; |
3062 | int nr_loops = 0; | 3066 | int nr_loops = 0; |
3063 | 3067 | ||
3064 | if (ring_buffer_iter_empty(iter)) | ||
3065 | return NULL; | ||
3066 | |||
3067 | cpu_buffer = iter->cpu_buffer; | 3068 | cpu_buffer = iter->cpu_buffer; |
3068 | buffer = cpu_buffer->buffer; | 3069 | buffer = cpu_buffer->buffer; |
3069 | 3070 | ||
3071 | /* | ||
3072 | * Check if someone performed a consuming read to | ||
3073 | * the buffer. A consuming read invalidates the iterator | ||
3074 | * and we need to reset the iterator in this case. | ||
3075 | */ | ||
3076 | if (unlikely(iter->cache_read != cpu_buffer->read || | ||
3077 | iter->cache_reader_page != cpu_buffer->reader_page)) | ||
3078 | rb_iter_reset(iter); | ||
3079 | |||
3070 | again: | 3080 | again: |
3081 | if (ring_buffer_iter_empty(iter)) | ||
3082 | return NULL; | ||
3083 | |||
3071 | /* | 3084 | /* |
3072 | * We repeat when a timestamp is encountered. | 3085 | * We repeat when a timestamp is encountered. |
3073 | * We can get multiple timestamps by nested interrupts or also | 3086 | * We can get multiple timestamps by nested interrupts or also |
@@ -3082,6 +3095,11 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) | |||
3082 | if (rb_per_cpu_empty(cpu_buffer)) | 3095 | if (rb_per_cpu_empty(cpu_buffer)) |
3083 | return NULL; | 3096 | return NULL; |
3084 | 3097 | ||
3098 | if (iter->head >= local_read(&iter->head_page->page->commit)) { | ||
3099 | rb_inc_iter(iter); | ||
3100 | goto again; | ||
3101 | } | ||
3102 | |||
3085 | event = rb_iter_head_event(iter); | 3103 | event = rb_iter_head_event(iter); |
3086 | 3104 | ||
3087 | switch (event->type_len) { | 3105 | switch (event->type_len) { |