2 * ltt-ring-buffer-client.h
4 * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6 * LTTng lib ring buffer client template.
8 * Dual LGPL v2.1/GPL v2 license.
11 #include <linux/module.h>
12 #include <linux/types.h>
13 #include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */
14 #include "wrapper/trace-clock.h"
15 #include "ltt-events.h"
16 #include "ltt-tracer.h"
19 * Keep the natural field alignment for _each field_ within this structure if
20 * you ever add/remove a field from this header. Packed attribute is not used
21 * because gcc generates poor code on at least powerpc and mips. Don't ever
22 * let gcc add padding between the structure elements.
24 struct packet_header
{
27 * contains endianness information.
31 uint64_t timestamp_begin
; /* Cycle count at subbuffer start */
32 uint64_t timestamp_end
; /* Cycle count at subbuffer end */
33 uint32_t content_size
; /* Size of data in subbuffer */
34 uint32_t packet_size
; /* Subbuffer size (include padding) */
35 uint32_t events_lost
; /*
36 * Events lost in this subbuffer since
37 * the beginning of the trace.
41 uint64_t start_time_sec
; /* NTP-corrected start time */
42 uint64_t start_time_usec
;
43 uint64_t start_freq
; /*
44 * Frequency at trace start,
45 * used all along the trace.
47 uint32_t freq_scale
; /* Frequency scaling (divisor) */
49 uint8_t header_end
[0]; /* End of header */
53 static inline notrace u64
lib_ring_buffer_clock_read(struct channel
*chan
)
55 return trace_clock_read64();
59 * record_header_size - Calculate the header size and padding necessary.
60 * @config: ring buffer instance configuration
62 * @offset: offset in the write buffer
63 * @data_size: size of the payload
64 * @pre_header_padding: padding to add before the header (output)
65 * @rflags: reservation flags
66 * @ctx: reservation context
68 * Returns the event header size (including padding).
71 * The event header must be 32-bits. The total offset calculated here :
73 * Alignment of header struct on 32 bits (min arch size, header size)
74 * + sizeof(header struct) (32-bits)
75 * + (opt) u16 (ext. event id)
76 * + (opt) u16 (event_size)
77 * (if event_size == LTT_MAX_SMALL_SIZE, has ext. event size)
78 * + (opt) u32 (ext. event size)
79 * + (opt) u64 full TSC (aligned on min(64-bits, arch size))
81 * The payload must itself determine its own alignment from the biggest type it
85 unsigned char record_header_size(const struct lib_ring_buffer_config
*config
,
86 struct channel
*chan
, size_t offset
,
87 size_t data_size
, size_t *pre_header_padding
,
89 struct lib_ring_buffer_ctx
*ctx
)
91 size_t orig_offset
= offset
;
94 BUILD_BUG_ON(sizeof(struct event_header
) != sizeof(u32
));
96 padding
= lib_ring_buffer_align(offset
,
97 sizeof(struct event_header
));
99 offset
+= sizeof(struct event_header
);
101 if (unlikely(rflags
)) {
103 case LTT_RFLAG_ID_SIZE_TSC
:
104 offset
+= sizeof(u16
) + sizeof(u16
);
105 if (data_size
>= LTT_MAX_SMALL_SIZE
)
106 offset
+= sizeof(u32
);
107 offset
+= lib_ring_buffer_align(offset
, sizeof(u64
));
108 offset
+= sizeof(u64
);
110 case LTT_RFLAG_ID_SIZE
:
111 offset
+= sizeof(u16
) + sizeof(u16
);
112 if (data_size
>= LTT_MAX_SMALL_SIZE
)
113 offset
+= sizeof(u32
);
116 offset
+= sizeof(u16
);
121 *pre_header_padding
= padding
;
122 return offset
- orig_offset
;
125 #include "wrapper/ringbuffer/api.h"
128 void ltt_write_event_header_slow(const struct lib_ring_buffer_config
*config
,
129 struct lib_ring_buffer_ctx
*ctx
,
130 u16 eID
, u32 event_size
);
133 * ltt_write_event_header
135 * Writes the event header to the offset (already aligned on 32-bits).
137 * @config: ring buffer instance configuration
138 * @ctx: reservation context
140 * @event_size : size of the event, excluding the event header.
143 void ltt_write_event_header(const struct lib_ring_buffer_config
*config
,
144 struct lib_ring_buffer_ctx
*ctx
,
145 u16 eID
, u32 event_size
)
147 struct event_header header
;
149 if (unlikely(ctx
->rflags
))
152 header
.id_time
= eID
<< LTT_TSC_BITS
;
153 header
.id_time
|= (u32
)ctx
->tsc
& LTT_TSC_MASK
;
154 lib_ring_buffer_write(config
, ctx
, &header
, sizeof(header
));
157 ltt_write_event_header_slow(config
, ctx
, eID
, event_size
);
160 void ltt_write_event_header_slow(const struct lib_ring_buffer_config
*config
,
161 struct lib_ring_buffer_ctx
*ctx
,
162 u16 eID
, u32 event_size
)
164 struct event_header header
;
167 switch (ctx
->rflags
) {
168 case LTT_RFLAG_ID_SIZE_TSC
:
169 header
.id_time
= 29 << LTT_TSC_BITS
;
171 case LTT_RFLAG_ID_SIZE
:
172 header
.id_time
= 30 << LTT_TSC_BITS
;
175 header
.id_time
= 31 << LTT_TSC_BITS
;
182 header
.id_time
|= (u32
)ctx
->tsc
& LTT_TSC_MASK
;
183 lib_ring_buffer_write(config
, ctx
, &header
, sizeof(header
));
185 switch (ctx
->rflags
) {
186 case LTT_RFLAG_ID_SIZE_TSC
:
187 small_size
= (u16
)min_t(u32
, event_size
, LTT_MAX_SMALL_SIZE
);
188 lib_ring_buffer_write(config
, ctx
, &eID
, sizeof(u16
));
189 lib_ring_buffer_write(config
, ctx
, &small_size
, sizeof(u16
));
190 if (small_size
== LTT_MAX_SMALL_SIZE
)
191 lib_ring_buffer_write(config
, ctx
, &event_size
,
193 lib_ring_buffer_align_ctx(ctx
, sizeof(u64
));
194 lib_ring_buffer_write(config
, ctx
, &ctx
->tsc
, sizeof(u64
));
196 case LTT_RFLAG_ID_SIZE
:
197 small_size
= (u16
)min_t(u32
, event_size
, LTT_MAX_SMALL_SIZE
);
198 lib_ring_buffer_write(config
, ctx
, &eID
, sizeof(u16
));
199 lib_ring_buffer_write(config
, ctx
, &small_size
, sizeof(u16
));
200 if (small_size
== LTT_MAX_SMALL_SIZE
)
201 lib_ring_buffer_write(config
, ctx
, &event_size
,
205 lib_ring_buffer_write(config
, ctx
, &eID
, sizeof(u16
));
210 static const struct lib_ring_buffer_config client_config
;
212 static u64
client_ring_buffer_clock_read(struct channel
*chan
)
214 return lib_ring_buffer_clock_read(chan
);
218 size_t client_record_header_size(const struct lib_ring_buffer_config
*config
,
219 struct channel
*chan
, size_t offset
,
221 size_t *pre_header_padding
,
223 struct lib_ring_buffer_ctx
*ctx
)
225 return record_header_size(config
, chan
, offset
, data_size
,
226 pre_header_padding
, rflags
, ctx
);
230 * client_packet_header_size - called on buffer-switch to a new sub-buffer
232 * Return header size without padding after the structure. Don't use packed
233 * structure because gcc generates inefficient code on some architectures
236 static size_t client_packet_header_size(void)
238 return offsetof(struct packet_header
, header_end
);
241 static void client_buffer_begin(struct lib_ring_buffer
*buf
, u64 tsc
,
242 unsigned int subbuf_idx
)
244 struct channel
*chan
= buf
->backend
.chan
;
245 struct packet_header
*header
=
246 (struct packet_header
*)
247 lib_ring_buffer_offset_address(&buf
->backend
,
248 subbuf_idx
* chan
->backend
.subbuf_size
);
249 struct ltt_session
*session
= channel_get_private(chan
);
251 header
->magic
= CTF_MAGIC_NUMBER
;
252 memcpy(header
->uuid
, session
->uuid
.b
, sizeof(session
->uuid
));
253 header
->timestamp_begin
= tsc
;
254 header
->timestamp_end
= 0;
255 header
->content_size
= 0xFFFFFFFF; /* for debugging */
256 header
->packet_size
= 0xFFFFFFFF;
257 header
->events_lost
= 0;
259 header
->start_time_sec
= ltt_chan
->session
->start_time
.tv_sec
;
260 header
->start_time_usec
= ltt_chan
->session
->start_time
.tv_usec
;
261 header
->start_freq
= ltt_chan
->session
->start_freq
;
262 header
->freq_scale
= ltt_chan
->session
->freq_scale
;
267 * offset is assumed to never be 0 here : never deliver a completely empty
268 * subbuffer. data_size is between 1 and subbuf_size.
270 static void client_buffer_end(struct lib_ring_buffer
*buf
, u64 tsc
,
271 unsigned int subbuf_idx
, unsigned long data_size
)
273 struct channel
*chan
= buf
->backend
.chan
;
274 struct packet_header
*header
=
275 (struct packet_header
*)
276 lib_ring_buffer_offset_address(&buf
->backend
,
277 subbuf_idx
* chan
->backend
.subbuf_size
);
278 unsigned long records_lost
= 0;
280 header
->timestamp_end
= tsc
;
281 header
->content_size
= data_size
;
282 header
->packet_size
= PAGE_ALIGN(data_size
);
283 records_lost
+= lib_ring_buffer_get_records_lost_full(&client_config
, buf
);
284 records_lost
+= lib_ring_buffer_get_records_lost_wrap(&client_config
, buf
);
285 records_lost
+= lib_ring_buffer_get_records_lost_big(&client_config
, buf
);
286 header
->events_lost
= records_lost
;
289 static int client_buffer_create(struct lib_ring_buffer
*buf
, void *priv
,
290 int cpu
, const char *name
)
295 static void client_buffer_finalize(struct lib_ring_buffer
*buf
, void *priv
, int cpu
)
299 static const struct lib_ring_buffer_config client_config
= {
300 .cb
.ring_buffer_clock_read
= client_ring_buffer_clock_read
,
301 .cb
.record_header_size
= client_record_header_size
,
302 .cb
.subbuffer_header_size
= client_packet_header_size
,
303 .cb
.buffer_begin
= client_buffer_begin
,
304 .cb
.buffer_end
= client_buffer_end
,
305 .cb
.buffer_create
= client_buffer_create
,
306 .cb
.buffer_finalize
= client_buffer_finalize
,
309 .alloc
= RING_BUFFER_ALLOC_PER_CPU
,
310 .sync
= RING_BUFFER_SYNC_PER_CPU
,
311 .mode
= RING_BUFFER_MODE_TEMPLATE
,
312 .backend
= RING_BUFFER_PAGE
,
313 .output
= RING_BUFFER_SPLICE
,
314 .oops
= RING_BUFFER_OOPS_CONSISTENCY
,
315 .ipi
= RING_BUFFER_IPI_BARRIER
,
316 .wakeup
= RING_BUFFER_WAKEUP_BY_TIMER
,
320 struct channel
*_channel_create(const char *name
,
321 struct ltt_session
*session
, void *buf_addr
,
322 size_t subbuf_size
, size_t num_subbuf
,
323 unsigned int switch_timer_interval
,
324 unsigned int read_timer_interval
)
326 return channel_create(&client_config
, name
, session
, buf_addr
,
327 subbuf_size
, num_subbuf
, switch_timer_interval
,
328 read_timer_interval
);
332 void ltt_channel_destroy(struct channel
*chan
)
334 channel_destroy(chan
);
338 struct lib_ring_buffer
*ltt_buffer_read_open(struct channel
*chan
)
340 struct lib_ring_buffer
*buf
;
343 for_each_channel_cpu(cpu
, chan
) {
344 buf
= channel_get_ring_buffer(&client_config
, chan
, cpu
);
345 if (!lib_ring_buffer_open_read(buf
))
352 void ltt_buffer_read_close(struct lib_ring_buffer
*buf
)
354 lib_ring_buffer_release_read(buf
);
359 int ltt_event_reserve(struct lib_ring_buffer_ctx
*ctx
)
363 cpu
= lib_ring_buffer_get_cpu(&client_config
);
368 ret
= lib_ring_buffer_reserve(&client_config
, ctx
);
374 lib_ring_buffer_put_cpu(&client_config
);
379 void ltt_event_commit(struct lib_ring_buffer_ctx
*ctx
)
381 lib_ring_buffer_commit(&client_config
, ctx
);
382 lib_ring_buffer_put_cpu(&client_config
);
386 void ltt_event_write(struct lib_ring_buffer_ctx
*ctx
, const void *src
,
389 lib_ring_buffer_write(&client_config
, ctx
, src
, len
);
393 wait_queue_head_t
*ltt_get_reader_wait_queue(struct ltt_channel
*chan
)
395 return &chan
->chan
->read_wait
;
398 static struct ltt_transport ltt_relay_transport
= {
399 .name
= "relay-" RING_BUFFER_MODE_TEMPLATE_STRING
,
400 .owner
= THIS_MODULE
,
402 .channel_create
= _channel_create
,
403 .channel_destroy
= ltt_channel_destroy
,
404 .buffer_read_open
= ltt_buffer_read_open
,
405 .buffer_read_close
= ltt_buffer_read_close
,
406 .event_reserve
= ltt_event_reserve
,
407 .event_commit
= ltt_event_commit
,
408 .event_write
= ltt_event_write
,
409 .packet_avail_size
= NULL
, /* Would be racy anyway */
410 .get_reader_wait_queue
= ltt_get_reader_wait_queue
,
414 static int __init
ltt_ring_buffer_client_init(void)
417 * This vmalloc sync all also takes care of the lib ring buffer
418 * vmalloc'd module pages when it is built as a module into LTTng.
420 wrapper_vmalloc_sync_all();
421 printk(KERN_INFO
"LTT : ltt ring buffer client init\n");
422 ltt_transport_register(<t_relay_transport
);
426 module_init(ltt_ring_buffer_client_init
);
428 static void __exit
ltt_ring_buffer_client_exit(void)
430 printk(KERN_INFO
"LTT : ltt ring buffer client exit\n");
431 ltt_transport_unregister(<t_relay_transport
);
434 module_exit(ltt_ring_buffer_client_exit
);
436 MODULE_LICENSE("GPL and additional rights");
437 MODULE_AUTHOR("Mathieu Desnoyers");
438 MODULE_DESCRIPTION("LTTng ring buffer " RING_BUFFER_MODE_TEMPLATE_STRING