All of lore.kernel.org
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: linux-kernel@vger.kernel.org
Cc: Ingo Molnar <mingo@elte.hu>, Thomas Gleixner <tglx@linutronix.de>,
	Peter Zijlstra <peterz@infradead.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	prasad@linux.vnet.ibm.com,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Mathieu Desnoyers <compudj@krystal.dyndns.org>,
	"Frank Ch. Eigler" <fche@redhat.com>,
	David Wilder <dwilder@us.ibm.com>,
	hch@lst.de, Martin Bligh <mbligh@google.com>,
	Tom Zanussi <zanussi@comcast.net>,
	Steven Rostedt <srostedt@redhat.com>
Subject: [RFC PATCH 3/3] ftrace: hack in the ring buffer
Date: Wed, 24 Sep 2008 01:10:59 -0400	[thread overview]
Message-ID: <20080924051400.552924670@goodmis.org> (raw)
In-Reply-To: 20080924051056.650388887@goodmis.org

[-- Attachment #1: ftrace-use-ring-buffer.patch --]
[-- Type: text/plain, Size: 78498 bytes --]

As a test case for the unified ring buffer, I wanted to try it out with
ftrace. This is a big patch that hacks up ftrace to get it to work.
Actually, I see areas that can be greatly improved with this new approach.
A lot of clean ups can follow this.

But before I go ahead and do all this work, I want to "release early
release often". This way I can get the feedback (whew, it's hot in here)
that will let me know what is expected.

Note, selftest is busted with this patch. I didn't have time to fixe it.

All these patches are busted, this is RFC remember!

Signed-off-by: Steven Rostedt <srostedt@redhat.com>
---
 arch/x86/kernel/Makefile          |    1 
 include/linux/ftrace.h            |    6 
 include/linux/mmiotrace.h         |    3 
 kernel/trace/trace.c              | 1326 ++++++++++----------------------------
 kernel/trace/trace.h              |   87 --
 kernel/trace/trace_functions.c    |    2 
 kernel/trace/trace_irqsoff.c      |   38 -
 kernel/trace/trace_mmiotrace.c    |   73 --
 kernel/trace/trace_sched_switch.c |    2 
 kernel/trace/trace_sched_wakeup.c |    3 
 10 files changed, 464 insertions(+), 1077 deletions(-)

Index: linux-compile.git/kernel/trace/trace.c
===================================================================
--- linux-compile.git.orig/kernel/trace/trace.c	2008-09-23 23:33:47.000000000 -0400
+++ linux-compile.git/kernel/trace/trace.c	2008-09-24 00:16:24.000000000 -0400
@@ -31,25 +31,24 @@
 #include <linux/writeback.h>
 
 #include <linux/stacktrace.h>
+#include <linux/ring_buffer.h>
 
 #include "trace.h"
 
+#define FTRACE_BUF_NAME		"ftrace"
+
+#define TRACE_BUFFER_FLAGS	(RB_FL_OVERWRITE | RB_FL_SNAPSHOT)
+
 unsigned long __read_mostly	tracing_max_latency = (cycle_t)ULONG_MAX;
 unsigned long __read_mostly	tracing_thresh;
 
-static unsigned long __read_mostly	tracing_nr_buffers;
 static cpumask_t __read_mostly		tracing_buffer_mask;
 
 #define for_each_tracing_cpu(cpu)	\
 	for_each_cpu_mask(cpu, tracing_buffer_mask)
 
-static int trace_alloc_page(void);
-static int trace_free_page(void);
-
 static int tracing_disabled = 1;
 
-static unsigned long tracing_pages_allocated;
-
 long
 ns2usecs(cycle_t nsec)
 {
@@ -79,20 +78,6 @@ static struct trace_array	global_trace;
 
 static DEFINE_PER_CPU(struct trace_array_cpu, global_trace_cpu);
 
-/*
- * The max_tr is used to snapshot the global_trace when a maximum
- * latency is reached. Some tracers will use this to store a maximum
- * trace while it continues examining live traces.
- *
- * The buffers for the max_tr are set up the same as the global_trace.
- * When a snapshot is taken, the link list of the max_tr is swapped
- * with the link list of the global_trace and the buffers are reset for
- * the global_trace so the tracing can continue.
- */
-static struct trace_array	max_tr;
-
-static DEFINE_PER_CPU(struct trace_array_cpu, max_data);
-
 /* tracer_enabled is used to toggle activation of a tracer */
 static int			tracer_enabled = 1;
 
@@ -100,11 +85,11 @@ static int			tracer_enabled = 1;
 int				ftrace_function_enabled;
 
 /*
- * trace_nr_entries is the number of entries that is allocated
- * for a buffer. Note, the number of entries is always rounded
- * to ENTRIES_PER_PAGE.
+ * trace_buf_size is the size in bytes that is allocated
+ * for a buffer. Note, the number of bytes is always rounded
+ * to page size.
  */
-static unsigned long		trace_nr_entries = 65536UL;
+static unsigned long		trace_buf_size = 65536UL;
 
 /* trace_types holds a link list of available tracers. */
 static struct tracer		*trace_types __read_mostly;
@@ -140,7 +125,7 @@ static notrace void no_trace_init(struct
 	ftrace_function_enabled = 0;
 	if(tr->ctrl)
 		for_each_online_cpu(cpu)
-			tracing_reset(tr->data[cpu]);
+			tracing_reset(tr, cpu);
 	tracer_enabled = 0;
 }
 
@@ -167,23 +152,21 @@ void trace_wake_up(void)
 		wake_up(&trace_wait);
 }
 
-#define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(struct trace_entry))
-
-static int __init set_nr_entries(char *str)
+static int __init set_buf_size(char *str)
 {
-	unsigned long nr_entries;
+	unsigned long buf_size;
 	int ret;
 
 	if (!str)
 		return 0;
-	ret = strict_strtoul(str, 0, &nr_entries);
+	ret = strict_strtoul(str, 0, &buf_size);
 	/* nr_entries can not be zero */
-	if (ret < 0 || nr_entries == 0)
+	if (ret < 0 || buf_size == 0)
 		return 0;
-	trace_nr_entries = nr_entries;
+	trace_buf_size = buf_size;
 	return 1;
 }
-__setup("trace_entries=", set_nr_entries);
+__setup("trace_buf_size=", set_buf_size);
 
 unsigned long nsecs_to_usecs(unsigned long nsecs)
 {
@@ -249,245 +232,20 @@ __update_max_tr(struct trace_array *tr, 
 {
 	struct trace_array_cpu *data = tr->data[cpu];
 
-	max_tr.cpu = cpu;
-	max_tr.time_start = data->preempt_timestamp;
-
-	data = max_tr.data[cpu];
-	data->saved_latency = tracing_max_latency;
-
-	memcpy(data->comm, tsk->comm, TASK_COMM_LEN);
-	data->pid = tsk->pid;
-	data->uid = tsk->uid;
-	data->nice = tsk->static_prio - 20 - MAX_RT_PRIO;
-	data->policy = tsk->policy;
-	data->rt_priority = tsk->rt_priority;
+	tr->cpu = cpu;
+	tr->time_start = data->preempt_timestamp;
+	tr->saved_latency = tracing_max_latency;
+	tr->pid = tsk->pid;
+	tr->uid = tsk->uid;
+	tr->nice = tsk->static_prio - 20 - MAX_RT_PRIO;
+	tr->policy = tsk->policy;
+	tr->rt_priority = tsk->rt_priority;
+	memcpy(tr->comm, tsk->comm, TASK_COMM_LEN);
 
 	/* record this tasks comm */
 	tracing_record_cmdline(current);
 }
 
-#define CHECK_COND(cond)			\
-	if (unlikely(cond)) {			\
-		tracing_disabled = 1;		\
-		WARN_ON(1);			\
-		return -1;			\
-	}
-
-/**
- * check_pages - integrity check of trace buffers
- *
- * As a safty measure we check to make sure the data pages have not
- * been corrupted.
- */
-int check_pages(struct trace_array_cpu *data)
-{
-	struct page *page, *tmp;
-
-	CHECK_COND(data->trace_pages.next->prev != &data->trace_pages);
-	CHECK_COND(data->trace_pages.prev->next != &data->trace_pages);
-
-	list_for_each_entry_safe(page, tmp, &data->trace_pages, lru) {
-		CHECK_COND(page->lru.next->prev != &page->lru);
-		CHECK_COND(page->lru.prev->next != &page->lru);
-	}
-
-	return 0;
-}
-
-/**
- * head_page - page address of the first page in per_cpu buffer.
- *
- * head_page returns the page address of the first page in
- * a per_cpu buffer. This also preforms various consistency
- * checks to make sure the buffer has not been corrupted.
- */
-void *head_page(struct trace_array_cpu *data)
-{
-	struct page *page;
-
-	if (list_empty(&data->trace_pages))
-		return NULL;
-
-	page = list_entry(data->trace_pages.next, struct page, lru);
-	BUG_ON(&page->lru == &data->trace_pages);
-
-	return page_address(page);
-}
-
-/**
- * trace_seq_printf - sequence printing of trace information
- * @s: trace sequence descriptor
- * @fmt: printf format string
- *
- * The tracer may use either sequence operations or its own
- * copy to user routines. To simplify formating of a trace
- * trace_seq_printf is used to store strings into a special
- * buffer (@s). Then the output may be either used by
- * the sequencer or pulled into another buffer.
- */
-int
-trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
-{
-	int len = (PAGE_SIZE - 1) - s->len;
-	va_list ap;
-	int ret;
-
-	if (!len)
-		return 0;
-
-	va_start(ap, fmt);
-	ret = vsnprintf(s->buffer + s->len, len, fmt, ap);
-	va_end(ap);
-
-	/* If we can't write it all, don't bother writing anything */
-	if (ret >= len)
-		return 0;
-
-	s->len += ret;
-
-	return len;
-}
-
-/**
- * trace_seq_puts - trace sequence printing of simple string
- * @s: trace sequence descriptor
- * @str: simple string to record
- *
- * The tracer may use either the sequence operations or its own
- * copy to user routines. This function records a simple string
- * into a special buffer (@s) for later retrieval by a sequencer
- * or other mechanism.
- */
-static int
-trace_seq_puts(struct trace_seq *s, const char *str)
-{
-	int len = strlen(str);
-
-	if (len > ((PAGE_SIZE - 1) - s->len))
-		return 0;
-
-	memcpy(s->buffer + s->len, str, len);
-	s->len += len;
-
-	return len;
-}
-
-static int
-trace_seq_putc(struct trace_seq *s, unsigned char c)
-{
-	if (s->len >= (PAGE_SIZE - 1))
-		return 0;
-
-	s->buffer[s->len++] = c;
-
-	return 1;
-}
-
-static int
-trace_seq_putmem(struct trace_seq *s, void *mem, size_t len)
-{
-	if (len > ((PAGE_SIZE - 1) - s->len))
-		return 0;
-
-	memcpy(s->buffer + s->len, mem, len);
-	s->len += len;
-
-	return len;
-}
-
-#define HEX_CHARS 17
-static const char hex2asc[] = "0123456789abcdef";
-
-static int
-trace_seq_putmem_hex(struct trace_seq *s, void *mem, size_t len)
-{
-	unsigned char hex[HEX_CHARS];
-	unsigned char *data = mem;
-	unsigned char byte;
-	int i, j;
-
-	BUG_ON(len >= HEX_CHARS);
-
-#ifdef __BIG_ENDIAN
-	for (i = 0, j = 0; i < len; i++) {
-#else
-	for (i = len-1, j = 0; i >= 0; i--) {
-#endif
-		byte = data[i];
-
-		hex[j++] = hex2asc[byte & 0x0f];
-		hex[j++] = hex2asc[byte >> 4];
-	}
-	hex[j++] = ' ';
-
-	return trace_seq_putmem(s, hex, j);
-}
-
-static void
-trace_seq_reset(struct trace_seq *s)
-{
-	s->len = 0;
-	s->readpos = 0;
-}
-
-ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt)
-{
-	int len;
-	int ret;
-
-	if (s->len <= s->readpos)
-		return -EBUSY;
-
-	len = s->len - s->readpos;
-	if (cnt > len)
-		cnt = len;
-	ret = copy_to_user(ubuf, s->buffer + s->readpos, cnt);
-	if (ret)
-		return -EFAULT;
-
-	s->readpos += len;
-	return cnt;
-}
-
-static void
-trace_print_seq(struct seq_file *m, struct trace_seq *s)
-{
-	int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len;
-
-	s->buffer[len] = 0;
-	seq_puts(m, s->buffer);
-
-	trace_seq_reset(s);
-}
-
-/*
- * flip the trace buffers between two trace descriptors.
- * This usually is the buffers between the global_trace and
- * the max_tr to record a snapshot of a current trace.
- *
- * The ftrace_max_lock must be held.
- */
-static void
-flip_trace(struct trace_array_cpu *tr1, struct trace_array_cpu *tr2)
-{
-	struct list_head flip_pages;
-
-	INIT_LIST_HEAD(&flip_pages);
-
-	memcpy(&tr1->trace_head_idx, &tr2->trace_head_idx,
-		sizeof(struct trace_array_cpu) -
-		offsetof(struct trace_array_cpu, trace_head_idx));
-
-	check_pages(tr1);
-	check_pages(tr2);
-	list_splice_init(&tr1->trace_pages, &flip_pages);
-	list_splice_init(&tr2->trace_pages, &tr1->trace_pages);
-	list_splice_init(&flip_pages, &tr2->trace_pages);
-	BUG_ON(!list_empty(&flip_pages));
-	check_pages(tr1);
-	check_pages(tr2);
-}
-
 /**
  * update_max_tr - snapshot all trace buffers from global_trace to max_tr
  * @tr: tracer
@@ -500,18 +258,9 @@ flip_trace(struct trace_array_cpu *tr1, 
 void
 update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
 {
-	struct trace_array_cpu *data;
-	int i;
-
 	WARN_ON_ONCE(!irqs_disabled());
 	__raw_spin_lock(&ftrace_max_lock);
-	/* clear out all the previous traces */
-	for_each_tracing_cpu(i) {
-		data = tr->data[i];
-		flip_trace(max_tr.data[i], data);
-		tracing_reset(data);
-	}
-
+	ring_buffer_snapshot(tr->buffer);
 	__update_max_tr(tr, tsk, cpu);
 	__raw_spin_unlock(&ftrace_max_lock);
 }
@@ -527,21 +276,20 @@ update_max_tr(struct trace_array *tr, st
 void
 update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu)
 {
-	struct trace_array_cpu *data = tr->data[cpu];
-	int i;
-
 	WARN_ON_ONCE(!irqs_disabled());
 	__raw_spin_lock(&ftrace_max_lock);
-	for_each_tracing_cpu(i)
-		tracing_reset(max_tr.data[i]);
-
-	flip_trace(max_tr.data[cpu], data);
-	tracing_reset(data);
-
+	ring_buffer_snapshot_one_cpu(tr->buffer, cpu);
 	__update_max_tr(tr, tsk, cpu);
 	__raw_spin_unlock(&ftrace_max_lock);
 }
 
+#define CHECK_COND(cond)			\
+	if (unlikely(cond)) {			\
+		tracing_disabled = 1;		\
+		WARN_ON(1);			\
+		return -1;			\
+	}
+
 /**
  * register_tracer - register a tracer with the ftrace system.
  * @type - the plugin for the tracer
@@ -573,7 +321,6 @@ int register_tracer(struct tracer *type)
 #ifdef CONFIG_FTRACE_STARTUP_TEST
 	if (type->selftest) {
 		struct tracer *saved_tracer = current_trace;
-		struct trace_array_cpu *data;
 		struct trace_array *tr = &global_trace;
 		int saved_ctrl = tr->ctrl;
 		int i;
@@ -585,10 +332,7 @@ int register_tracer(struct tracer *type)
 		 * If we fail, we do not register this tracer.
 		 */
 		for_each_tracing_cpu(i) {
-			data = tr->data[i];
-			if (!head_page(data))
-				continue;
-			tracing_reset(data);
+			tracing_reset(tr, i);
 		}
 		current_trace = type;
 		tr->ctrl = 0;
@@ -604,10 +348,7 @@ int register_tracer(struct tracer *type)
 		}
 		/* Only reset on passing, to avoid touching corrupted buffers */
 		for_each_tracing_cpu(i) {
-			data = tr->data[i];
-			if (!head_page(data))
-				continue;
-			tracing_reset(data);
+			tracing_reset(tr, i);
 		}
 		printk(KERN_CONT "PASSED\n");
 	}
