Home Home > GIT Browse > SLE11-SP4
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiroslav Benes <mbenes@suse.cz>2018-12-21 13:28:53 +0100
committerMiroslav Benes <mbenes@suse.cz>2018-12-21 13:28:53 +0100
commit0db51623c02976b4260a7bb75b679f643330d7f7 (patch)
treee0906dc1f71eec848eb6001bd37af5c07409cafd
parent59ef321dae5679d46b3db217fecdae2af5666cc5 (diff)
ring-buffer: Fix infinite spin in reading buffer (bsc#1120107).
-rw-r--r--patches.fixes/ring-buffer-fix-infinite-spin-in-reading-buffer.patch55
-rw-r--r--series.conf1
2 files changed, 56 insertions, 0 deletions
diff --git a/patches.fixes/ring-buffer-fix-infinite-spin-in-reading-buffer.patch b/patches.fixes/ring-buffer-fix-infinite-spin-in-reading-buffer.patch
new file mode 100644
index 0000000000..121bd90cb5
--- /dev/null
+++ b/patches.fixes/ring-buffer-fix-infinite-spin-in-reading-buffer.patch
@@ -0,0 +1,55 @@
+From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>
+Date: Thu, 2 Oct 2014 16:51:18 -0400
+Subject: ring-buffer: Fix infinite spin in reading buffer
+Git-commit: 24607f114fd14f2f37e3e0cb3d47bce96e81e848
+Patch-mainline: v3.17
+References: bsc#1120107
+
+Commit 651e22f2701b "ring-buffer: Always reset iterator to reader page"
+fixed one bug but in the process caused another one. The reset is to
+update the header page, but that fix also changed the way the cached
+reads were updated. The cache reads are used to test if an iterator
+needs to be updated or not.
+
+A ring buffer iterator, when created, disables writes to the ring buffer
+but does not stop other readers or consuming reads from happening.
+Although all readers are synchronized via a lock, they are only
+synchronized when in the ring buffer functions. Those functions may
+be called by any number of readers. The iterator continues down when
+its not interrupted by a consuming reader. If a consuming read
+occurs, the iterator starts from the beginning of the buffer.
+
+The way the iterator sees that a consuming read has happened since
+its last read is by checking the reader "cache". The cache holds the
+last counts of the read and the reader page itself.
+
+Commit 651e22f2701b changed what was saved by the cache_read when
+the rb_iter_reset() occurred, making the iterator never match the cache.
+Then if the iterator calls rb_iter_reset(), it will go into an
+infinite loop by checking if the cache doesn't match, doing the reset
+and retrying, just to see that the cache still doesn't match! Which
+should never happen as the reset is suppose to set the cache to the
+current value and there's locks that keep a consuming reader from
+having access to the data.
+
+Fixes: 651e22f2701b "ring-buffer: Always reset iterator to reader page"
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Acked-by: Miroslav Benes <mbenes@suse.cz>
+---
+ kernel/trace/ring_buffer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
+index b38fb2b9e237..2d75c94ae87d 100644
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -3359,7 +3359,7 @@ static void rb_iter_reset(struct ring_buffer_iter *iter)
+ iter->head = cpu_buffer->reader_page->read;
+
+ iter->cache_reader_page = iter->head_page;
+- iter->cache_read = iter->head;
++ iter->cache_read = cpu_buffer->read;
+
+ if (iter->head)
+ iter->read_stamp = cpu_buffer->read_stamp;
+
diff --git a/series.conf b/series.conf
index f671fbe4db..7c1e5e437d 100644
--- a/series.conf
+++ b/series.conf
@@ -23183,6 +23183,7 @@
patches.fixes/ring-buffer-fix-first-commit-on-sub-buffer-having-non-zero-delta.patch
patches.fixes/ring-buffer-up-rb_iter_peek-loop-count-to-3.patch
patches.fixes/ring-buffer-always-reset-iterator-to-reader-page.patch
+ patches.fixes/ring-buffer-fix-infinite-spin-in-reading-buffer.patch
patches.fixes/tracepoints-do-not-trace-when-cpu-is-offline.patch
########################################################