aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorSteven Rostedt <rostedt@goodmis.org>2008-09-29 23:02:38 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-14 04:38:54 -0400
commit7a8e76a3829f1067b70f715771ff88baf2fbf3c3 (patch)
tree71126d4ad6f89abd00cac688318aff14323a96bb /include
parent5aa60c6073456812251caf9177cb921b2de68f77 (diff)
tracing: unified trace buffer
This is a unified tracing buffer that implements a ring buffer that hopefully everyone will eventually be able to use. The events recorded into the buffer have the following structure: struct ring_buffer_event { u32 type:2, len:3, time_delta:27; u32 array[]; }; The minimum size of an event is 8 bytes. All events are 4 byte aligned inside the buffer. There are 4 types (all internal use for the ring buffer, only the data type is exported to the interface users). RINGBUF_TYPE_PADDING: this type is used to note extra space at the end of a buffer page. RINGBUF_TYPE_TIME_EXTENT: This type is used when the time between events is greater than the 27 bit delta can hold. We add another 32 bits, and record that in its own event (8 byte size). RINGBUF_TYPE_TIME_STAMP: (Not implemented yet). This will hold data to help keep the buffer timestamps in sync. RINGBUF_TYPE_DATA: The event actually holds user data. The "len" field is only three bits. Since the data must be 4 byte aligned, this field is shifted left by 2, giving a max length of 28 bytes. If the data load is greater than 28 bytes, the first array field holds the full length of the data load and the len field is set to zero. Example, data size of 7 bytes: type = RINGBUF_TYPE_DATA len = 2 time_delta: <time-stamp> - <prev_event-time-stamp> array[0..1]: <7 bytes of data> <1 byte empty> This event is saved in 12 bytes of the buffer. An event with 82 bytes of data: type = RINGBUF_TYPE_DATA len = 0 time_delta: <time-stamp> - <prev_event-time-stamp> array[0]: 84 (Note the alignment) array[1..14]: <82 bytes of data> <2 bytes empty> The above event is saved in 92 bytes (if my math is correct). 82 bytes of data, 2 bytes empty, 4 byte header, 4 byte length. Do not reference the above event struct directly. Use the following functions to gain access to the event table, since the ring_buffer_event structure may change in the future. ring_buffer_event_length(event): get the length of the event. This is the size of the memory used to record this event, and not the size of the data pay load. ring_buffer_time_delta(event): get the time delta of the event This returns the delta time stamp since the last event. Note: Even though this is in the header, there should be no reason to access this directly, accept for debugging. ring_buffer_event_data(event): get the data from the event This is the function to use to get the actual data from the event. Note, it is only a pointer to the data inside the buffer. This data must be copied to another location otherwise you risk it being written over in the buffer. ring_buffer_lock: A way to lock the entire buffer. ring_buffer_unlock: unlock the buffer. ring_buffer_alloc: create a new ring buffer. Can choose between overwrite or consumer/producer mode. Overwrite will overwrite old data, where as consumer producer will throw away new data if the consumer catches up with the producer. The consumer/producer is the default. ring_buffer_free: free the ring buffer. ring_buffer_resize: resize the buffer. Changes the size of each cpu buffer. Note, it is up to the caller to provide that the buffer is not being used while this is happening. This requirement may go away but do not count on it. ring_buffer_lock_reserve: locks the ring buffer and allocates an entry on the buffer to write to. ring_buffer_unlock_commit: unlocks the ring buffer and commits it to the buffer. ring_buffer_write: writes some data into the ring buffer. ring_buffer_peek: Look at a next item in the cpu buffer. ring_buffer_consume: get the next item in the cpu buffer and consume it. That is, this function increments the head pointer. ring_buffer_read_start: Start an iterator of a cpu buffer. For now, this disables the cpu buffer, until you issue a finish. This is just because we do not want the iterator to be overwritten. This restriction may change in the future. But note, this is used for static reading of a buffer which is usually done "after" a trace. Live readings would want to use the ring_buffer_consume above, which will not disable the ring buffer. ring_buffer_read_finish: Finishes the read iterator and reenables the ring buffer. ring_buffer_iter_peek: Look at the next item in the cpu iterator. ring_buffer_read: Read the iterator and increment it. ring_buffer_iter_reset: Reset the iterator to point to the beginning of the cpu buffer. ring_buffer_iter_empty: Returns true if the iterator is at the end of the cpu buffer. ring_buffer_size: returns the size in bytes of each cpu buffer. Note, the real size is this times the number of CPUs. ring_buffer_reset_cpu: Sets the cpu buffer to empty ring_buffer_reset: sets all cpu buffers to empty ring_buffer_swap_cpu: swaps a cpu buffer from one buffer with a cpu buffer of another buffer. This is handy when you want to take a snap shot of a running trace on just one cpu. Having a backup buffer, to swap with facilitates this. Ftrace max latencies use this. ring_buffer_empty: Returns true if the ring buffer is empty. ring_buffer_empty_cpu: Returns true if the cpu buffer is empty. ring_buffer_record_disable: disable all cpu buffers (read only) ring_buffer_record_disable_cpu: disable a single cpu buffer (read only) ring_buffer_record_enable: enable all cpu buffers. ring_buffer_record_enabl_cpu: enable a single cpu buffer. ring_buffer_entries: The number of entries in a ring buffer. ring_buffer_overruns: The number of entries removed due to writing wrap. ring_buffer_time_stamp: Get the time stamp used by the ring buffer ring_buffer_normalize_time_stamp: normalize the ring buffer time stamp into nanosecs. I still need to implement the GTOD feature. But we need support from the cpu frequency infrastructure. But this can be done at a later time without affecting the ring buffer interface. Signed-off-by: Steven Rostedt <srostedt@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include')
-rw-r--r--include/linux/ring_buffer.h130
1 files changed, 130 insertions, 0 deletions
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
new file mode 100644
index 000000000000..c52375b8330d
--- /dev/null
+++ b/include/linux/ring_buffer.h
@@ -0,0 +1,130 @@
1#ifndef _LINUX_RING_BUFFER_H
2#define _LINUX_RING_BUFFER_H
3
4#include <linux/mm.h>
5#include <linux/seq_file.h>
6
7struct ring_buffer;
8struct ring_buffer_iter;
9
10/*
11 * Don't reference this struct directly, use functions below.
12 */
13struct ring_buffer_event {
14 u32 type:2, len:3, time_delta:27;
15 u32 array[];
16};
17
18/**
19 * enum ring_buffer_type - internal ring buffer types
20 *
21 * @RINGBUF_TYPE_PADDING: Left over page padding
22 * array is ignored
23 * size is variable depending on how much
24 * padding is needed
25 *
26 * @RINGBUF_TYPE_TIME_EXTEND: Extend the time delta
27 * array[0] = time delta (28 .. 59)
28 * size = 8 bytes
29 *
30 * @RINGBUF_TYPE_TIME_STAMP: Sync time stamp with external clock
31 * array[0] = tv_nsec
32 * array[1] = tv_sec
33 * size = 16 bytes
34 *
35 * @RINGBUF_TYPE_DATA: Data record
36 * If len is zero:
37 * array[0] holds the actual length
38 * array[1..(length+3)/4-1] holds data
39 * else
40 * length = len << 2
41 * array[0..(length+3)/4] holds data
42 */
43enum ring_buffer_type {
44 RINGBUF_TYPE_PADDING,
45 RINGBUF_TYPE_TIME_EXTEND,
46 /* FIXME: RINGBUF_TYPE_TIME_STAMP not implemented */
47 RINGBUF_TYPE_TIME_STAMP,
48 RINGBUF_TYPE_DATA,
49};
50
51unsigned ring_buffer_event_length(struct ring_buffer_event *event);
52void *ring_buffer_event_data(struct ring_buffer_event *event);
53
54/**
55 * ring_buffer_event_time_delta - return the delta timestamp of the event
56 * @event: the event to get the delta timestamp of
57 *
58 * The delta timestamp is the 27 bit timestamp since the last event.
59 */
60static inline unsigned
61ring_buffer_event_time_delta(struct ring_buffer_event *event)
62{
63 return event->time_delta;
64}
65
66void ring_buffer_lock(struct ring_buffer *buffer, unsigned long *flags);
67void ring_buffer_unlock(struct ring_buffer *buffer, unsigned long flags);
68
69/*
70 * size is in bytes for each per CPU buffer.
71 */
72struct ring_buffer *
73ring_buffer_alloc(unsigned long size, unsigned flags);
74void ring_buffer_free(struct ring_buffer *buffer);
75
76int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size);
77
78struct ring_buffer_event *
79ring_buffer_lock_reserve(struct ring_buffer *buffer,
80 unsigned long length,
81 unsigned long *flags);
82int ring_buffer_unlock_commit(struct ring_buffer *buffer,
83 struct ring_buffer_event *event,
84 unsigned long flags);
85int ring_buffer_write(struct ring_buffer *buffer,
86 unsigned long length, void *data);
87
88struct ring_buffer_event *
89ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts);
90struct ring_buffer_event *
91ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts);
92
93struct ring_buffer_iter *
94ring_buffer_read_start(struct ring_buffer *buffer, int cpu);
95void ring_buffer_read_finish(struct ring_buffer_iter *iter);
96
97struct ring_buffer_event *
98ring_buffer_iter_peek(struct ring_buffer_iter *iter, u64 *ts);
99struct ring_buffer_event *
100ring_buffer_read(struct ring_buffer_iter *iter, u64 *ts);
101void ring_buffer_iter_reset(struct ring_buffer_iter *iter);
102int ring_buffer_iter_empty(struct ring_buffer_iter *iter);
103
104unsigned long ring_buffer_size(struct ring_buffer *buffer);
105
106void ring_buffer_reset_cpu(struct ring_buffer *buffer, int cpu);
107void ring_buffer_reset(struct ring_buffer *buffer);
108
109int ring_buffer_swap_cpu(struct ring_buffer *buffer_a,
110 struct ring_buffer *buffer_b, int cpu);
111
112int ring_buffer_empty(struct ring_buffer *buffer);
113int ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu);
114
115void ring_buffer_record_disable(struct ring_buffer *buffer);
116void ring_buffer_record_enable(struct ring_buffer *buffer);
117void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu);
118void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu);
119
120unsigned long ring_buffer_entries(struct ring_buffer *buffer);
121unsigned long ring_buffer_overruns(struct ring_buffer *buffer);
122
123u64 ring_buffer_time_stamp(int cpu);
124void ring_buffer_normalize_time_stamp(int cpu, u64 *ts);
125
126enum ring_buffer_flags {
127 RB_FL_OVERWRITE = 1 << 0,
128};
129
130#endif /* _LINUX_RING_BUFFER_H */