diff options
author | Steven Rostedt <srostedt@redhat.com> | 2009-03-17 17:22:06 -0400 |
---|---|---|
committer | Steven Rostedt <srostedt@redhat.com> | 2009-03-17 23:06:31 -0400 |
commit | 37886f6a9f62d22530ffee8d3f9215c8345b6969 (patch) | |
tree | 046c9086682145fd2808af7197af669f08be6d0a /kernel | |
parent | 6adaad14d7d4d3ef31b4e2dc992b18b5da7c4eb3 (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.c | 65 | ||||
-rw-r--r-- | kernel/trace/trace.c | 21 |
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 | |||
186 | u64 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 | } | ||
197 | EXPORT_SYMBOL_GPL(ring_buffer_time_stamp); | ||
198 | |||
199 | void ring_buffer_normalize_time_stamp(int cpu, u64 *ts) | ||
200 | { | ||
201 | /* Just stupid testing the normalize function and deltas */ | ||
202 | *ts >>= DEBUG_SHIFT; | ||
203 | } | ||
204 | EXPORT_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 | ||
379 | struct ring_buffer_iter { | 357 | struct 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 | |||
378 | u64 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 | } | ||
389 | EXPORT_SYMBOL_GPL(ring_buffer_time_stamp); | ||
390 | |||
391 | void 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 | } | ||
397 | EXPORT_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 | } |
646 | EXPORT_SYMBOL_GPL(ring_buffer_free); | 649 | EXPORT_SYMBOL_GPL(ring_buffer_free); |
647 | 650 | ||
651 | void ring_buffer_set_clock(struct ring_buffer *buffer, | ||
652 | u64 (*clock)(void)) | ||
653 | { | ||
654 | buffer->clock = clock; | ||
655 | } | ||
656 | |||
648 | static void rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer); | 657 | static void rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer); |
649 | 658 | ||
650 | static void | 659 | static 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 | ||
158 | cycle_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 | ||
179 | static DEFINE_PER_CPU(struct trace_array_cpu, global_trace_cpu); | 172 | static DEFINE_PER_CPU(struct trace_array_cpu, global_trace_cpu); |
180 | 173 | ||
174 | cycle_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 |