xref: /openbmc/linux/include/linux/ring_buffer.h (revision 7a8e76a3829f1067b70f715771ff88baf2fbf3c3)
1*7a8e76a3SSteven Rostedt #ifndef _LINUX_RING_BUFFER_H
2*7a8e76a3SSteven Rostedt #define _LINUX_RING_BUFFER_H
3*7a8e76a3SSteven Rostedt 
4*7a8e76a3SSteven Rostedt #include <linux/mm.h>
5*7a8e76a3SSteven Rostedt #include <linux/seq_file.h>
6*7a8e76a3SSteven Rostedt 
7*7a8e76a3SSteven Rostedt struct ring_buffer;
8*7a8e76a3SSteven Rostedt struct ring_buffer_iter;
9*7a8e76a3SSteven Rostedt 
10*7a8e76a3SSteven Rostedt /*
11*7a8e76a3SSteven Rostedt  * Don't reference this struct directly, use functions below.
12*7a8e76a3SSteven Rostedt  */
13*7a8e76a3SSteven Rostedt struct ring_buffer_event {
14*7a8e76a3SSteven Rostedt 	u32		type:2, len:3, time_delta:27;
15*7a8e76a3SSteven Rostedt 	u32		array[];
16*7a8e76a3SSteven Rostedt };
17*7a8e76a3SSteven Rostedt 
18*7a8e76a3SSteven Rostedt /**
19*7a8e76a3SSteven Rostedt  * enum ring_buffer_type - internal ring buffer types
20*7a8e76a3SSteven Rostedt  *
21*7a8e76a3SSteven Rostedt  * @RINGBUF_TYPE_PADDING:	Left over page padding
22*7a8e76a3SSteven Rostedt  *				 array is ignored
23*7a8e76a3SSteven Rostedt  *				 size is variable depending on how much
24*7a8e76a3SSteven Rostedt  *				  padding is needed
25*7a8e76a3SSteven Rostedt  *
26*7a8e76a3SSteven Rostedt  * @RINGBUF_TYPE_TIME_EXTEND:	Extend the time delta
27*7a8e76a3SSteven Rostedt  *				 array[0] = time delta (28 .. 59)
28*7a8e76a3SSteven Rostedt  *				 size = 8 bytes
29*7a8e76a3SSteven Rostedt  *
30*7a8e76a3SSteven Rostedt  * @RINGBUF_TYPE_TIME_STAMP:	Sync time stamp with external clock
31*7a8e76a3SSteven Rostedt  *				 array[0] = tv_nsec
32*7a8e76a3SSteven Rostedt  *				 array[1] = tv_sec
33*7a8e76a3SSteven Rostedt  *				 size = 16 bytes
34*7a8e76a3SSteven Rostedt  *
35*7a8e76a3SSteven Rostedt  * @RINGBUF_TYPE_DATA:		Data record
36*7a8e76a3SSteven Rostedt  *				 If len is zero:
37*7a8e76a3SSteven Rostedt  *				  array[0] holds the actual length
38*7a8e76a3SSteven Rostedt  *				  array[1..(length+3)/4-1] holds data
39*7a8e76a3SSteven Rostedt  *				 else
40*7a8e76a3SSteven Rostedt  *				  length = len << 2
41*7a8e76a3SSteven Rostedt  *				  array[0..(length+3)/4] holds data
42*7a8e76a3SSteven Rostedt  */
43*7a8e76a3SSteven Rostedt enum ring_buffer_type {
44*7a8e76a3SSteven Rostedt 	RINGBUF_TYPE_PADDING,
45*7a8e76a3SSteven Rostedt 	RINGBUF_TYPE_TIME_EXTEND,
46*7a8e76a3SSteven Rostedt 	/* FIXME: RINGBUF_TYPE_TIME_STAMP not implemented */
47*7a8e76a3SSteven Rostedt 	RINGBUF_TYPE_TIME_STAMP,
48*7a8e76a3SSteven Rostedt 	RINGBUF_TYPE_DATA,
49*7a8e76a3SSteven Rostedt };
50*7a8e76a3SSteven Rostedt 
51*7a8e76a3SSteven Rostedt unsigned ring_buffer_event_length(struct ring_buffer_event *event);
52*7a8e76a3SSteven Rostedt void *ring_buffer_event_data(struct ring_buffer_event *event);
53*7a8e76a3SSteven Rostedt 
54*7a8e76a3SSteven Rostedt /**
55*7a8e76a3SSteven Rostedt  * ring_buffer_event_time_delta - return the delta timestamp of the event
56*7a8e76a3SSteven Rostedt  * @event: the event to get the delta timestamp of
57*7a8e76a3SSteven Rostedt  *
58*7a8e76a3SSteven Rostedt  * The delta timestamp is the 27 bit timestamp since the last event.
59*7a8e76a3SSteven Rostedt  */
60*7a8e76a3SSteven Rostedt static inline unsigned
61*7a8e76a3SSteven Rostedt ring_buffer_event_time_delta(struct ring_buffer_event *event)
62*7a8e76a3SSteven Rostedt {
63*7a8e76a3SSteven Rostedt 	return event->time_delta;
64*7a8e76a3SSteven Rostedt }
65*7a8e76a3SSteven Rostedt 
66*7a8e76a3SSteven Rostedt void ring_buffer_lock(struct ring_buffer *buffer, unsigned long *flags);
67*7a8e76a3SSteven Rostedt void ring_buffer_unlock(struct ring_buffer *buffer, unsigned long flags);
68*7a8e76a3SSteven Rostedt 
69*7a8e76a3SSteven Rostedt /*
70*7a8e76a3SSteven Rostedt  * size is in bytes for each per CPU buffer.
71*7a8e76a3SSteven Rostedt  */
72*7a8e76a3SSteven Rostedt struct ring_buffer *
73*7a8e76a3SSteven Rostedt ring_buffer_alloc(unsigned long size, unsigned flags);
74*7a8e76a3SSteven Rostedt void ring_buffer_free(struct ring_buffer *buffer);
75*7a8e76a3SSteven Rostedt 
76*7a8e76a3SSteven Rostedt int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size);
77*7a8e76a3SSteven Rostedt 
78*7a8e76a3SSteven Rostedt struct ring_buffer_event *
79*7a8e76a3SSteven Rostedt ring_buffer_lock_reserve(struct ring_buffer *buffer,
80*7a8e76a3SSteven Rostedt 			 unsigned long length,
81*7a8e76a3SSteven Rostedt 			 unsigned long *flags);
82*7a8e76a3SSteven Rostedt int ring_buffer_unlock_commit(struct ring_buffer *buffer,
83*7a8e76a3SSteven Rostedt 			      struct ring_buffer_event *event,
84*7a8e76a3SSteven Rostedt 			      unsigned long flags);
85*7a8e76a3SSteven Rostedt int ring_buffer_write(struct ring_buffer *buffer,
86*7a8e76a3SSteven Rostedt 		      unsigned long length, void *data);
87*7a8e76a3SSteven Rostedt 
88*7a8e76a3SSteven Rostedt struct ring_buffer_event *
89*7a8e76a3SSteven Rostedt ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts);
90*7a8e76a3SSteven Rostedt struct ring_buffer_event *
91*7a8e76a3SSteven Rostedt ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts);
92*7a8e76a3SSteven Rostedt 
93*7a8e76a3SSteven Rostedt struct ring_buffer_iter *
94*7a8e76a3SSteven Rostedt ring_buffer_read_start(struct ring_buffer *buffer, int cpu);
95*7a8e76a3SSteven Rostedt void ring_buffer_read_finish(struct ring_buffer_iter *iter);
96*7a8e76a3SSteven Rostedt 
97*7a8e76a3SSteven Rostedt struct ring_buffer_event *
98*7a8e76a3SSteven Rostedt ring_buffer_iter_peek(struct ring_buffer_iter *iter, u64 *ts);
99*7a8e76a3SSteven Rostedt struct ring_buffer_event *
100*7a8e76a3SSteven Rostedt ring_buffer_read(struct ring_buffer_iter *iter, u64 *ts);
101*7a8e76a3SSteven Rostedt void ring_buffer_iter_reset(struct ring_buffer_iter *iter);
102*7a8e76a3SSteven Rostedt int ring_buffer_iter_empty(struct ring_buffer_iter *iter);
103*7a8e76a3SSteven Rostedt 
104*7a8e76a3SSteven Rostedt unsigned long ring_buffer_size(struct ring_buffer *buffer);
105*7a8e76a3SSteven Rostedt 
106*7a8e76a3SSteven Rostedt void ring_buffer_reset_cpu(struct ring_buffer *buffer, int cpu);
107*7a8e76a3SSteven Rostedt void ring_buffer_reset(struct ring_buffer *buffer);
108*7a8e76a3SSteven Rostedt 
109*7a8e76a3SSteven Rostedt int ring_buffer_swap_cpu(struct ring_buffer *buffer_a,
110*7a8e76a3SSteven Rostedt 			 struct ring_buffer *buffer_b, int cpu);
111*7a8e76a3SSteven Rostedt 
112*7a8e76a3SSteven Rostedt int ring_buffer_empty(struct ring_buffer *buffer);
113*7a8e76a3SSteven Rostedt int ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu);
114*7a8e76a3SSteven Rostedt 
115*7a8e76a3SSteven Rostedt void ring_buffer_record_disable(struct ring_buffer *buffer);
116*7a8e76a3SSteven Rostedt void ring_buffer_record_enable(struct ring_buffer *buffer);
117*7a8e76a3SSteven Rostedt void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu);
118*7a8e76a3SSteven Rostedt void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu);
119*7a8e76a3SSteven Rostedt 
120*7a8e76a3SSteven Rostedt unsigned long ring_buffer_entries(struct ring_buffer *buffer);
121*7a8e76a3SSteven Rostedt unsigned long ring_buffer_overruns(struct ring_buffer *buffer);
122*7a8e76a3SSteven Rostedt 
123*7a8e76a3SSteven Rostedt u64 ring_buffer_time_stamp(int cpu);
124*7a8e76a3SSteven Rostedt void ring_buffer_normalize_time_stamp(int cpu, u64 *ts);
125*7a8e76a3SSteven Rostedt 
126*7a8e76a3SSteven Rostedt enum ring_buffer_flags {
127*7a8e76a3SSteven Rostedt 	RB_FL_OVERWRITE		= 1 << 0,
128*7a8e76a3SSteven Rostedt };
129*7a8e76a3SSteven Rostedt 
130*7a8e76a3SSteven Rostedt #endif /* _LINUX_RING_BUFFER_H */
131