diff options
Diffstat (limited to 'kernel/trace/ring_buffer.c')
-rw-r--r-- | kernel/trace/ring_buffer.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index bb6922a931b1..d03f4f44a823 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -838,6 +838,7 @@ rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer) | |||
838 | * back to us). This allows us to do a simple loop to | 838 | * back to us). This allows us to do a simple loop to |
839 | * assign the commit to the tail. | 839 | * assign the commit to the tail. |
840 | */ | 840 | */ |
841 | again: | ||
841 | while (cpu_buffer->commit_page != cpu_buffer->tail_page) { | 842 | while (cpu_buffer->commit_page != cpu_buffer->tail_page) { |
842 | cpu_buffer->commit_page->page->commit = | 843 | cpu_buffer->commit_page->page->commit = |
843 | cpu_buffer->commit_page->write; | 844 | cpu_buffer->commit_page->write; |
@@ -853,6 +854,17 @@ rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer) | |||
853 | cpu_buffer->commit_page->write; | 854 | cpu_buffer->commit_page->write; |
854 | barrier(); | 855 | barrier(); |
855 | } | 856 | } |
857 | |||
858 | /* again, keep gcc from optimizing */ | ||
859 | barrier(); | ||
860 | |||
861 | /* | ||
862 | * If an interrupt came in just after the first while loop | ||
863 | * and pushed the tail page forward, we will be left with | ||
864 | * a dangling commit that will never go forward. | ||
865 | */ | ||
866 | if (unlikely(cpu_buffer->commit_page != cpu_buffer->tail_page)) | ||
867 | goto again; | ||
856 | } | 868 | } |
857 | 869 | ||
858 | static void rb_reset_reader_page(struct ring_buffer_per_cpu *cpu_buffer) | 870 | static void rb_reset_reader_page(struct ring_buffer_per_cpu *cpu_buffer) |