Skip to contentSkip to conversation

[2.6.33] ring-buffer: urgent changes

GIT PULL New Steven Rostedt 2 participants 4 messages Jan 7, 2010

Subsystems (2)
lore
Share & tools
lore

Steven Rostedt

author maintainer
#0 lore raw

Ingo,

Please pull the latest tip/tracing/urgent tree, which can be found at:

git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace.git
tip/tracing/urgent

David Sharp (1):
ring-buffer: Wrap a list.next reference with rb_list_head()

Steven Rostedt (1):
ring-buffer: Add rb_list_head() wrapper around new reader page next field

----

 kernel/trace/ring_buffer.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
author maintainer
#1 lore raw

PATCH 1/2 ring-buffer: Wrap a list.next reference with rb_list_head()

From: David Sharp <[email protected]>

This reference at the end of rb_get_reader_page() was causing off-by-one writes to the prev pointer of the page after the reader page when that page is the head page, and therefore the reader page has the RB_PAGE_HEAD flag in its list.next pointer. This eventually results in a GPF in a subsequent call to rb_set_head_page() (usually from rb_get_reader_page()) when that prev pointer is dereferenced. The dereferenced register would characteristically have an address that appears shifted left by one byte (eg, ffxxxxxxxxxxxxyy instead of ffffxxxxxxxxxxxx) due to being written at an address one byte too high.

LKML-Reference: <[email protected]>

---
 kernel/trace/ring_buffer.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
kernel/trace/ring_buffer.c +1 -1
index 2326b04..d5b7308 100644
@@ -2906,7 +2906,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
 	 *
 	 * Now make the new head point back to the reader page.
 	 */
-	reader->list.next->prev = &cpu_buffer->reader_page->list;
+	rb_list_head(reader->list.next)->prev = &cpu_buffer->reader_page->list;
 	rb_inc_page(cpu_buffer, &cpu_buffer->head_page);
 
 	/* Finally update the reader page to the new head */
Signature · 1 line
1.6.5
author maintainer
#2 lore raw

PATCH 2/2 ring-buffer: Add rb_list_head() wrapper around new reader page next field

In reply to Steven Rostedt

From: Steven Rostedt <[email protected]>

If the very unlikely case happens where the writer moves the head by one between where the head page is read and where the new reader page is assigned _and_ the writer then writes and wraps the entire ring buffer so that the head page is back to what was originally read as the head page, the page to be swapped will have a corrupted next pointer.

Simple solution is to wrap the assignment of the next pointer with a rb_list_head().

---
 kernel/trace/ring_buffer.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
kernel/trace/ring_buffer.c +1 -1
index d5b7308..edefe3b 100644
@@ -2869,7 +2869,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
 	 * Splice the empty reader page into the list around the head.
 	 */
 	reader = rb_set_head_page(cpu_buffer);
-	cpu_buffer->reader_page->list.next = reader->list.next;
+	cpu_buffer->reader_page->list.next = rb_list_head(reader->list.next);
 	cpu_buffer->reader_page->list.prev = reader->list.prev;
 
 	/*
Signature · 1 line
1.6.5
#3 lore raw
In reply to Steven Rostedt
Quoted 12 lines · Steven Rostedt

Ingo,

Please pull the latest tip/tracing/urgent tree, which can be found at:

git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace.git
tip/tracing/urgent

David Sharp (1):
ring-buffer: Wrap a list.next reference with rb_list_head()

Quoted 6 lines

Steven Rostedt (1):
ring-buffer: Add rb_list_head() wrapper around new reader page next field

----

 kernel/trace/ring_buffer.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

Pulled, thanks a lot Steve!

Ingo