@@ -653,13 +394,9 @@ void unregister_tracer(struct tracer *ty
 	mutex_unlock(&trace_types_lock);
 }
 
-void tracing_reset(struct trace_array_cpu *data)
+void tracing_reset(struct trace_array *tr, int cpu)
 {
-	data->trace_idx = 0;
-	data->overrun = 0;
-	data->trace_head = data->trace_tail = head_page(data);
-	data->trace_head_idx = 0;
-	data->trace_tail_idx = 0;
+	ring_buffer_reset_cpu(tr->buffer, cpu);
 }
 
 #define SAVED_CMDLINES 128
@@ -745,70 +482,6 @@ void tracing_record_cmdline(struct task_
 	trace_save_cmdline(tsk);
 }
 
-static inline struct list_head *
-trace_next_list(struct trace_array_cpu *data, struct list_head *next)
-{
-	/*
-	 * Roundrobin - but skip the head (which is not a real page):
-	 */
-	next = next->next;
-	if (unlikely(next == &data->trace_pages))
-		next = next->next;
-	BUG_ON(next == &data->trace_pages);
-
-	return next;
-}
-
-static inline void *
-trace_next_page(struct trace_array_cpu *data, void *addr)
-{
-	struct list_head *next;
-	struct page *page;
-
-	page = virt_to_page(addr);
-
-	next = trace_next_list(data, &page->lru);
-	page = list_entry(next, struct page, lru);
-
-	return page_address(page);
-}
-
-static inline struct trace_entry *
-tracing_get_trace_entry(struct trace_array *tr, struct trace_array_cpu *data)
-{
-	unsigned long idx, idx_next;
-	struct trace_entry *entry;
-
-	data->trace_idx++;
-	idx = data->trace_head_idx;
-	idx_next = idx + 1;
-
-	BUG_ON(idx * TRACE_ENTRY_SIZE >= PAGE_SIZE);
-
-	entry = data->trace_head + idx * TRACE_ENTRY_SIZE;
-
-	if (unlikely(idx_next >= ENTRIES_PER_PAGE)) {
-		data->trace_head = trace_next_page(data, data->trace_head);
-		idx_next = 0;
-	}
-
-	if (data->trace_head == data->trace_tail &&
-	    idx_next == data->trace_tail_idx) {
-		/* overrun */
-		data->overrun++;
-		data->trace_tail_idx++;
-		if (data->trace_tail_idx >= ENTRIES_PER_PAGE) {
-			data->trace_tail =
-				trace_next_page(data, data->trace_tail);
-			data->trace_tail_idx = 0;
-		}
-	}
-
-	data->trace_head_idx = idx_next;
-
-	return entry;
-}
-
 static inline void
 tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags)
 {
@@ -819,7 +492,6 @@ tracing_generic_entry_update(struct trac
 
 	entry->preempt_count	= pc & 0xff;
 	entry->pid		= (tsk) ? tsk->pid : 0;
-	entry->t		= ftrace_now(raw_smp_processor_id());
 	entry->flags = (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) |
 		((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) |
 		((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) |
@@ -830,18 +502,17 @@ void
 trace_function(struct trace_array *tr, struct trace_array_cpu *data,
 	       unsigned long ip, unsigned long parent_ip, unsigned long flags)
 {
-	struct trace_entry *entry;
+	struct ftrace_entry *entry;
 	unsigned long irq_flags;
 
-	raw_local_irq_save(irq_flags);
-	__raw_spin_lock(&data->lock);
-	entry			= tracing_get_trace_entry(tr, data);
-	tracing_generic_entry_update(entry, flags);
-	entry->type		= TRACE_FN;
-	entry->fn.ip		= ip;
-	entry->fn.parent_ip	= parent_ip;
-	__raw_spin_unlock(&data->lock);
-	raw_local_irq_restore(irq_flags);
+	entry = ring_buffer_lock_reserve(tr->buffer, TRACE_FN, sizeof(*entry),
+					 &irq_flags);
+	if (!entry)
+		return;
+	tracing_generic_entry_update(&entry->ent, flags);
+	entry->ip		= ip;
+	entry->parent_ip	= parent_ip;
+	ring_buffer_unlock_commit(tr->buffer, entry, irq_flags);
 }
 
 void
@@ -856,19 +527,16 @@ ftrace(struct trace_array *tr, struct tr
 void __trace_mmiotrace_rw(struct trace_array *tr, struct trace_array_cpu *data,
 						struct mmiotrace_rw *rw)
 {
-	struct trace_entry *entry;
+	struct mmiotrace_rw *entry;
 	unsigned long irq_flags;
 
-	raw_local_irq_save(irq_flags);
-	__raw_spin_lock(&data->lock);
-
-	entry			= tracing_get_trace_entry(tr, data);
-	tracing_generic_entry_update(entry, 0);
-	entry->type		= TRACE_MMIO_RW;
-	entry->mmiorw		= *rw;
-
-	__raw_spin_unlock(&data->lock);
-	raw_local_irq_restore(irq_flags);
+	entry = ring_buffer_lock_reserve(tr->buffer, TRACE_MMIO_RW,
+					 sizeof(*entry), &irq_flags);
+	if (!entry)
+		return;
+	tracing_generic_entry_update(&entry->ent, 0);
+	*entry			= *rw;
+	ring_buffer_unlock_commit(tr->buffer, entry, irq_flags);
 
 	trace_wake_up();
 }
@@ -876,19 +544,16 @@ void __trace_mmiotrace_rw(struct trace_a
 void __trace_mmiotrace_map(struct trace_array *tr, struct trace_array_cpu *data,
 						struct mmiotrace_map *map)
 {
-	struct trace_entry *entry;
+	struct mmiotrace_map *entry;
 	unsigned long irq_flags;
 
-	raw_local_irq_save(irq_flags);
-	__raw_spin_lock(&data->lock);
-
-	entry			= tracing_get_trace_entry(tr, data);
-	tracing_generic_entry_update(entry, 0);
-	entry->type		= TRACE_MMIO_MAP;
-	entry->mmiomap		= *map;
-
-	__raw_spin_unlock(&data->lock);
-	raw_local_irq_restore(irq_flags);
+	entry = ring_buffer_lock_reserve(tr->buffer, TRACE_MMIO_MAP,
+					 sizeof(*entry), &irq_flags);
+	if (!entry)
+		return;
+	tracing_generic_entry_update(&entry->ent, 0);
+	*entry			= *map;
+	ring_buffer_unlock_commit(tr->buffer, entry, irq_flags);
 
 	trace_wake_up();
 }
@@ -899,24 +564,28 @@ void __trace_stack(struct trace_array *t
 		   unsigned long flags,
 		   int skip)
 {
-	struct trace_entry *entry;
+	struct stack_entry *entry;
 	struct stack_trace trace;
+	unsigned long irq_flags;
 
 	if (!(trace_flags & TRACE_ITER_STACKTRACE))
 		return;
 
-	entry			= tracing_get_trace_entry(tr, data);
-	tracing_generic_entry_update(entry, flags);
-	entry->type		= TRACE_STACK;
+	entry = ring_buffer_lock_reserve(tr->buffer, FTRACE_STACK_ENTRIES,
+					 sizeof(*entry), &irq_flags);
+	if (!entry)
+		return;
+	tracing_generic_entry_update(&entry->ent, flags);
 
-	memset(&entry->stack, 0, sizeof(entry->stack));
+	memset(&entry->caller, 0, sizeof(entry->caller));
 
 	trace.nr_entries	= 0;
 	trace.max_entries	= FTRACE_STACK_ENTRIES;
 	trace.skip		= skip;
-	trace.entries		= entry->stack.caller;
+	trace.entries		= entry->caller;
 
 	save_stack_trace(&trace);
+	ring_buffer_unlock_commit(tr->buffer, entry, irq_flags);
 }
 
 void
@@ -925,20 +594,19 @@ __trace_special(void *__tr, void *__data
 {
 	struct trace_array_cpu *data = __data;
 	struct trace_array *tr = __tr;
-	struct trace_entry *entry;
+	struct special_entry *entry;
 	unsigned long irq_flags;
 
-	raw_local_irq_save(irq_flags);
-	__raw_spin_lock(&data->lock);
-	entry			= tracing_get_trace_entry(tr, data);
-	tracing_generic_entry_update(entry, 0);
-	entry->type		= TRACE_SPECIAL;
-	entry->special.arg1	= arg1;
-	entry->special.arg2	= arg2;
-	entry->special.arg3	= arg3;
+	entry = ring_buffer_lock_reserve(tr->buffer, TRACE_SPECIAL,
+					 sizeof(*entry), &irq_flags);
+	if (!entry)
+		return;
+	tracing_generic_entry_update(&entry->ent, 0);
+	entry->arg1	= arg1;
+	entry->arg2	= arg2;
+	entry->arg3	= arg3;
+	ring_buffer_unlock_commit(tr->buffer, entry, irq_flags);
 	__trace_stack(tr, data, irq_flags, 4);
-	__raw_spin_unlock(&data->lock);
-	raw_local_irq_restore(irq_flags);
 
 	trace_wake_up();
 }
@@ -950,23 +618,22 @@ tracing_sched_switch_trace(struct trace_
 			   struct task_struct *next,
 			   unsigned long flags)
 {
-	struct trace_entry *entry;
+	struct ctx_switch_entry *entry;
 	unsigned long irq_flags;
 
-	raw_local_irq_save(irq_flags);
-	__raw_spin_lock(&data->lock);
-	entry			= tracing_get_trace_entry(tr, data);
-	tracing_generic_entry_update(entry, flags);
-	entry->type		= TRACE_CTX;
-	entry->ctx.prev_pid	= prev->pid;
-	entry->ctx.prev_prio	= prev->prio;
-	entry->ctx.prev_state	= prev->state;
-	entry->ctx.next_pid	= next->pid;
-	entry->ctx.next_prio	= next->prio;
-	entry->ctx.next_state	= next->state;
+	entry = ring_buffer_lock_reserve(tr->buffer, TRACE_CTX,
+					 sizeof(*entry), &irq_flags);
+	if (!entry)
+		return;
+	tracing_generic_entry_update(&entry->ent, flags);
+	entry->prev_pid		= prev->pid;
+	entry->prev_prio	= prev->prio;
+	entry->prev_state	= prev->state;
+	entry->next_pid		= next->pid;
+	entry->next_prio	= next->prio;
+	entry->next_state	= next->state;
+	ring_buffer_unlock_commit(tr->buffer, entry, irq_flags);
 	__trace_stack(tr, data, flags, 5);
-	__raw_spin_unlock(&data->lock);
-	raw_local_irq_restore(irq_flags);
 }
 
 void
@@ -976,23 +643,22 @@ tracing_sched_wakeup_trace(struct trace_
 			   struct task_struct *curr,
 			   unsigned long flags)
 {
-	struct trace_entry *entry;
+	struct ctx_switch_entry *entry;
 	unsigned long irq_flags;
 
-	raw_local_irq_save(irq_flags);
-	__raw_spin_lock(&data->lock);
-	entry			= tracing_get_trace_entry(tr, data);
-	tracing_generic_entry_update(entry, flags);
-	entry->type		= TRACE_WAKE;
-	entry->ctx.prev_pid	= curr->pid;
-	entry->ctx.prev_prio	= curr->prio;
-	entry->ctx.prev_state	= curr->state;
-	entry->ctx.next_pid	= wakee->pid;
-	entry->ctx.next_prio	= wakee->prio;
-	entry->ctx.next_state	= wakee->state;
+	entry = ring_buffer_lock_reserve(tr->buffer, TRACE_WAKE,
+					 sizeof(*entry), &irq_flags);
+	if (!entry)
+		return;
+	tracing_generic_entry_update(&entry->ent, flags);
+	entry->prev_pid	= curr->pid;
+	entry->prev_prio	= curr->prio;
+	entry->prev_state	= curr->state;
+	entry->next_pid	= wakee->pid;
+	entry->next_prio	= wakee->prio;
+	entry->next_state	= wakee->state;
+	ring_buffer_unlock_commit(tr->buffer, entry, irq_flags);
 	__trace_stack(tr, data, flags, 6);
-	__raw_spin_unlock(&data->lock);
-	raw_local_irq_restore(irq_flags);
 
 	trace_wake_up();
 }
@@ -1070,112 +736,21 @@ void tracing_stop_function_trace(void)
 #endif
 
 enum trace_file_type {
-	TRACE_FILE_LAT_FMT	= 1,
+	TRACE_FILE_LAT_FMT	= 1 << 0,
+	TRACE_FILE_USE_MAX	= 1 << 1,
 };
 
-static struct trace_entry *
-trace_entry_idx(struct trace_array *tr, struct trace_array_cpu *data,
-		struct trace_iterator *iter, int cpu)
-{
-	struct page *page;
-	struct trace_entry *array;
-
-	if (iter->next_idx[cpu] >= tr->entries ||
-	    iter->next_idx[cpu] >= data->trace_idx ||
-	    (data->trace_head == data->trace_tail &&
-	     data->trace_head_idx == data->trace_tail_idx))
-		return NULL;
-
-	if (!iter->next_page[cpu]) {
-		/* Initialize the iterator for this cpu trace buffer */
-		WARN_ON(!data->trace_tail);
-		page = virt_to_page(data->trace_tail);
-		iter->next_page[cpu] = &page->lru;
-		iter->next_page_idx[cpu] = data->trace_tail_idx;
-	}
-
-	page = list_entry(iter->next_page[cpu], struct page, lru);
-	BUG_ON(&data->trace_pages == &page->lru);
-
-	array = page_address(page);
-
-	WARN_ON(iter->next_page_idx[cpu] >= ENTRIES_PER_PAGE);
-	return &array[iter->next_page_idx[cpu]];
-}
-
-static struct trace_entry *
-find_next_entry(struct trace_iterator *iter, int *ent_cpu)
-{
-	struct trace_array *tr = iter->tr;
-	struct trace_entry *ent, *next = NULL;
-	int next_cpu = -1;
-	int cpu;
-
-	for_each_tracing_cpu(cpu) {
-		if (!head_page(tr->data[cpu]))
-			continue;
-		ent = trace_entry_idx(tr, tr->data[cpu], iter, cpu);
-		/*
-		 * Pick the entry with the smallest timestamp:
-		 */
-		if (ent && (!next || ent->t < next->t)) {
-			next = ent;
-			next_cpu = cpu;
-		}
-	}
-
-	if (ent_cpu)
-		*ent_cpu = next_cpu;
-
-	return next;
-}
-
-static void trace_iterator_increment(struct trace_iterator *iter)
-{
-	iter->idx++;
-	iter->next_idx[iter->cpu]++;
-	iter->next_page_idx[iter->cpu]++;
-
-	if (iter->next_page_idx[iter->cpu] >= ENTRIES_PER_PAGE) {
-		struct trace_array_cpu *data = iter->tr->data[iter->cpu];
-
-		iter->next_page_idx[iter->cpu] = 0;
-		iter->next_page[iter->cpu] =
-			trace_next_list(data, iter->next_page[iter->cpu]);
-	}
-}
-
-static void trace_consume(struct trace_iterator *iter)
-{
-	struct trace_array_cpu *data = iter->tr->data[iter->cpu];
-
-	data->trace_tail_idx++;
-	if (data->trace_tail_idx >= ENTRIES_PER_PAGE) {
-		data->trace_tail = trace_next_page(data, data->trace_tail);
-		data->trace_tail_idx = 0;
-	}
-
-	/* Check if we empty it, then reset the index */
-	if (data->trace_head == data->trace_tail &&
-	    data->trace_head_idx == data->trace_tail_idx)
-		data->trace_idx = 0;
-}
-
 static void *find_next_entry_inc(struct trace_iterator *iter)
 {
-	struct trace_entry *next;
+	struct ring_buffer_event *next;
 	int next_cpu = -1;
 
-	next = find_next_entry(iter, &next_cpu);
-
-	iter->prev_ent = iter->ent;
-	iter->prev_cpu = iter->cpu;
-
-	iter->ent = next;
+	next = ring_buffer_read(iter->buffer_iter, &next_cpu);
+	iter->event = next;
 	iter->cpu = next_cpu;
 
 	if (next)
-		trace_iterator_increment(iter);
+		iter->idx++;
 
 	return next ? iter : NULL;
 }
@@ -1210,7 +785,6 @@ static void *s_start(struct seq_file *m,
 	struct trace_iterator *iter = m->private;
 	void *p = NULL;
 	loff_t l = 0;
-	int i;
 
 	mutex_lock(&trace_types_lock);
 
@@ -1226,16 +800,9 @@ static void *s_start(struct seq_file *m,
 		current_trace->start(iter);
 
 	if (*pos != iter->pos) {
-		iter->ent = NULL;
+		iter->event = NULL;
 		iter->cpu = 0;
 		iter->idx = -1;
-		iter->prev_ent = NULL;
-		iter->prev_cpu = -1;
-
-		for_each_tracing_cpu(i) {
-			iter->next_idx[i] = 0;
-			iter->next_page[i] = NULL;
-		}
 
 		for (p = iter; p && l < *pos; p = s_next(m, p, &l))
 			;
@@ -1276,27 +843,27 @@ static inline int kretprobed(unsigned lo
 #endif /* CONFIG_KRETPROBES */
 
 static int
-seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address)
+seq_print_sym_short(struct ring_buffer_seq *s, const char *fmt, unsigned long address)
 {
 #ifdef CONFIG_KALLSYMS
 	char str[KSYM_SYMBOL_LEN];
 
 	kallsyms_lookup(address, NULL, NULL, NULL, str);
 
-	return trace_seq_printf(s, fmt, str);
+	return ring_buffer_seq_printf(s, fmt, str);
 #endif
 	return 1;
 }
 
 static int
-seq_print_sym_offset(struct trace_seq *s, const char *fmt,
+seq_print_sym_offset(struct ring_buffer_seq *s, const char *fmt,
 		     unsigned long address)
 {
 #ifdef CONFIG_KALLSYMS
 	char str[KSYM_SYMBOL_LEN];
 
 	sprint_symbol(str, address);
-	return trace_seq_printf(s, fmt, str);
+	return ring_buffer_seq_printf(s, fmt, str);
 #endif
 	return 1;
 }
@@ -1308,12 +875,12 @@ seq_print_sym_offset(struct trace_seq *s
 #endif
 
 static int
-seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
+seq_print_ip_sym(struct ring_buffer_seq *s, unsigned long ip, unsigned long sym_flags)
 {
 	int ret;
 
 	if (!ip)
-		return trace_seq_printf(s, "0");
+		return ring_buffer_seq_printf(s, "0");
 
 	if (sym_flags & TRACE_ITER_SYM_OFFSET)
 		ret = seq_print_sym_offset(s, "%s", ip);
@@ -1324,7 +891,7 @@ seq_print_ip_sym(struct trace_seq *s, un
 		return 0;
 
 	if (sym_flags & TRACE_ITER_SYM_ADDR)
-		ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
+		ret = ring_buffer_seq_printf(s, " <" IP_FMT ">", ip);
 	return ret;
 }
 
@@ -1357,21 +924,12 @@ print_trace_header(struct seq_file *m, s
 	struct tracer *type = current_trace;
 	unsigned long total   = 0;
 	unsigned long entries = 0;
-	int cpu;
 	const char *name = "preemption";
 
 	if (type)
 		name = type->name;
 
-	for_each_tracing_cpu(cpu) {
-		if (head_page(tr->data[cpu])) {
-			total += tr->data[cpu]->trace_idx;
-			if (tr->data[cpu]->trace_idx > tr->entries)
-				entries += tr->entries;
-			else
-				entries += tr->data[cpu]->trace_idx;
-		}
-	}
+	entries = ring_buffer_entries(iter->tr->buffer);
 
 	seq_printf(m, "%s latency trace v1.1.5 on %s\n",
 		   name, UTS_RELEASE);
@@ -1379,7 +937,7 @@ print_trace_header(struct seq_file *m, s
 		 "---------------------------------\n");
 	seq_printf(m, " latency: %lu us, #%lu/%lu, CPU#%d |"
 		   " (M:%s VP:%d, KP:%d, SP:%d HP:%d",
-		   nsecs_to_usecs(data->saved_latency),
+		   nsecs_to_usecs(tr->saved_latency),
 		   entries,
 		   total,
 		   tr->cpu,
@@ -1402,17 +960,17 @@ print_trace_header(struct seq_file *m, s
 	seq_puts(m, "    -----------------\n");
 	seq_printf(m, "    | task: %.16s-%d "
 		   "(uid:%d nice:%ld policy:%ld rt_prio:%ld)\n",
-		   data->comm, data->pid, data->uid, data->nice,
-		   data->policy, data->rt_priority);
+		   tr->comm, tr->pid, tr->uid, tr->nice,
+		   tr->policy, tr->rt_priority);
 	seq_puts(m, "    -----------------\n");
 
 	if (data->critical_start) {
 		seq_puts(m, " => started at: ");
-		seq_print_ip_sym(&iter->seq, data->critical_start, sym_flags);
-		trace_print_seq(m, &iter->seq);
+		seq_print_ip_sym(iter->seq, data->critical_start, sym_flags);
+		ring_buffer_seq_to_seqfile(m, iter->seq);
 		seq_puts(m, "\n => ended at:   ");
-		seq_print_ip_sym(&iter->seq, data->critical_end, sym_flags);
-		trace_print_seq(m, &iter->seq);
+		seq_print_ip_sym(iter->seq, data->critical_end, sym_flags);
+		ring_buffer_seq_to_seqfile(m, iter->seq);
 		seq_puts(m, "\n");
 	}
 
@@ -1420,71 +978,71 @@ print_trace_header(struct seq_file *m, s
 }
 
 static void
-lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
+lat_print_generic(struct ring_buffer_seq *s, struct trace_entry *entry, int cpu)
 {
 	int hardirq, softirq;
 	char *comm;
 
 	comm = trace_find_cmdline(entry->pid);
 
-	trace_seq_printf(s, "%8.8s-%-5d ", comm, entry->pid);
-	trace_seq_printf(s, "%d", cpu);
-	trace_seq_printf(s, "%c%c",
+	ring_buffer_seq_printf(s, "%8.8s-%-5d ", comm, entry->pid);
+	ring_buffer_seq_printf(s, "%d", cpu);
+	ring_buffer_seq_printf(s, "%c%c",
 			(entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' : '.',
 			((entry->flags & TRACE_FLAG_NEED_RESCHED) ? 'N' : '.'));
 
 	hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
 	softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
 	if (hardirq && softirq) {
-		trace_seq_putc(s, 'H');
+		ring_buffer_seq_putc(s, 'H');
 	} else {
 		if (hardirq) {
-			trace_seq_putc(s, 'h');
+			ring_buffer_seq_putc(s, 'h');
 		} else {
 			if (softirq)
-				trace_seq_putc(s, 's');
+				ring_buffer_seq_putc(s, 's');
 			else
-				trace_seq_putc(s, '.');
+				ring_buffer_seq_putc(s, '.');
 		}
 	}
 
 	if (entry->preempt_count)
-		trace_seq_printf(s, "%x", entry->preempt_count);
+		ring_buffer_seq_printf(s, "%x", entry->preempt_count);
 	else
-		trace_seq_puts(s, ".");
+		ring_buffer_seq_puts(s, ".");
 }
 
 unsigned long preempt_mark_thresh = 100;
 
 static void
-lat_print_timestamp(struct trace_seq *s, unsigned long long abs_usecs,
+lat_print_timestamp(struct ring_buffer_seq *s, unsigned long long abs_usecs,
 		    unsigned long rel_usecs)
 {
-	trace_seq_printf(s, " %4lldus", abs_usecs);
+	ring_buffer_seq_printf(s, " %4lldus", abs_usecs);
 	if (rel_usecs > preempt_mark_thresh)
-		trace_seq_puts(s, "!: ");
+		ring_buffer_seq_puts(s, "!: ");
 	else if (rel_usecs > 1)
-		trace_seq_puts(s, "+: ");
+		ring_buffer_seq_puts(s, "+: ");
 	else
-		trace_seq_puts(s, " : ");
+		ring_buffer_seq_puts(s, " : ");
 }
 
 static const char state_to_char[] = TASK_STATE_TO_CHAR_STR;
 
 #define SEQ_PUT_FIELD_RET(s, x)				\
 do {							\
-	if (!trace_seq_putmem(s, &(x), sizeof(x)))	\
+	if (!ring_buffer_seq_putmem(s, &(x), sizeof(x)))	\
 		return 0;				\
 } while (0)
 
 #define SEQ_PUT_HEX_FIELD_RET(s, x)			\
 do {							\
-	if (!trace_seq_putmem_hex(s, &(x), sizeof(x)))	\
+	if (!ring_buffer_seq_putmem_hex(s, &(x), sizeof(x)))	\
 		return 0;				\
 } while (0)
 
 static int
-trace_print_func(struct trace_seq *s, struct ftrace_entry *entry,
+trace_print_func(struct ring_buffer_seq *s, struct ftrace_entry *entry,
 		 int sym_flags, int print_type)
 {
 	int ret = 1;
@@ -1499,17 +1057,17 @@ trace_print_func(struct trace_seq *s, st
 		SEQ_PUT_HEX_FIELD_RET(s, entry->parent_ip);
 		break;
 	case TRACE_ITER_RAW:
-		ret = trace_seq_printf(s, "%x %x\n",
+		ret = ring_buffer_seq_printf(s, "%lx %lx\n",
 					entry->ip, entry->parent_ip);
 		break;
 	case TRACE_FILE_LAT_FMT:
 		seq_print_ip_sym(s, entry->ip, sym_flags);
-		trace_seq_puts(s, " (");
+		ring_buffer_seq_puts(s, " (");
 		if (kretprobed(entry->parent_ip))
-			trace_seq_puts(s, KRETPROBE_MSG);
+			ring_buffer_seq_puts(s, KRETPROBE_MSG);
 		else
 			seq_print_ip_sym(s, entry->parent_ip, sym_flags);
-		trace_seq_puts(s, ")\n");
+		ring_buffer_seq_puts(s, ")\n");
 		break;
 	default:
 		ret = seq_print_ip_sym(s, entry->ip, sym_flags);
@@ -1517,25 +1075,25 @@ trace_print_func(struct trace_seq *s, st
 			return 0;
 		if ((sym_flags & TRACE_ITER_PRINT_PARENT) &&
 					entry->parent_ip) {
-			ret = trace_seq_printf(s, " <-");
+			ret = ring_buffer_seq_printf(s, " <-");
 			if (!ret)
 				return 0;
 			if (kretprobed(entry->parent_ip))
-				ret = trace_seq_puts(s, KRETPROBE_MSG);
+				ret = ring_buffer_seq_puts(s, KRETPROBE_MSG);
 			else
 				ret = seq_print_ip_sym(s, entry->parent_ip,
 						       sym_flags);
 			if (!ret)
 				return 0;
 		}
-		ret = trace_seq_printf(s, "\n");
+		ret = ring_buffer_seq_printf(s, "\n");
 	}
 
 	return ret;
 }
 
 static int
-trace_print_ctx(struct trace_seq *s, struct ctx_switch_entry *entry,
+trace_print_ctx(struct ring_buffer_seq *s, struct ctx_switch_entry *entry,
 		int type, int print_type)
 {
 	unsigned state;
@@ -1571,7 +1129,7 @@ trace_print_ctx(struct trace_seq *s, str
 	case TRACE_ITER_RAW:
 		if (type == TRACE_WAKE)
 			S = '+';
-		ret = trace_seq_printf(s, "%d %d %c %d %d %c\n",
+		ret = ring_buffer_seq_printf(s, "%d %d %c %d %d %c\n",
 				       entry->prev_pid,
 				       entry->prev_prio,
 				       S,
@@ -1581,7 +1139,7 @@ trace_print_ctx(struct trace_seq *s, str
 		break;
 	default:
 		comm = trace_find_cmdline(entry->next_pid);
-		ret = trace_seq_printf(s, " %5d:%3d:%c %s %5d:%3d:%c %s\n",
+		ret = ring_buffer_seq_printf(s, " %5d:%3d:%c %s %5d:%3d:%c %s\n",
 				       entry->prev_pid,
 				       entry->prev_prio,
 				       S, type == TRACE_CTX ? "==>" : "  +",
@@ -1594,7 +1152,7 @@ trace_print_ctx(struct trace_seq *s, str
 }
 
 static int
-trace_print_special(struct trace_seq *s, struct special_entry *entry,
+trace_print_special(struct ring_buffer_seq *s, struct special_entry *entry,
 			    int print_type)
 {
 	int ret = 0;
@@ -1612,7 +1170,7 @@ trace_print_special(struct trace_seq *s,
 		break;
 	case TRACE_ITER_RAW:
 	default:
-		ret = trace_seq_printf(s, "# %ld %ld %ld\n",
+		ret = ring_buffer_seq_printf(s, "# %ld %ld %ld\n",
 				       entry->arg1,
 				       entry->arg2,
 				       entry->arg3);
@@ -1621,7 +1179,7 @@ trace_print_special(struct trace_seq *s,
 }
 
 static int
-trace_print_stack(struct trace_seq *s, struct stack_entry *entry, int sym_flags,
+trace_print_stack(struct ring_buffer_seq *s, struct stack_entry *entry, int sym_flags,
 		  int print_type)
 {
 	int i;
@@ -1634,7 +1192,7 @@ trace_print_stack(struct trace_seq *s, s
 	default:
 		for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
 			if (i) {
-				ret = trace_seq_puts(s, " <= ");
+				ret = ring_buffer_seq_puts(s, " <= ");
 				if (!ret)
 					return 0;
 			}
@@ -1643,7 +1201,7 @@ trace_print_stack(struct trace_seq *s, s
 			if (!ret)
 				return 0;
 		}
-		ret = trace_seq_puts(s, "\n");
+		ret = ring_buffer_seq_puts(s, "\n");
 	}
 
 	return ret;
@@ -1652,29 +1210,35 @@ trace_print_stack(struct trace_seq *s, s
 static int
 print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu)
 {
-	struct trace_seq *s = &iter->seq;
+	struct ring_buffer_seq *s = iter->seq;
 	unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
-	struct trace_entry *next_entry = find_next_entry(iter, NULL);
+	struct ring_buffer_event *next_event = ring_buffer_peek(iter->buffer_iter, NULL);
 	unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE);
-	struct trace_entry *entry = iter->ent;
+	struct trace_entry *entry = ring_buffer_event_data(iter->event);
+	unsigned long long ns1, ns2;
 	unsigned long abs_usecs;
 	unsigned long rel_usecs;
 	char *comm;
 	int print_type = TRACE_FILE_LAT_FMT;
+	int type;
+
+	if (!next_event)
+		next_event = iter->event;
+	ns1 = ring_buffer_event_counter(iter->event);
+	ns2 = ring_buffer_event_counter(next_event);
+	rel_usecs = ns2usecs(ns2 - ns1);
+	abs_usecs = ns2usecs(ns1 - iter->tr->time_start);
 
-	if (!next_entry)
-		next_entry = entry;
-	rel_usecs = ns2usecs(next_entry->t - entry->t);
-	abs_usecs = ns2usecs(entry->t - iter->tr->time_start);
+	type = ring_buffer_event_type(iter->event);
 
 	if (verbose) {
 		comm = trace_find_cmdline(entry->pid);
-		trace_seq_printf(s, "%16s %5d %d %d %08x %08x [%08lx]"
+		ring_buffer_seq_printf(s, "%16s %5d %d %d %08x %08x [%08lx]"
 				 " %ld.%03ldms (+%ld.%03ldms): ",
 				 comm,
 				 entry->pid, cpu, entry->flags,
 				 entry->preempt_count, trace_idx,
-				 ns2usecs(entry->t),
+				 ns2usecs(ns1),
 				 abs_usecs/1000,
 				 abs_usecs % 1000, rel_usecs/1000,
 				 rel_usecs % 1000);
@@ -1682,74 +1246,77 @@ print_lat_fmt(struct trace_iterator *ite
 		lat_print_generic(s, entry, cpu);
 		lat_print_timestamp(s, abs_usecs, rel_usecs);
 	}
-	switch (entry->type) {
+	switch (type) {
 	case TRACE_FN:
-		trace_print_func(s, &entry->fn, sym_flags, print_type);
+		trace_print_func(s, (struct ftrace_entry *)entry, sym_flags, print_type);
 		break;
 	case TRACE_CTX:
 	case TRACE_WAKE:
-		trace_print_ctx(s, &entry->ctx, entry->type, print_type);
+		trace_print_ctx(s, (struct ctx_switch_entry *)entry, type, print_type);
 		break;
 	case TRACE_SPECIAL:
-		trace_print_special(s, &entry->special, print_type);
+		trace_print_special(s, (struct special_entry *)entry, print_type);
 		break;
 	case TRACE_STACK:
-		trace_print_stack(s, &entry->stack, sym_flags, print_type);
+		trace_print_stack(s, (struct stack_entry *)entry, sym_flags, print_type);
 		break;
 	default:
-		trace_seq_printf(s, "Unknown type %d\n", entry->type);
+		ring_buffer_seq_printf(s, "Unknown type %d\n", type);
 	}
 	return 1;
 }
 
 static int print_trace_fmt(struct trace_iterator *iter)
 {
-	struct trace_seq *s = &iter->seq;
+	struct ring_buffer_seq *s = iter->seq;
 	unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
 	struct trace_entry *entry;
 	unsigned long usec_rem;
-	unsigned long long t;
+	unsigned long long t, ns;
 	unsigned long secs;
 	char *comm;
+	int type;
 	int ret;
 
-	entry = iter->ent;
+	entry = ring_buffer_event_data(iter->event);
+	type = ring_buffer_event_type(iter->event);
+	ns = ring_buffer_event_counter(iter->event);
 
-	comm = trace_find_cmdline(iter->ent->pid);
+	comm = trace_find_cmdline(entry->pid);
 
-	t = ns2usecs(entry->t);
+	t = ns2usecs(ns);
 	usec_rem = do_div(t, 1000000ULL);
 	secs = (unsigned long)t;
 
-	ret = trace_seq_printf(s, "%16s-%-5d ", comm, entry->pid);
+	ret = ring_buffer_seq_printf(s, "%16s-%-5d ", comm, entry->pid);
 	if (!ret)
 		return 0;
-	ret = trace_seq_printf(s, "[%02d] ", iter->cpu);
+	ret = ring_buffer_seq_printf(s, "[%02d] ", iter->cpu);
 	if (!ret)
 		return 0;
-	ret = trace_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem);
+	ret = ring_buffer_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem);
 	if (!ret)
 		return 0;
 
-	switch (entry->type) {
+	switch (type) {
 	case TRACE_FN:
-		ret = trace_print_func(s, &entry->fn, sym_flags, 0);
+		ret = trace_print_func(s, (struct ftrace_entry *)entry, sym_flags, 0);
 		if (!ret)
 			return 0;
 		break;
 	case TRACE_CTX:
 	case TRACE_WAKE:
-		ret = trace_print_ctx(s, &entry->ctx, entry->type, 0);
+ 		ret = trace_print_ctx(s, (struct ctx_switch_entry *)entry, type, 0);
 		if (!ret)
 			return 0;
 		break;
 	case TRACE_SPECIAL:
-		ret = trace_print_special(s, &entry->special, 0);
+		ret = trace_print_special(s, (struct special_entry *)entry, 0);
 		if (!ret)
 			return 0;
 		break;
 	case TRACE_STACK:
-		ret = trace_print_stack(s, &entry->stack, sym_flags, 0);
+		ret = trace_print_stack(s, (struct stack_entry *)entry, sym_flags, 0);
 		if (!ret)
 			return 0;
 		break;
@@ -1759,33 +1326,37 @@ static int print_trace_fmt(struct trace_
 
 static int print_raw_fmt(struct trace_iterator *iter)
 {
-	struct trace_seq *s = &iter->seq;
+	struct ring_buffer_seq *s = iter->seq;
 	struct trace_entry *entry;
+	unsigned long long t;
+	int type;
 	int print_type = TRACE_ITER_RAW;
 	int ret;
 
-	entry = iter->ent;
+	entry = ring_buffer_event_data(iter->event);
+	type = ring_buffer_event_type(iter->event);
+	t = ring_buffer_event_counter(iter->event);
 
-	ret = trace_seq_printf(s, "%d %d %llu ",
-		entry->pid, iter->cpu, entry->t);
+	ret = ring_buffer_seq_printf(s, "%d %d %llu ",
+		entry->pid, iter->cpu, t);
 	if (!ret)
 		return 0;
 
-	switch (entry->type) {
+	switch (type) {
 	case TRACE_FN:
-		ret = trace_print_func(s, &entry->fn, 0, print_type);
+		ret = trace_print_func(s, (struct ftrace_entry *)entry, 0, print_type);
 		if (!ret)
 			return 0;
 		break;
 	case TRACE_CTX:
 	case TRACE_WAKE:
-		ret = trace_print_ctx(s, &entry->ctx, entry->type, print_type);
+		ret = trace_print_ctx(s, (struct ctx_switch_entry *)entry, type, print_type);
 		if (!ret)
 			return 0;
 		break;
 	case TRACE_SPECIAL:
 	case TRACE_STACK:
-		ret = trace_print_special(s, &entry->special, print_type);
+		ret = trace_print_special(s, (struct special_entry *)entry, print_type);
 		if (!ret)
 			return 0;
 		break;
@@ -1795,28 +1366,32 @@ static int print_raw_fmt(struct trace_it
 
 static int print_hex_fmt(struct trace_iterator *iter)
 {
-	struct trace_seq *s = &iter->seq;
+	struct ring_buffer_seq *s = iter->seq;
 	unsigned char newline = '\n';
 	struct trace_entry *entry;
 	int print_type = TRACE_ITER_HEX;
+	unsigned long long t;
+	int type;
 
-	entry = iter->ent;
+	entry = ring_buffer_event_data(iter->event);
+	type = ring_buffer_event_type(iter->event);
+	t = ring_buffer_event_counter(iter->event);
 
 	SEQ_PUT_HEX_FIELD_RET(s, entry->pid);
 	SEQ_PUT_HEX_FIELD_RET(s, iter->cpu);
-	SEQ_PUT_HEX_FIELD_RET(s, entry->t);
+	SEQ_PUT_HEX_FIELD_RET(s, t);
 
-	switch (entry->type) {
+	switch (type) {
 	case TRACE_FN:
-		trace_print_func(s, &entry->fn, 0, print_type);
+		trace_print_func(s, (struct ftrace_entry *)entry, 0, print_type);
 		break;
 	case TRACE_CTX:
 	case TRACE_WAKE:
-		trace_print_ctx(s, &entry->ctx, entry->type, print_type);
+		trace_print_ctx(s, (struct ctx_switch_entry *)entry, type, print_type);
 		break;
 	case TRACE_SPECIAL:
 	case TRACE_STACK:
-		trace_print_special(s, &entry->special, print_type);
+		trace_print_special(s, (struct special_entry *)entry, print_type);
 		break;
 	}
 	SEQ_PUT_FIELD_RET(s, newline);
@@ -1826,26 +1401,30 @@ static int print_hex_fmt(struct trace_it
 
 static int print_bin_fmt(struct trace_iterator *iter)
 {
-	struct trace_seq *s = &iter->seq;
+	struct ring_buffer_seq *s = iter->seq;
 	struct trace_entry *entry;
 	int print_type = TRACE_ITER_BIN;
+	unsigned long long t;
+	int type;
 
-	entry = iter->ent;
+	entry = ring_buffer_event_data(iter->event);
+	type = ring_buffer_event_type(iter->event);
+	t = ring_buffer_event_counter(iter->event);
 
 	SEQ_PUT_FIELD_RET(s, entry->pid);
-	SEQ_PUT_FIELD_RET(s, entry->cpu);
-	SEQ_PUT_FIELD_RET(s, entry->t);
+	SEQ_PUT_FIELD_RET(s, iter->cpu);
+	SEQ_PUT_FIELD_RET(s, t);
 
-	switch (entry->type) {
+	switch (type) {
 	case TRACE_FN:
-		trace_print_func(s, &entry->fn, 0, print_type);
+		trace_print_func(s, (struct ftrace_entry *)entry, 0, print_type);
 		break;
 	case TRACE_CTX:
-		trace_print_ctx(s, &entry->ctx, entry->type, print_type);
+		trace_print_ctx(s, (struct ctx_switch_entry *)entry, type, print_type);
 		break;
 	case TRACE_SPECIAL:
 	case TRACE_STACK:
-		trace_print_special(s, &entry->special, print_type);
+		trace_print_special(s, (struct special_entry *)entry, print_type);
 		break;
 	}
 	return 1;
@@ -1853,18 +1432,7 @@ static int print_bin_fmt(struct trace_it
 
 static int trace_empty(struct trace_iterator *iter)
 {
-	struct trace_array_cpu *data;
-	int cpu;
-
-	for_each_tracing_cpu(cpu) {
-		data = iter->tr->data[cpu];
-
-		if (head_page(data) && data->trace_idx &&
-		    (data->trace_tail != data->trace_head ||
-		     data->trace_tail_idx != data->trace_head_idx))
-			return 0;
-	}
-	return 1;
+	return ring_buffer_empty(iter->tr->buffer);
 }
 
 static int print_trace_line(struct trace_iterator *iter)
@@ -1891,7 +1459,7 @@ static int s_show(struct seq_file *m, vo
 {
 	struct trace_iterator *iter = v;
 
-	if (iter->ent == NULL) {
+	if (iter->event == NULL) {
 		if (iter->tr) {
 			seq_printf(m, "# tracer: %s\n", iter->trace->name);
 			seq_puts(m, "#\n");
@@ -1909,7 +1477,7 @@ static int s_show(struct seq_file *m, vo
 		}
 	} else {
 		print_trace_line(iter);
-		trace_print_seq(m, &iter->seq);
+		ring_buffer_seq_to_seqfile(m, iter->seq);
 	}
 
 	return 0;
@@ -1926,6 +1494,7 @@ static struct trace_iterator *
 __tracing_open(struct inode *inode, struct file *file, int *ret)
 {
 	struct trace_iterator *iter;
+	unsigned buf_flags = 0;
 
 	if (tracing_disabled) {
 		*ret = -ENODEV;
@@ -1938,11 +1507,32 @@ __tracing_open(struct inode *inode, stru
 		goto out;
 	}
 
+
+
 	mutex_lock(&trace_types_lock);
-	if (current_trace && current_trace->print_max)
-		iter->tr = &max_tr;
-	else
-		iter->tr = inode->i_private;
+
+	iter->tr = inode->i_private;
+
+	if (current_trace && current_trace->print_max) {
+		iter->iter_flags |= TRACE_FILE_USE_MAX;
+		buf_flags = RB_ITER_FL_SNAP;
+	}
+
+	iter->buffer_iter = ring_buffer_start(iter->tr->buffer, buf_flags);
+	if (!iter->buffer_iter) {
+		kfree(iter);
+		iter = NULL;
+		goto out_unlock;
+	}
+
+	iter->seq = ring_buffer_seq_alloc(GFP_KERNEL);
+	if (!iter->seq) {
+		ring_buffer_finish(iter->buffer_iter);
+		kfree(iter);
+		iter = NULL;
+		goto out_unlock;
+	}
+
 	iter->trace = current_trace;
 	iter->pos = -1;
 
@@ -1964,6 +1554,7 @@ __tracing_open(struct inode *inode, stru
 		kfree(iter);
 		iter = NULL;
 	}
+ out_unlock:
 	mutex_unlock(&trace_types_lock);
 
  out:
@@ -1985,6 +1576,10 @@ int tracing_release(struct inode *inode,
 	struct trace_iterator *iter = m->private;
 
 	mutex_lock(&trace_types_lock);
+
+	ring_buffer_seq_free(iter->seq);
+	ring_buffer_finish(iter->buffer_iter);
+
 	if (iter->trace && iter->trace->close)
 		iter->trace->close(iter);
 
@@ -2491,6 +2086,7 @@ static atomic_t tracing_reader;
 static int tracing_open_pipe(struct inode *inode, struct file *filp)
 {
 	struct trace_iterator *iter;
+	int max_event_size;
 
 	if (tracing_disabled)
 		return -ENODEV;
@@ -2506,6 +2102,13 @@ static int tracing_open_pipe(struct inod
 	if (!iter)
 		return -ENOMEM;
 
+	max_event_size = ring_buffer_max_event_size(global_trace.buffer);
+	iter->last_event = kmalloc(max_event_size, GFP_KERNEL);
+	if (!iter->last_event) {
+		kfree(iter);
+		return -ENOMEM;
+	}
+
 	mutex_lock(&trace_types_lock);
 	iter->tr = &global_trace;
 	iter->trace = current_trace;
@@ -2522,6 +2125,7 @@ static int tracing_release_pipe(struct i
 {
 	struct trace_iterator *iter = file->private_data;
 
+	kfree(iter->last_event);
 	kfree(iter);
 	atomic_dec(&tracing_reader);
 
@@ -2557,22 +2161,30 @@ tracing_read_pipe(struct file *filp, cha
 		  size_t cnt, loff_t *ppos)
 {
 	struct trace_iterator *iter = filp->private_data;
-	struct trace_array_cpu *data;
-	static cpumask_t mask;
+	struct ring_buffer_event *event;
 	unsigned long flags;
 #ifdef CONFIG_FTRACE
 	int ftrace_save;
 #endif
-	int cpu;
+	static int save_event;
 	ssize_t sret;
 
 	/* return any leftover data */
-	sret = trace_seq_to_user(&iter->seq, ubuf, cnt);
+	sret = ring_buffer_seq_copy_to_user(iter->seq, ubuf, cnt);
 	if (sret != -EBUSY)
 		return sret;
 	sret = 0;
 
-	trace_seq_reset(&iter->seq);
+	ring_buffer_seq_reset(iter->seq);
+
+	/* Check to see if we over flowed the iterator */
+	if (save_event) {
+		iter->event = iter->last_event;
+		print_trace_line(iter);
+		save_event = 0;
+		sret = ring_buffer_seq_copy_to_user(iter->seq, ubuf, cnt);
+		return sret;
+	}
 
 	mutex_lock(&trace_types_lock);
 	if (iter->trace->read) {
@@ -2652,68 +2264,40 @@ tracing_read_pipe(struct file *filp, cha
 	 * and then release the locks again.
 	 */
 
-	cpus_clear(mask);
-	local_irq_save(flags);
 #ifdef CONFIG_FTRACE
 	ftrace_save = ftrace_enabled;
 	ftrace_enabled = 0;
 #endif
 	smp_wmb();
-	for_each_tracing_cpu(cpu) {
-		data = iter->tr->data[cpu];
-
-		if (!head_page(data) || !data->trace_idx)
-			continue;
+	ring_buffer_lock(iter->tr->buffer, &flags);
 
-		atomic_inc(&data->disabled);
-		cpu_set(cpu, mask);
-	}
-
-	for_each_cpu_mask(cpu, mask) {
-		data = iter->tr->data[cpu];
-		__raw_spin_lock(&data->lock);
-
-		if (data->overrun > iter->last_overrun[cpu])
-			iter->overrun[cpu] +=
-				data->overrun - iter->last_overrun[cpu];
-		iter->last_overrun[cpu] = data->overrun;
-	}
-
-	while (find_next_entry_inc(iter) != NULL) {
+	while ((event = ring_buffer_consume(iter->tr->buffer))) {
 		int ret;
-		int len = iter->seq.len;
+		int len = ring_buffer_seq_length(iter->seq);
 
+		iter->event = event;
 		ret = print_trace_line(iter);
 		if (!ret) {
 			/* don't print partial lines */
-			iter->seq.len = len;
+			ring_buffer_seq_set_length(iter->seq, len);
+			save_event = 1;
+			memcpy(iter->last_event, event,
+			       ring_buffer_event_length(event));
 			break;
 		}
 
-		trace_consume(iter);
-
-		if (iter->seq.len >= cnt)
+		len = ring_buffer_seq_length(iter->seq);
+		if (len >= cnt)
 			break;
 	}
 
-	for_each_cpu_mask(cpu, mask) {
-		data = iter->tr->data[cpu];
-		__raw_spin_unlock(&data->lock);
-	}
-
-	for_each_cpu_mask(cpu, mask) {
-		data = iter->tr->data[cpu];
-		atomic_dec(&data->disabled);
-	}
 #ifdef CONFIG_FTRACE
 	ftrace_enabled = ftrace_save;
 #endif
-	local_irq_restore(flags);
+	ring_buffer_unlock(iter->tr->buffer, flags);
 
 	/* Now copy what we have to the user */
-	sret = trace_seq_to_user(&iter->seq, ubuf, cnt);
-	if (iter->seq.readpos >= iter->seq.len)
-		trace_seq_reset(&iter->seq);
+	sret = ring_buffer_seq_copy_to_user(iter->seq, ubuf, cnt);
 	if (sret == -EBUSY)
 		sret = 0;
 
@@ -2731,17 +2315,28 @@ tracing_entries_read(struct file *filp, 
 	char buf[64];
 	int r;
 
-	r = sprintf(buf, "%lu\n", tr->entries);
+	r = sprintf(buf, "%lu\n", ring_buffer_size(tr->buffer));
 	return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
 }
 
+static void
+trace_default_print(struct ring_buffer *buffer,
+		    struct ring_buffer_seq *seq,
+		    struct ring_buffer_event *event)
+{
+	/* just some garbage for now */
+	ring_buffer_seq_printf(seq, "found %d\n",
+			       ring_buffer_event_type(event));
+}
+
 static ssize_t
 tracing_entries_write(struct file *filp, const char __user *ubuf,
 		      size_t cnt, loff_t *ppos)
 {
+	struct ring_buffer *buffer;
 	unsigned long val;
 	char buf[64];
-	int i, ret;
+	int ret;
 
 	if (cnt >= sizeof(buf))
 		return -EINVAL;
@@ -2768,59 +2363,28 @@ tracing_entries_write(struct file *filp,
 		goto out;
 	}
 
-	if (val > global_trace.entries) {
-		long pages_requested;
-		unsigned long freeable_pages;
-
-		/* make sure we have enough memory before mapping */
-		pages_requested =
-			(val + (ENTRIES_PER_PAGE-1)) / ENTRIES_PER_PAGE;
-
-		/* account for each buffer (and max_tr) */
-		pages_requested *= tracing_nr_buffers * 2;
-
-		/* Check for overflow */
-		if (pages_requested < 0) {
-			cnt = -ENOMEM;
-			goto out;
-		}
 
-		freeable_pages = determine_dirtyable_memory();
+	if (val == ring_buffer_size(global_trace.buffer))
+		goto out_same;
 
-		/* we only allow to request 1/4 of useable memory */
-		if (pages_requested >
-		    ((freeable_pages + tracing_pages_allocated) / 4)) {
-			cnt = -ENOMEM;
-			goto out;
-		}
-
-		while (global_trace.entries < val) {
-			if (trace_alloc_page()) {
-				cnt = -ENOMEM;
-				goto out;
-			}
-			/* double check that we don't go over the known pages */
-			if (tracing_pages_allocated > pages_requested)
-				break;
-		}
-
-	} else {
-		/* include the number of entries in val (inc of page entries) */
-		while (global_trace.entries > val + (ENTRIES_PER_PAGE - 1))
-			trace_free_page();
+	buffer = ring_buffer_alloc(val,
+				   TRACE_BUFFER_FLAGS, 0,
+				   trace_default_print,
+				   "ftrace_tmp");
+	if (!buffer) {
+		cnt = -ENOMEM;
+		goto out;
 	}
 
-	/* check integrity */
-	for_each_tracing_cpu(i)
-		check_pages(global_trace.data[i]);
+	ring_buffer_free(global_trace.buffer);
+	ring_buffer_rename(buffer, FTRACE_BUF_NAME);
 
+	global_trace.buffer = buffer;
+
+ out_same:
 	filp->f_pos += cnt;
 
-	/* If check pages failed, return ENOMEM */
-	if (tracing_disabled)
-		cnt = -ENOMEM;
  out:
-	max_tr.entries = global_trace.entries;
 	mutex_unlock(&trace_types_lock);
 
 	return cnt;
@@ -2883,17 +2447,23 @@ static struct dentry *d_tracer;
 struct dentry *tracing_init_dentry(void)
 {
 	static int once;
+	static DEFINE_MUTEX(mutex);
 
 	if (d_tracer)
 		return d_tracer;
 
+	mutex_lock(&mutex);
+	if (d_tracer)
+		goto out;
+
 	d_tracer = debugfs_create_dir("tracing", NULL);
 
 	if (!d_tracer && !once) {
 		once = 1;
 		pr_warning("Could not create debugfs directory 'tracing'\n");
-		return NULL;
 	}
+ out:
+	mutex_unlock(&mutex);
 
 	return d_tracer;
 }
@@ -2987,190 +2557,52 @@ static __init void tracer_init_debugfs(v
 #endif
 }
 
-static int trace_alloc_page(void)
+struct trace_array *
+trace_allocate_tracer(unsigned long size,
+		      unsigned long flags,
+		      unsigned long max_entry_size,
+		      ring_buffer_print_func print_func,
+		      char *name)
 {
-	struct trace_array_cpu *data;
-	struct page *page, *tmp;
-	LIST_HEAD(pages);
-	void *array;
-	unsigned pages_allocated = 0;
-	int i;
-
-	/* first allocate a page for each CPU */
-	for_each_tracing_cpu(i) {
-		array = (void *)__get_free_page(GFP_KERNEL);
-		if (array == NULL) {
-			printk(KERN_ERR "tracer: failed to allocate page"
-			       "for trace buffer!\n");
-			goto free_pages;
-		}
-
-		pages_allocated++;
-		page = virt_to_page(array);
-		list_add(&page->lru, &pages);
-
-/* Only allocate if we are actually using the max trace */
-#ifdef CONFIG_TRACER_MAX_TRACE
-		array = (void *)__get_free_page(GFP_KERNEL);
-		if (array == NULL) {
-			printk(KERN_ERR "tracer: failed to allocate page"
-			       "for trace buffer!\n");
-			goto free_pages;
-		}
-		pages_allocated++;
-		page = virt_to_page(array);
-		list_add(&page->lru, &pages);
-#endif
-	}
+	struct trace_array *tr;
 
-	/* Now that we successfully allocate a page per CPU, add them */
-	for_each_tracing_cpu(i) {
-		data = global_trace.data[i];
-		page = list_entry(pages.next, struct page, lru);
-		list_del_init(&page->lru);
-		list_add_tail(&page->lru, &data->trace_pages);
-		ClearPageLRU(page);
-
-#ifdef CONFIG_TRACER_MAX_TRACE
-		data = max_tr.data[i];
-		page = list_entry(pages.next, struct page, lru);
-		list_del_init(&page->lru);
-		list_add_tail(&page->lru, &data->trace_pages);
-		SetPageLRU(page);
-#endif
-	}
-	tracing_pages_allocated += pages_allocated;
-	global_trace.entries += ENTRIES_PER_PAGE;
+	tr = kzalloc(ALIGN(sizeof(*tr), cache_line_size()), GFP_KERNEL);
+	if (!tr)
+		return NULL;
 
-	return 0;
+	tr->buffer = ring_buffer_alloc(size, flags, max_entry_size,
+				       print_func, name);
 
- free_pages:
-	list_for_each_entry_safe(page, tmp, &pages, lru) {
-		list_del_init(&page->lru);
-		__free_page(page);
-	}
-	return -ENOMEM;
-}
+	if (!tr->buffer)
+		goto fail_free_trace;
 
-static int trace_free_page(void)
-{
-	struct trace_array_cpu *data;
-	struct page *page;
-	struct list_head *p;
-	int i;
-	int ret = 0;
+	tr->ctrl = tracer_enabled;
 
-	/* free one page from each buffer */
-	for_each_tracing_cpu(i) {
-		data = global_trace.data[i];
-		p = data->trace_pages.next;
-		if (p == &data->trace_pages) {
-			/* should never happen */
-			WARN_ON(1);
-			tracing_disabled = 1;
-			ret = -1;
-			break;
-		}
-		page = list_entry(p, struct page, lru);
-		ClearPageLRU(page);
-		list_del(&page->lru);
-		tracing_pages_allocated--;
-		tracing_pages_allocated--;
-		__free_page(page);
-
-		tracing_reset(data);
-
-#ifdef CONFIG_TRACER_MAX_TRACE
-		data = max_tr.data[i];
-		p = data->trace_pages.next;
-		if (p == &data->trace_pages) {
-			/* should never happen */
-			WARN_ON(1);
-			tracing_disabled = 1;
-			ret = -1;
-			break;
-		}
-		page = list_entry(p, struct page, lru);
-		ClearPageLRU(page);
-		list_del(&page->lru);
-		__free_page(page);
+	return tr;
 
-		tracing_reset(data);
-#endif
-	}
-	global_trace.entries -= ENTRIES_PER_PAGE;
-
-	return ret;
+ fail_free_trace:
+	kfree(tr);
+	return NULL;
 }
 
 __init static int tracer_alloc_buffers(void)
 {
-	struct trace_array_cpu *data;
-	void *array;
-	struct page *page;
-	int pages = 0;
-	int ret = -ENOMEM;
 	int i;
 
-	/* TODO: make the number of buffers hot pluggable with CPUS */
-	tracing_nr_buffers = num_possible_cpus();
 	tracing_buffer_mask = cpu_possible_map;
 
-	/* Allocate the first page for all buffers */
-	for_each_tracing_cpu(i) {
-		data = global_trace.data[i] = &per_cpu(global_trace_cpu, i);
-		max_tr.data[i] = &per_cpu(max_data, i);
-
-		array = (void *)__get_free_page(GFP_KERNEL);
-		if (array == NULL) {
-			printk(KERN_ERR "tracer: failed to allocate page"
-			       "for trace buffer!\n");
-			goto free_buffers;
-		}
-
-		/* set the array to the list */
-		INIT_LIST_HEAD(&data->trace_pages);
-		page = virt_to_page(array);
-		list_add(&page->lru, &data->trace_pages);
-		/* use the LRU flag to differentiate the two buffers */
-		ClearPageLRU(page);
-
-		data->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
-		max_tr.data[i]->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
-
-/* Only allocate if we are actually using the max trace */
-#ifdef CONFIG_TRACER_MAX_TRACE
-		array = (void *)__get_free_page(GFP_KERNEL);
-		if (array == NULL) {
-			printk(KERN_ERR "tracer: failed to allocate page"
-			       "for trace buffer!\n");
-			goto free_buffers;
-		}
-
-		INIT_LIST_HEAD(&max_tr.data[i]->trace_pages);
-		page = virt_to_page(array);
-		list_add(&page->lru, &max_tr.data[i]->trace_pages);
-		SetPageLRU(page);
-#endif
+	global_trace.buffer = ring_buffer_alloc(trace_buf_size,
+						TRACE_BUFFER_FLAGS, 0,
+						trace_default_print,
+						FTRACE_BUF_NAME);
+	if (!global_trace.buffer) {
+		printk(KERN_ERR "tracer: failed to allocate buffer\n");
+		return -ENOMEM;
 	}
 
-	/*
-	 * Since we allocate by orders of pages, we may be able to
-	 * round up a bit.
-	 */
-	global_trace.entries = ENTRIES_PER_PAGE;
-	pages++;
-
-	while (global_trace.entries < trace_nr_entries) {
-		if (trace_alloc_page())
-			break;
-		pages++;
-	}
-	max_tr.entries = global_trace.entries;
+	for_each_tracing_cpu(i)
+		global_trace.data[i] = &per_cpu(global_trace_cpu, i);
 
-	pr_info("tracer: %d pages allocated for %ld entries of %ld bytes\n",
-		pages, trace_nr_entries, (long)TRACE_ENTRY_SIZE);
-	pr_info("   actual entries %ld\n", global_trace.entries);
 
 	tracer_init_debugfs();
 
@@ -3184,31 +2616,5 @@ __init static int tracer_alloc_buffers(v
 	tracing_disabled = 0;
 
 	return 0;
-
- free_buffers:
-	for (i-- ; i >= 0; i--) {
-		struct page *page, *tmp;
-		struct trace_array_cpu *data = global_trace.data[i];
-
-		if (data) {
-			list_for_each_entry_safe(page, tmp,
-						 &data->trace_pages, lru) {
-				list_del_init(&page->lru);
-				__free_page(page);
-			}
-		}
-
-#ifdef CONFIG_TRACER_MAX_TRACE
-		data = max_tr.data[i];
-		if (data) {
-			list_for_each_entry_safe(page, tmp,
-						 &data->trace_pages, lru) {
-				list_del_init(&page->lru);
-				__free_page(page);
-			}
-		}
-#endif
-	}
-	return ret;
 }
 fs_initcall(tracer_alloc_buffers);
Index: linux-compile.git/kernel/trace/trace.h
===================================================================
--- linux-compile.git.orig/kernel/trace/trace.h	2008-09-23 23:33:29.000000000 -0400
+++ linux-compile.git/kernel/trace/trace.h	2008-09-23 23:34:46.000000000 -0400
@@ -6,6 +6,7 @@
 #include <linux/sched.h>
 #include <linux/clocksource.h>
 #include <linux/mmiotrace.h>
+#include <linux/ring_buffer.h>
 
 enum trace_type {
 	__TRACE_FIRST_TYPE = 0,
@@ -25,6 +26,7 @@ enum trace_type {
  * Function trace entry - function address and parent function addres:
  */
 struct ftrace_entry {
+	struct trace_entry	ent;
 	unsigned long		ip;
 	unsigned long		parent_ip;
 };
@@ -33,6 +35,7 @@ struct ftrace_entry {
  * Context switch trace entry - which task (and prio) we switched from/to:
  */
 struct ctx_switch_entry {
+	struct trace_entry	ent;
 	unsigned int		prev_pid;
 	unsigned char		prev_prio;
 	unsigned char		prev_state;
@@ -45,6 +48,7 @@ struct ctx_switch_entry {
  * Special (free-form) trace entry:
  */
 struct special_entry {
+	struct trace_entry	ent;
 	unsigned long		arg1;
 	unsigned long		arg2;
 	unsigned long		arg3;
@@ -57,63 +61,23 @@ struct special_entry {
 #define FTRACE_STACK_ENTRIES	8
 
 struct stack_entry {
+	struct trace_entry	ent;
 	unsigned long		caller[FTRACE_STACK_ENTRIES];
 };
 
 /*
- * The trace entry - the most basic unit of tracing. This is what
- * is printed in the end as a single line in the trace output, such as:
- *
- *     bash-15816 [01]   235.197585: idle_cpu <- irq_enter
- */
-struct trace_entry {
-	char			type;
-	char			cpu;
-	char			flags;
-	char			preempt_count;
-	int			pid;
-	cycle_t			t;
-	union {
-		struct ftrace_entry		fn;
-		struct ctx_switch_entry		ctx;
-		struct special_entry		special;
-		struct stack_entry		stack;
-		struct mmiotrace_rw		mmiorw;
-		struct mmiotrace_map		mmiomap;
-	};
-};
-
-#define TRACE_ENTRY_SIZE	sizeof(struct trace_entry)
-
-/*
  * The CPU trace array - it consists of thousands of trace entries
  * plus some other descriptor data: (for example which task started
  * the trace, etc.)
  */
 struct trace_array_cpu {
-	struct list_head	trace_pages;
 	atomic_t		disabled;
-	raw_spinlock_t		lock;
-	struct lock_class_key	lock_key;
 
 	/* these fields get copied into max-trace: */
-	unsigned		trace_head_idx;
-	unsigned		trace_tail_idx;
-	void			*trace_head; /* producer */
-	void			*trace_tail; /* consumer */
-	unsigned long		trace_idx;
-	unsigned long		overrun;
-	unsigned long		saved_latency;
 	unsigned long		critical_start;
 	unsigned long		critical_end;
 	unsigned long		critical_sequence;
-	unsigned long		nice;
-	unsigned long		policy;
-	unsigned long		rt_priority;
 	cycle_t			preempt_timestamp;
-	pid_t			pid;
-	uid_t			uid;
-	char			comm[TASK_COMM_LEN];
 };
 
 struct trace_iterator;
@@ -124,12 +88,20 @@ struct trace_iterator;
  * They have on/off state as well:
  */
 struct trace_array {
-	unsigned long		entries;
+	struct ring_buffer	*buffer;
 	long			ctrl;
 	int			cpu;
 	cycle_t			time_start;
 	struct task_struct	*waiter;
 	struct trace_array_cpu	*data[NR_CPUS];
+
+	unsigned long		saved_latency;
+	unsigned long		nice;
+	unsigned long		policy;
+	unsigned long		rt_priority;
+	pid_t			pid;
+	uid_t			uid;
+	char			comm[TASK_COMM_LEN];
 };
 
 /*
@@ -137,6 +109,7 @@ struct trace_array {
  */
 struct tracer {
 	const char		*name;
+	struct trace_array	*tr;
 	void			(*init)(struct trace_array *tr);
 	void			(*reset)(struct trace_array *tr);
 	void			(*open)(struct trace_iterator *iter);
@@ -157,12 +130,6 @@ struct tracer {
 	int			print_max;
 };
 
-struct trace_seq {
-	unsigned char		buffer[PAGE_SIZE];
-	unsigned int		len;
-	unsigned int		readpos;
-};
-
 /*
  * Trace iterator - used by printout routines who present trace
  * results to users and which routines might sleep, etc:
@@ -171,26 +138,21 @@ struct trace_iterator {
 	struct trace_array	*tr;
 	struct tracer		*trace;
 	void			*private;
-	long			last_overrun[NR_CPUS];
-	long			overrun[NR_CPUS];
 
 	/* The below is zeroed out in pipe_read */
-	struct trace_seq	seq;
-	struct trace_entry	*ent;
+	struct ring_buffer_seq	*seq;
 	int			cpu;
 
-	struct trace_entry	*prev_ent;
-	int			prev_cpu;
+	struct ring_buffer_event *event;
+	struct ring_buffer_event *last_event;
+	struct ring_buffer_iter	*buffer_iter;
 
 	unsigned long		iter_flags;
 	loff_t			pos;
-	unsigned long		next_idx[NR_CPUS];
-	struct list_head	*next_page[NR_CPUS];
-	unsigned		next_page_idx[NR_CPUS];
 	long			idx;
 };
 
-void tracing_reset(struct trace_array_cpu *data);
+void tracing_reset(struct trace_array *tr, int cpu);
 int tracing_open_generic(struct inode *inode, struct file *filp);
 struct dentry *tracing_init_dentry(void);
 void init_tracer_sysprof_debugfs(struct dentry *d_tracer);
@@ -227,6 +189,11 @@ void tracing_start_cmdline_record(void);
 void tracing_stop_cmdline_record(void);
 int register_tracer(struct tracer *type);
 void unregister_tracer(struct tracer *type);
+struct trace_array *trace_allocate_tracer(unsigned long size,
+					  unsigned long flags,
+					  unsigned long max_entry_size,
+					  ring_buffer_print_func print_func,
+					  char *name);
 
 extern unsigned long nsecs_to_usecs(unsigned long nsecs);
 
@@ -308,10 +275,6 @@ extern int trace_selftest_startup_syspro
 #endif
 #endif /* CONFIG_FTRACE_STARTUP_TEST */
 
-extern void *head_page(struct trace_array_cpu *data);
-extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...);
-extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
-				 size_t cnt);
 extern long ns2usecs(cycle_t nsec);
 
 extern unsigned long trace_flags;
Index: linux-compile.git/include/linux/ftrace.h
===================================================================
--- linux-compile.git.orig/include/linux/ftrace.h	2008-09-23 23:33:29.000000000 -0400
+++ linux-compile.git/include/linux/ftrace.h	2008-09-23 23:34:46.000000000 -0400
@@ -162,4 +162,10 @@ static inline void
 ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { }
 #endif
 
+struct trace_entry {
+	char			flags;
+	char			preempt_count;
+	int			pid;
+};
+
 #endif /* _LINUX_FTRACE_H */
Index: linux-compile.git/include/linux/mmiotrace.h
===================================================================
--- linux-compile.git.orig/include/linux/mmiotrace.h	2008-09-23 23:33:29.000000000 -0400
+++ linux-compile.git/include/linux/mmiotrace.h	2008-09-23 23:34:46.000000000 -0400
@@ -1,6 +1,7 @@
 #ifndef MMIOTRACE_H
 #define MMIOTRACE_H
 
+#include <linux/ftrace.h>
 #include <linux/types.h>
 #include <linux/list.h>
 
@@ -60,6 +61,7 @@ enum mm_io_opcode {
 };
 
 struct mmiotrace_rw {
+	struct trace_entry ent;
 	resource_size_t phys;	/* PCI address of register */
 	unsigned long value;
 	unsigned long pc;	/* optional program counter */
@@ -69,6 +71,7 @@ struct mmiotrace_rw {
 };
 
 struct mmiotrace_map {
+	struct trace_entry ent;
 	resource_size_t phys;	/* base address in PCI space */
 	unsigned long virt;	/* base virtual address */
 	unsigned long len;	/* mapping size */
Index: linux-compile.git/kernel/trace/trace_functions.c
===================================================================
--- linux-compile.git.orig/kernel/trace/trace_functions.c	2008-09-23 23:33:29.000000000 -0400
+++ linux-compile.git/kernel/trace/trace_functions.c	2008-09-23 23:34:46.000000000 -0400
@@ -23,7 +23,7 @@ static void function_reset(struct trace_
 	tr->time_start = ftrace_now(tr->cpu);
 
 	for_each_online_cpu(cpu)
-		tracing_reset(tr->data[cpu]);
+		tracing_reset(tr, cpu);
 }
 
 static void start_function_trace(struct trace_array *tr)
Index: linux-compile.git/kernel/trace/trace_irqsoff.c
===================================================================
--- linux-compile.git.orig/kernel/trace/trace_irqsoff.c	2008-09-23 23:33:29.000000000 -0400
+++ linux-compile.git/kernel/trace/trace_irqsoff.c	2008-09-23 23:34:46.000000000 -0400
@@ -20,6 +20,7 @@
 
 static struct trace_array		*irqsoff_trace __read_mostly;
 static int				tracer_enabled __read_mostly;
+static int				preemptirq_buffer_size = 10000;
 
 static DEFINE_PER_CPU(int, tracing_cpu);
 
@@ -173,7 +174,7 @@ out_unlock:
 out:
 	data->critical_sequence = max_sequence;
 	data->preempt_timestamp = ftrace_now(cpu);
-	tracing_reset(data);
+	tracing_reset(tr, cpu);
 	trace_function(tr, data, CALLER_ADDR0, parent_ip, flags);
 }
 
@@ -203,7 +204,7 @@ start_critical_timing(unsigned long ip, 
 	data->critical_sequence = max_sequence;
 	data->preempt_timestamp = ftrace_now(cpu);
 	data->critical_start = parent_ip ? : ip;
-	tracing_reset(data);
+	tracing_reset(tr, cpu);
 
 	local_save_flags(flags);
 
@@ -234,8 +235,7 @@ stop_critical_timing(unsigned long ip, u
 
 	data = tr->data[cpu];
 
-	if (unlikely(!data) || unlikely(!head_page(data)) ||
-	    !data->critical_start || atomic_read(&data->disabled))
+	if (unlikely(!data) || !data->critical_start || atomic_read(&data->disabled))
 		return;
 
 	atomic_inc(&data->disabled);
@@ -399,6 +399,13 @@ static void irqsoff_tracer_close(struct 
 		start_irqsoff_tracer(iter->tr);
 }
 
+static void
+register_preemptirq_tracer(struct tracer *trace, struct trace_array *tr)
+{
+	trace->tr = tr;
+	register_tracer(trace);
+}
+
 #ifdef CONFIG_IRQSOFF_TRACER
 static void irqsoff_tracer_init(struct trace_array *tr)
 {
@@ -419,7 +426,7 @@ static struct tracer irqsoff_tracer __re
 	.selftest    = trace_selftest_startup_irqsoff,
 #endif
 };
-# define register_irqsoff(trace) register_tracer(&trace)
+# define register_irqsoff(trace, tr) register_preemptirq_tracer(trace, tr)
 #else
 # define register_irqsoff(trace) do { } while (0)
 #endif
@@ -445,7 +452,7 @@ static struct tracer preemptoff_tracer _
 	.selftest    = trace_selftest_startup_preemptoff,
 #endif
 };
-# define register_preemptoff(trace) register_tracer(&trace)
+# define register_preemptoff(trace, tr) register_preemptirq_tracer(trace, tr)
 #else
 # define register_preemptoff(trace) do { } while (0)
 #endif
@@ -474,16 +481,25 @@ static struct tracer preemptirqsoff_trac
 #endif
 };
 
-# define register_preemptirqsoff(trace) register_tracer(&trace)
+# define register_preemptirqsoff(trace, tr) register_preemptirq_tracer(trace, tr)
 #else
-# define register_preemptirqsoff(trace) do { } while (0)
+# define register_preemptirqsoff(trace, tr) do { } while (0)
 #endif
 
 __init static int init_irqsoff_tracer(void)
 {
-	register_irqsoff(irqsoff_tracer);
-	register_preemptoff(preemptoff_tracer);
-	register_preemptirqsoff(preemptirqsoff_tracer);
+	struct trace_array *tr = NULL;
+#if 0
+	tr = trace_allocate_tracer(preemptirq_buffer_size,
+				   RB_FL_SNAPSHOT | RB_FL_OVERWRITE, 0,
+				   NULL, "preemptirqs");
+	if (!tr)
+		return -ENOMEM;
+#endif
+
+	register_irqsoff(&irqsoff_tracer, tr);
+	register_preemptoff(&preemptoff_tracer, tr);
+	register_preemptirqsoff(&preemptirqsoff_tracer, tr);
 
 	return 0;
 }
Index: linux-compile.git/kernel/trace/trace_mmiotrace.c
===================================================================
--- linux-compile.git.orig/kernel/trace/trace_mmiotrace.c	2008-09-23 23:33:29.000000000 -0400
+++ linux-compile.git/kernel/trace/trace_mmiotrace.c	2008-09-23 23:34:46.000000000 -0400
@@ -27,7 +27,7 @@ static void mmio_reset_data(struct trace
 	tr->time_start = ftrace_now(tr->cpu);
 
 	for_each_online_cpu(cpu)
-		tracing_reset(tr->data[cpu]);
+		tracing_reset(tr, cpu);
 }
 
 static void mmio_trace_init(struct trace_array *tr)
@@ -60,17 +60,17 @@ static void mmio_trace_ctrl_update(struc
 	}
 }
 
-static int mmio_print_pcidev(struct trace_seq *s, const struct pci_dev *dev)
+static int mmio_print_pcidev(struct ring_buffer_seq *s, const struct pci_dev *dev)
 {
 	int ret = 0;
 	int i;
 	resource_size_t start, end;
 	const struct pci_driver *drv = pci_dev_driver(dev);
 
-	/* XXX: incomplete checks for trace_seq_printf() return value */
-	ret += trace_seq_printf(s, "PCIDEV %02x%02x %04x%04x %x",
-				dev->bus->number, dev->devfn,
-				dev->vendor, dev->device, dev->irq);
+	/* XXX: incomplete checks for ring_buffer_seq_printf() return value */
+	ret += ring_buffer_seq_printf(s, "PCIDEV %02x%02x %04x%04x %x",
+				      dev->bus->number, dev->devfn,
+				      dev->vendor, dev->device, dev->irq);
 	/*
 	 * XXX: is pci_resource_to_user() appropriate, since we are
 	 * supposed to interpret the __ioremap() phys_addr argument based on
@@ -78,20 +78,20 @@ static int mmio_print_pcidev(struct trac
 	 */
 	for (i = 0; i < 7; i++) {
 		pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);
-		ret += trace_seq_printf(s, " %llx",
+		ret += ring_buffer_seq_printf(s, " %llx",
 			(unsigned long long)(start |
 			(dev->resource[i].flags & PCI_REGION_FLAG_MASK)));
 	}
 	for (i = 0; i < 7; i++) {
 		pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);
-		ret += trace_seq_printf(s, " %llx",
+		ret += ring_buffer_seq_printf(s, " %llx",
 			dev->resource[i].start < dev->resource[i].end ?
 			(unsigned long long)(end - start) + 1 : 0);
 	}
 	if (drv)
-		ret += trace_seq_printf(s, " %s\n", drv->name);
+		ret += ring_buffer_seq_printf(s, " %s\n", drv->name);
 	else
-		ret += trace_seq_printf(s, " \n");
+		ret += ring_buffer_seq_printf(s, " \n");
 	return ret;
 }
 
@@ -106,9 +106,9 @@ static void destroy_header_iter(struct h
 static void mmio_pipe_open(struct trace_iterator *iter)
 {
 	struct header_iter *hiter;
-	struct trace_seq *s = &iter->seq;
+	struct ring_buffer_seq *s = iter->seq;
 
-	trace_seq_printf(s, "VERSION 20070824\n");
+	ring_buffer_seq_printf(s, "VERSION 20070824\n");
 
 	hiter = kzalloc(sizeof(*hiter), GFP_KERNEL);
 	if (!hiter)
@@ -128,13 +128,7 @@ static void mmio_close(struct trace_iter
 
 static unsigned long count_overruns(struct trace_iterator *iter)
 {
-	int cpu;
-	unsigned long cnt = 0;
-	for_each_online_cpu(cpu) {
-		cnt += iter->overrun[cpu];
-		iter->overrun[cpu] = 0;
-	}
-	return cnt;
+	return ring_buffer_overruns(iter->tr->buffer);
 }
 
 static ssize_t mmio_read(struct trace_iterator *iter, struct file *filp,
@@ -142,13 +136,13 @@ static ssize_t mmio_read(struct trace_it
 {
 	ssize_t ret;
 	struct header_iter *hiter = iter->private;
-	struct trace_seq *s = &iter->seq;
+	struct ring_buffer_seq *s = iter->seq;
 	unsigned long n;
 
 	n = count_overruns(iter);
 	if (n) {
 		/* XXX: This is later than where events were lost. */
-		trace_seq_printf(s, "MARK 0.000000 Lost %lu events.\n", n);
+		ring_buffer_seq_printf(s, "MARK 0.000000 Lost %lu events.\n", n);
 		if (!overrun_detected)
 			pr_warning("mmiotrace has lost events.\n");
 		overrun_detected = true;
@@ -167,37 +161,37 @@ static ssize_t mmio_read(struct trace_it
 	}
 
 print_out:
-	ret = trace_seq_to_user(s, ubuf, cnt);
+	ret = ring_buffer_seq_copy_to_user(s, ubuf, cnt);
 	return (ret == -EBUSY) ? 0 : ret;
 }
 
 static int mmio_print_rw(struct trace_iterator *iter)
 {
-	struct trace_entry *entry = iter->ent;
-	struct mmiotrace_rw *rw	= &entry->mmiorw;
-	struct trace_seq *s	= &iter->seq;
-	unsigned long long t	= ns2usecs(entry->t);
+	struct ring_buffer_event *event = iter->event;
+	struct mmiotrace_rw *rw = ring_buffer_event_data(event);
+	struct ring_buffer_seq *s = iter->seq;
+	unsigned long long t	= ns2usecs(ring_buffer_event_counter(event));
 	unsigned long usec_rem	= do_div(t, 1000000ULL);
 	unsigned secs		= (unsigned long)t;
 	int ret = 1;
 
-	switch (entry->mmiorw.opcode) {
+	switch (rw->opcode) {
 	case MMIO_READ:
-		ret = trace_seq_printf(s,
+		ret = ring_buffer_seq_printf(s,
 			"R %d %lu.%06lu %d 0x%llx 0x%lx 0x%lx %d\n",
 			rw->width, secs, usec_rem, rw->map_id,
 			(unsigned long long)rw->phys,
 			rw->value, rw->pc, 0);
 		break;
 	case MMIO_WRITE:
-		ret = trace_seq_printf(s,
+		ret = ring_buffer_seq_printf(s,
 			"W %d %lu.%06lu %d 0x%llx 0x%lx 0x%lx %d\n",
 			rw->width, secs, usec_rem, rw->map_id,
 			(unsigned long long)rw->phys,
 			rw->value, rw->pc, 0);
 		break;
 	case MMIO_UNKNOWN_OP:
-		ret = trace_seq_printf(s,
+		ret = ring_buffer_seq_printf(s,
 			"UNKNOWN %lu.%06lu %d 0x%llx %02x,%02x,%02x 0x%lx %d\n",
 			secs, usec_rem, rw->map_id,
 			(unsigned long long)rw->phys,
@@ -205,7 +199,7 @@ static int mmio_print_rw(struct trace_it
 			(rw->value >> 0) & 0xff, rw->pc, 0);
 		break;
 	default:
-		ret = trace_seq_printf(s, "rw what?\n");
+		ret = ring_buffer_seq_printf(s, "rw what?\n");
 		break;
 	}
 	if (ret)
@@ -215,29 +209,28 @@ static int mmio_print_rw(struct trace_it
 
 static int mmio_print_map(struct trace_iterator *iter)
 {
-	struct trace_entry *entry = iter->ent;
-	struct mmiotrace_map *m	= &entry->mmiomap;
-	struct trace_seq *s	= &iter->seq;
-	unsigned long long t	= ns2usecs(entry->t);
+	struct mmiotrace_map *m	= ring_buffer_event_data(iter->event);
+	struct ring_buffer_seq *s = iter->seq;
+	unsigned long long t	= ns2usecs(ring_buffer_event_counter(iter->event));
 	unsigned long usec_rem	= do_div(t, 1000000ULL);
 	unsigned secs		= (unsigned long)t;
 	int ret = 1;
 
-	switch (entry->mmiorw.opcode) {
+	switch (m->opcode) {
 	case MMIO_PROBE:
-		ret = trace_seq_printf(s,
+		ret = ring_buffer_seq_printf(s,
 			"MAP %lu.%06lu %d 0x%llx 0x%lx 0x%lx 0x%lx %d\n",
 			secs, usec_rem, m->map_id,
 			(unsigned long long)m->phys, m->virt, m->len,
 			0UL, 0);
 		break;
 	case MMIO_UNPROBE:
-		ret = trace_seq_printf(s,
+		ret = ring_buffer_seq_printf(s,
 			"UNMAP %lu.%06lu %d 0x%lx %d\n",
 			secs, usec_rem, m->map_id, 0UL, 0);
 		break;
 	default:
-		ret = trace_seq_printf(s, "map what?\n");
+		ret = ring_buffer_seq_printf(s, "map what?\n");
 		break;
 	}
 	if (ret)
@@ -248,7 +241,7 @@ static int mmio_print_map(struct trace_i
 /* return 0 to abort printing without consuming current entry in pipe mode */
 static int mmio_print_line(struct trace_iterator *iter)
 {
-	switch (iter->ent->type) {
+	switch (ring_buffer_event_type(iter->event)) {
 	case TRACE_MMIO_RW:
 		return mmio_print_rw(iter);
 	case TRACE_MMIO_MAP:
Index: linux-compile.git/kernel/trace/trace_sched_switch.c
===================================================================
--- linux-compile.git.orig/kernel/trace/trace_sched_switch.c	2008-09-23 23:33:29.000000000 -0400
+++ linux-compile.git/kernel/trace/trace_sched_switch.c	2008-09-23 23:34:46.000000000 -0400
@@ -133,7 +133,7 @@ static void sched_switch_reset(struct tr
 	tr->time_start = ftrace_now(tr->cpu);
 
 	for_each_online_cpu(cpu)
-		tracing_reset(tr->data[cpu]);
+		tracing_reset(tr, cpu);
 }
 
 static int tracing_sched_register(void)
Index: linux-compile.git/kernel/trace/trace_sched_wakeup.c
===================================================================
--- linux-compile.git.orig/kernel/trace/trace_sched_wakeup.c	2008-09-23 23:33:29.000000000 -0400
+++ linux-compile.git/kernel/trace/trace_sched_wakeup.c	2008-09-23 23:34:46.000000000 -0400
@@ -215,8 +215,7 @@ static void __wakeup_reset(struct trace_
 	int cpu;
 
 	for_each_possible_cpu(cpu) {
-		data = tr->data[cpu];
-		tracing_reset(data);
+		tracing_reset(tr, cpu);
 	}
 
 	wakeup_cpu = -1;
Index: linux-compile.git/arch/x86/kernel/Makefile
===================================================================
--- linux-compile.git.orig/arch/x86/kernel/Makefile	2008-09-23 23:33:29.000000000 -0400
+++ linux-compile.git/arch/x86/kernel/Makefile	2008-09-23 23:34:46.000000000 -0400
@@ -11,6 +11,7 @@ ifdef CONFIG_FTRACE
 CFLAGS_REMOVE_tsc.o = -pg
 CFLAGS_REMOVE_rtc.o = -pg
 CFLAGS_REMOVE_paravirt.o = -pg
+CFLAGS_REMOVE_early_printk.o = -pg
 endif
 
 #

-- 

      parent reply	other threads:[~2008-09-24  5:14 UTC|newest]

Thread overview: 109+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-24  5:10 [RFC PATCH 0/3] An Unified tracing buffer (attempt) Steven Rostedt
2008-09-24  5:10 ` [RFC PATCH 1/3] Unified trace buffer Steven Rostedt
2008-09-24 15:03   ` Peter Zijlstra
2008-09-24 15:44     ` Steven Rostedt
2008-09-25 10:38       ` Ingo Molnar
2008-09-24 15:47     ` Martin Bligh
2008-09-24 16:11       ` Peter Zijlstra
2008-09-24 16:24         ` Linus Torvalds
2008-09-24 16:37           ` Steven Rostedt
2008-09-24 16:56             ` Martin Bligh
2008-09-24 17:25             ` Linus Torvalds
2008-09-24 18:01           ` Mathieu Desnoyers
2008-09-24 20:49             ` Linus Torvalds
2008-09-24 16:26         ` Steven Rostedt
2008-09-24 16:49         ` Martin Bligh
2008-09-24 17:36           ` Linus Torvalds
2008-09-24 17:49             ` Steven Rostedt
2008-09-24 20:23               ` Linus Torvalds
2008-09-24 20:37                 ` David Miller
2008-09-24 20:48                   ` Steven Rostedt
2008-09-24 20:51                   ` Martin Bligh
2008-09-24 21:24                     ` Frank Ch. Eigler
2008-09-24 21:33                       ` Steven Rostedt
2008-09-24 20:47                 ` Steven Rostedt
2008-09-24 21:03                   ` Martin Bligh
2008-09-24 21:17                     ` Steven Rostedt
2008-09-24 21:51                     ` Steven Rostedt
2008-09-25 10:41                     ` Peter Zijlstra
2008-09-25 14:33                       ` Martin Bligh
2008-09-25 14:53                         ` Peter Zijlstra
2008-09-25 15:05                           ` Linus Torvalds
2008-09-25 15:25                             ` Martin Bligh
2008-09-25 15:36                               ` Ingo Molnar
2008-09-25 16:23                                 ` Mathieu Desnoyers
2008-09-25 16:32                                   ` Steven Rostedt
2008-09-25 17:20                                     ` Mathieu Desnoyers
2008-09-25 17:32                                       ` Steven Rostedt
2008-09-25 16:40                                 ` Linus Torvalds
2008-09-25 16:53                                   ` Steven Rostedt
2008-09-25 17:07                                     ` Linus Torvalds
2008-09-25 19:55                                       ` Ingo Molnar
2008-09-25 20:12                                         ` Ingo Molnar
2008-09-25 20:24                                           ` Linus Torvalds
2008-09-25 20:29                                             ` Linus Torvalds
2008-09-25 20:47                                               ` Steven Rostedt
2008-09-25 21:01                                               ` Steven Rostedt
2008-09-25 21:10                                               ` Ingo Molnar
2008-09-25 21:16                                                 ` Ingo Molnar
2008-09-25 21:41                                                 ` Ingo Molnar
2008-09-25 21:56                                                   ` Ingo Molnar
2008-09-25 21:58                                                   ` Linus Torvalds
2008-09-25 22:14                                                     ` Ingo Molnar
2008-09-25 23:33                                                       ` Linus Torvalds
2008-09-27 17:16                                                         ` Ingo Molnar
2008-09-27 17:36                                                           ` Ingo Molnar
2008-09-27 17:38                                                           ` Steven Rostedt
2008-09-27 17:50                                                             ` Peter Zijlstra
2008-09-27 18:18                                                               ` Steven Rostedt
2008-09-27 18:42                                                             ` Ingo Molnar
2008-09-25 20:52                                             ` Ingo Molnar
2008-09-25 21:14                                               ` Jeremy Fitzhardinge
2008-09-25 21:15                                               ` Martin Bligh
2008-09-25 20:29                                           ` Mathieu Desnoyers
2008-09-25 20:20                                         ` Ingo Molnar
2008-09-25 21:02                                   ` Jeremy Fitzhardinge
2008-09-25 21:55                                     ` Linus Torvalds
2008-09-25 22:25                                       ` Ingo Molnar
2008-09-25 22:45                                         ` Steven Rostedt
2008-09-25 23:04                                           ` Jeremy Fitzhardinge
2008-09-25 23:25                                             ` Ingo Molnar
2008-09-26 14:04                                           ` Thomas Gleixner
2008-09-25 22:39                                       ` Jeremy Fitzhardinge
2008-09-25 22:55                                         ` Ingo Molnar
2008-09-26  1:17                                           ` Jeremy Fitzhardinge
2008-09-26  1:27                                             ` Steven Rostedt
2008-09-26  1:49                                               ` Jeremy Fitzhardinge
2008-09-25 22:59                                         ` Steven Rostedt
2008-09-26  1:27                                           ` Jeremy Fitzhardinge
2008-09-26  1:35                                             ` Steven Rostedt
2008-09-26  2:07                                               ` Jeremy Fitzhardinge
2008-09-26  2:25                                                 ` Steven Rostedt
2008-09-26  5:31                                                   ` Jeremy Fitzhardinge
2008-09-26 10:41                                                     ` Steven Rostedt
2008-09-25 15:26                             ` Steven Rostedt
2008-09-25 17:22                               ` Linus Torvalds
2008-09-25 17:39                                 ` Steven Rostedt
2008-09-25 18:14                                   ` Linus Torvalds
2008-09-25 15:20                           ` Steven Rostedt
2008-09-24 17:54             ` Martin Bligh
2008-09-24 18:04               ` Martin Bligh
2008-09-24 20:39                 ` Linus Torvalds
2008-09-24 20:56                   ` Martin Bligh
2008-09-24 21:08                     ` Steven Rostedt
2008-09-24 20:30               ` Linus Torvalds
2008-09-24 20:53                 ` Mathieu Desnoyers
2008-09-24 22:28                   ` Linus Torvalds
2008-09-24 22:41                     ` Linus Torvalds
2008-09-25 17:15                     ` Mathieu Desnoyers
2008-09-25 17:29                       ` Linus Torvalds
2008-09-25 17:42                         ` Mathieu Desnoyers
2008-09-25 16:37                 ` Mathieu Desnoyers
2008-09-25 16:49                   ` Linus Torvalds
2008-09-25 17:02                     ` Steven Rostedt
2008-09-24 16:13       ` Mathieu Desnoyers
2008-09-24 16:31         ` Steven Rostedt
2008-09-24 16:39         ` Peter Zijlstra
2008-09-24 16:51           ` Mathieu Desnoyers
2008-09-24  5:10 ` [RFC PATCH 2/3] ftrace: combine some print formating Steven Rostedt
2008-09-24  5:10 ` Steven Rostedt [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080924051400.552924670@goodmis.org \
    --to=rostedt@goodmis.org \
    --cc=akpm@linux-foundation.org \
    --cc=compudj@krystal.dyndns.org \
    --cc=dwilder@us.ibm.com \
    --cc=fche@redhat.com \
    --cc=hch@lst.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mbligh@google.com \
    --cc=mingo@elte.hu \
    --cc=peterz@infradead.org \
    --cc=prasad@linux.vnet.ibm.com \
    --cc=srostedt@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    --cc=zanussi@comcast.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.