aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-03-17 17:22:06 -0400
committerSteven Rostedt <srostedt@redhat.com>2009-03-17 23:06:31 -0400
commit37886f6a9f62d22530ffee8d3f9215c8345b6969 (patch)
tree046c9086682145fd2808af7197af669f08be6d0a /kernel
parent6adaad14d7d4d3ef31b4e2dc992b18b5da7c4eb3 (diff)
ring-buffer: add api to allow a tracer to change clock source
This patch adds a new function called ring_buffer_set_clock that allows a tracer to assign its own clock source to the buffer. Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/ring_buffer.c65
-rw-r--r--kernel/trace/trace.c21
2 files changed, 52 insertions, 34 deletions
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 58128ad2fde0..bbf51922a8ca 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -180,29 +180,6 @@ EXPORT_SYMBOL_GPL(tracing_is_on);
180 180
181#include "trace.h" 181#include "trace.h"
182 182
183/* Up this if you want to test the TIME_EXTENTS and normalization */
184#define DEBUG_SHIFT 0
185
186u64 ring_buffer_time_stamp(int cpu)
187{
188 u64 time;
189
190 preempt_disable_notrace();
191 /* shift to debug/test normalization and TIME_EXTENTS */
192 time = trace_clock_local() << DEBUG_SHIFT;
193 preempt_enable_no_resched_notrace();
194
195 return time;
196}
197EXPORT_SYMBOL_GPL(ring_buffer_time_stamp);
198
199void ring_buffer_normalize_time_stamp(int cpu, u64 *ts)
200{
201 /* Just stupid testing the normalize function and deltas */
202 *ts >>= DEBUG_SHIFT;
203}
204EXPORT_SYMBOL_GPL(ring_buffer_normalize_time_stamp);
205
206#define RB_EVNT_HDR_SIZE (offsetof(struct ring_buffer_event, array)) 183#define RB_EVNT_HDR_SIZE (offsetof(struct ring_buffer_event, array))
207#define RB_ALIGNMENT 4U 184#define RB_ALIGNMENT 4U
208#define RB_MAX_SMALL_DATA 28 185#define RB_MAX_SMALL_DATA 28
@@ -374,6 +351,7 @@ struct ring_buffer {
374#ifdef CONFIG_HOTPLUG_CPU 351#ifdef CONFIG_HOTPLUG_CPU
375 struct notifier_block cpu_notify; 352 struct notifier_block cpu_notify;
376#endif 353#endif
354 u64 (*clock)(void);
377}; 355};
378 356
379struct ring_buffer_iter { 357struct ring_buffer_iter {
@@ -394,6 +372,30 @@ struct ring_buffer_iter {
394 _____ret; \ 372 _____ret; \
395 }) 373 })
396 374
375/* Up this if you want to test the TIME_EXTENTS and normalization */
376#define DEBUG_SHIFT 0
377
378u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu)
379{
380 u64 time;
381
382 preempt_disable_notrace();
383 /* shift to debug/test normalization and TIME_EXTENTS */
384 time = buffer->clock() << DEBUG_SHIFT;
385 preempt_enable_no_resched_notrace();
386
387 return time;
388}
389EXPORT_SYMBOL_GPL(ring_buffer_time_stamp);
390
391void ring_buffer_normalize_time_stamp(struct ring_buffer *buffer,
392 int cpu, u64 *ts)
393{
394 /* Just stupid testing the normalize function and deltas */
395 *ts >>= DEBUG_SHIFT;
396}
397EXPORT_SYMBOL_GPL(ring_buffer_normalize_time_stamp);
398
397/** 399/**
398 * check_pages - integrity check of buffer pages 400 * check_pages - integrity check of buffer pages
399 * @cpu_buffer: CPU buffer with pages to test 401 * @cpu_buffer: CPU buffer with pages to test
@@ -569,6 +571,7 @@ struct ring_buffer *ring_buffer_alloc(unsigned long size, unsigned flags)
569 571
570 buffer->pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE); 572 buffer->pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
571 buffer->flags = flags; 573 buffer->flags = flags;
574 buffer->clock = trace_clock_local;
572 575
573 /* need at least two pages */ 576 /* need at least two pages */
574 if (buffer->pages == 1) 577 if (buffer->pages == 1)
@@ -645,6 +648,12 @@ ring_buffer_free(struct ring_buffer *buffer)
645} 648}
646EXPORT_SYMBOL_GPL(ring_buffer_free); 649EXPORT_SYMBOL_GPL(ring_buffer_free);
647 650
651void ring_buffer_set_clock(struct ring_buffer *buffer,
652 u64 (*clock)(void))
653{
654 buffer->clock = clock;
655}
656
648static void rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer); 657static void rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer);
649 658
650static void 659static void
@@ -1191,7 +1200,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
1191 cpu_buffer->tail_page = next_page; 1200 cpu_buffer->tail_page = next_page;
1192 1201
1193 /* reread the time stamp */ 1202 /* reread the time stamp */
1194 *ts = ring_buffer_time_stamp(cpu_buffer->cpu); 1203 *ts = ring_buffer_time_stamp(buffer, cpu_buffer->cpu);
1195 cpu_buffer->tail_page->page->time_stamp = *ts; 1204 cpu_buffer->tail_page->page->time_stamp = *ts;
1196 } 1205 }
1197 1206
@@ -1334,7 +1343,7 @@ rb_reserve_next_event(struct ring_buffer_per_cpu *cpu_buffer,
1334 if (RB_WARN_ON(cpu_buffer, ++nr_loops > 1000)) 1343 if (RB_WARN_ON(cpu_buffer, ++nr_loops > 1000))
1335 return NULL; 1344 return NULL;
1336 1345
1337 ts = ring_buffer_time_stamp(cpu_buffer->cpu); 1346 ts = ring_buffer_time_stamp(cpu_buffer->buffer, cpu_buffer->cpu);
1338 1347
1339 /* 1348 /*
1340 * Only the first commit can update the timestamp. 1349 * Only the first commit can update the timestamp.
@@ -2051,7 +2060,8 @@ rb_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
2051 case RINGBUF_TYPE_DATA: 2060 case RINGBUF_TYPE_DATA:
2052 if (ts) { 2061 if (ts) {
2053 *ts = cpu_buffer->read_stamp + event->time_delta; 2062 *ts = cpu_buffer->read_stamp + event->time_delta;
2054 ring_buffer_normalize_time_stamp(cpu_buffer->cpu, ts); 2063 ring_buffer_normalize_time_stamp(buffer,
2064 cpu_buffer->cpu, ts);
2055 } 2065 }
2056 return event; 2066 return event;
2057 2067
@@ -2112,7 +2122,8 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
2112 case RINGBUF_TYPE_DATA: 2122 case RINGBUF_TYPE_DATA:
2113 if (ts) { 2123 if (ts) {
2114 *ts = iter->read_stamp + event->time_delta; 2124 *ts = iter->read_stamp + event->time_delta;
2115 ring_buffer_normalize_time_stamp(cpu_buffer->cpu, ts); 2125 ring_buffer_normalize_time_stamp(buffer,
2126 cpu_buffer->cpu, ts);
2116 } 2127 }
2117 return event; 2128 return event;
2118 2129
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 8f89690230e6..3be2f788e10d 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -155,13 +155,6 @@ ns2usecs(cycle_t nsec)
155 return nsec; 155 return nsec;
156} 156}
157 157
158cycle_t ftrace_now(int cpu)
159{
160 u64 ts = ring_buffer_time_stamp(cpu);
161 ring_buffer_normalize_time_stamp(cpu, &ts);
162 return ts;
163}
164
165/* 158/*
166 * The global_trace is the descriptor that holds the tracing 159 * The global_trace is the descriptor that holds the tracing
167 * buffers for the live tracing. For each CPU, it contains 160 * buffers for the live tracing. For each CPU, it contains
@@ -178,6 +171,20 @@ static struct trace_array global_trace;
178 171
179static DEFINE_PER_CPU(struct trace_array_cpu, global_trace_cpu); 172static DEFINE_PER_CPU(struct trace_array_cpu, global_trace_cpu);
180 173
174cycle_t ftrace_now(int cpu)
175{
176 u64 ts;
177
178 /* Early boot up does not have a buffer yet */
179 if (!global_trace.buffer)
180 return trace_clock_local();
181
182 ts = ring_buffer_time_stamp(global_trace.buffer, cpu);
183 ring_buffer_normalize_time_stamp(global_trace.buffer, cpu, &ts);
184
185 return ts;
186}
187
181/* 188/*
182 * The max_tr is used to snapshot the global_trace when a maximum 189 * The max_tr is used to snapshot the global_trace when a maximum
183 * latency is reached. Some tracers will use this to store a maximum 190 * latency is reached. Some tracers will use this to store a maximum