Home Home > GIT Browse > SLE11-SP4
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiroslav Benes <mbenes@suse.cz>2018-12-20 17:43:00 +0100
committerMiroslav Benes <mbenes@suse.cz>2018-12-20 17:43:00 +0100
commit7df010dc838b64aae127f01062102837f8904f6f (patch)
tree123343054861fed759c63fe35911f0f6c953f36b
parentb98c1cd8884737c17215d06f05d34e80d43eba03 (diff)
ring-buffer: Up rb_iter_peek() loop count to 3 (bsc#1120105).
-rw-r--r--patches.fixes/ring-buffer-up-rb_iter_peek-loop-count-to-3.patch99
-rw-r--r--series.conf1
2 files changed, 100 insertions, 0 deletions
diff --git a/patches.fixes/ring-buffer-up-rb_iter_peek-loop-count-to-3.patch b/patches.fixes/ring-buffer-up-rb_iter_peek-loop-count-to-3.patch
new file mode 100644
index 0000000000..41d5a7f6d7
--- /dev/null
+++ b/patches.fixes/ring-buffer-up-rb_iter_peek-loop-count-to-3.patch
@@ -0,0 +1,99 @@
+From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>
+Date: Wed, 6 Aug 2014 15:36:31 -0400
+Subject: ring-buffer: Up rb_iter_peek() loop count to 3
+Git-commit: 021de3d904b88b1771a3a2cfc5b75023c391e646
+Patch-mainline: v3.17-rc1
+References: bsc#1120105
+
+After writting a test to try to trigger the bug that caused the
+ring buffer iterator to become corrupted, I hit another bug:
+
+ WARNING: CPU: 1 PID: 5281 at kernel/trace/ring_buffer.c:3766 rb_iter_peek+0x113/0x238()
+ Modules linked in: ipt_MASQUERADE sunrpc [...]
+ CPU: 1 PID: 5281 Comm: grep Tainted: G W 3.16.0-rc3-test+ #143
+ Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./To be filled by O.E.M., BIOS SDBLI944.86P 05/08/2007
+ 0000000000000000 ffffffff81809a80 ffffffff81503fb0 0000000000000000
+ ffffffff81040ca1 ffff8800796d6010 ffffffff810c138d ffff8800796d6010
+ ffff880077438c80 ffff8800796d6010 ffff88007abbe600 0000000000000003
+ Call Trace:
+ [<ffffffff81503fb0>] ? dump_stack+0x4a/0x75
+ [<ffffffff81040ca1>] ? warn_slowpath_common+0x7e/0x97
+ [<ffffffff810c138d>] ? rb_iter_peek+0x113/0x238
+ [<ffffffff810c138d>] ? rb_iter_peek+0x113/0x238
+ [<ffffffff810c14df>] ? ring_buffer_iter_peek+0x2d/0x5c
+ [<ffffffff810c6f73>] ? tracing_iter_reset+0x6e/0x96
+ [<ffffffff810c74a3>] ? s_start+0xd7/0x17b
+ [<ffffffff8112b13e>] ? kmem_cache_alloc_trace+0xda/0xea
+ [<ffffffff8114cf94>] ? seq_read+0x148/0x361
+ [<ffffffff81132d98>] ? vfs_read+0x93/0xf1
+ [<ffffffff81132f1b>] ? SyS_read+0x60/0x8e
+ [<ffffffff8150bf9f>] ? tracesys+0xdd/0xe2
+
+Debugging this bug, which triggers when the rb_iter_peek() loops too
+many times (more than 2 times), I discovered there's a case that can
+cause that function to legitimately loop 3 times!
+
+rb_iter_peek() is different than rb_buffer_peek() as the rb_buffer_peek()
+only deals with the reader page (it's for consuming reads). The
+rb_iter_peek() is for traversing the buffer without consuming it, and as
+such, it can loop for one more reason. That is, if we hit the end of
+the reader page or any page, it will go to the next page and try again.
+
+That is, we have this:
+
+ 1. iter->head > iter->head_page->page->commit
+ (rb_inc_iter() which moves the iter to the next page)
+ try again
+
+ 2. event = rb_iter_head_event()
+ event->type_len == RINGBUF_TYPE_TIME_EXTEND
+ rb_advance_iter()
+ try again
+
+ 3. read the event.
+
+But we never get to 3, because the count is greater than 2 and we
+cause the WARNING and return NULL.
+
+Up the counter to 3.
+
+Cc: stable@vger.kernel.org # 2.6.37+
+Fixes: 69d1b839f7ee "ring-buffer: Bind time extend and data events together"
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Acked-by: Miroslav Benes <mbenes@suse.cz>
+---
+ kernel/trace/ring_buffer.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -1611,7 +1611,7 @@ rb_add_time_stamp(struct ring_buffer_eve
+
+ /**
+ * ring_buffer_update_event - update event type and data
+- * @event: the even to update
++ * @event: the event to update
+ * @type: the type of event
+ * @length: the size of the event field in the ring buffer
+ *
+@@ -3166,12 +3166,14 @@ rb_iter_peek(struct ring_buffer_iter *it
+ return NULL;
+
+ /*
+- * We repeat when a time extend is encountered.
+- * Since the time extend is always attached to a data event,
+- * we should never loop more than once.
+- * (We never hit the following condition more than twice).
++ * We repeat when a time extend is encountered or we hit
++ * the end of the page. Since the time extend is always attached
++ * to a data event, we should never loop more than three times.
++ * Once for going to next page, once on time extend, and
++ * finally once to get the event.
++ * (We never hit the following condition more than thrice).
+ */
+- if (RB_WARN_ON(cpu_buffer, ++nr_loops > 2))
++ if (RB_WARN_ON(cpu_buffer, ++nr_loops > 3))
+ return NULL;
+
+ if (rb_per_cpu_empty(cpu_buffer))
+
diff --git a/series.conf b/series.conf
index 9e8c88b934..c5bb79282d 100644
--- a/series.conf
+++ b/series.conf
@@ -23181,6 +23181,7 @@
patches.fixes/tracing-allow-events-to-have-null-strings.patch
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
########################################################
# KVM patches