1 /* SPDX-License-Identifier: (GPL-2.0 or LGPL-2.1)
3 * lttng-ring-buffer-event-notifier-client.h
5 * LTTng lib ring buffer event notifier client template.
7 * Copyright (C) 2010-2020 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
10 #include <linux/limits.h>
11 #include <linux/module.h>
12 #include <linux/types.h>
13 #include <wrapper/vmalloc.h> /* for wrapper_vmalloc_sync_mappings() */
14 #include <lttng/abi.h>
15 #include <lttng/events.h>
16 #include <lttng/events-internal.h>
17 #include <lttng/tracer.h>
18 #include <wrapper/limits.h>
20 static struct lttng_transport lttng_relay_transport
;
22 struct event_notifier_packet_header
{
23 uint8_t header_end
[0];
26 struct event_notifier_record_header
{
27 uint32_t payload_len
; /* in bytes */
28 uint8_t header_end
[0]; /* End of header */
31 static const struct lttng_kernel_ring_buffer_config client_config
;
34 u64
lib_ring_buffer_clock_read(struct lttng_kernel_ring_buffer_channel
*chan
)
40 size_t record_header_size(const struct lttng_kernel_ring_buffer_config
*config
,
41 struct lttng_kernel_ring_buffer_channel
*chan
, size_t offset
,
42 size_t *pre_header_padding
,
43 struct lttng_kernel_ring_buffer_ctx
*ctx
,
46 size_t orig_offset
= offset
;
49 padding
= lib_ring_buffer_align(offset
, lttng_alignof(uint32_t));
52 offset
+= sizeof(uint32_t);
54 *pre_header_padding
= padding
;
56 return offset
- orig_offset
;
59 #include <ringbuffer/api.h>
61 static u64
client_ring_buffer_clock_read(struct lttng_kernel_ring_buffer_channel
*chan
)
67 size_t client_record_header_size(const struct lttng_kernel_ring_buffer_config
*config
,
68 struct lttng_kernel_ring_buffer_channel
*chan
, size_t offset
,
69 size_t *pre_header_padding
,
70 struct lttng_kernel_ring_buffer_ctx
*ctx
,
73 return record_header_size(config
, chan
, offset
,
74 pre_header_padding
, ctx
, client_ctx
);
78 * client_packet_header_size - called on buffer-switch to a new sub-buffer
80 * Return header size without padding after the structure. Don't use packed
81 * structure because gcc generates inefficient code on some architectures
84 static size_t client_packet_header_size(void)
86 return offsetof(struct event_notifier_packet_header
, header_end
);
89 static void client_buffer_begin(struct lttng_kernel_ring_buffer
*buf
, u64 tsc
,
90 unsigned int subbuf_idx
)
95 * offset is assumed to never be 0 here : never deliver a completely empty
96 * subbuffer. data_size is between 1 and subbuf_size.
98 static void client_buffer_end(struct lttng_kernel_ring_buffer
*buf
, u64 tsc
,
99 unsigned int subbuf_idx
, unsigned long data_size
)
103 static int client_buffer_create(struct lttng_kernel_ring_buffer
*buf
, void *priv
,
104 int cpu
, const char *name
)
109 static void client_buffer_finalize(struct lttng_kernel_ring_buffer
*buf
, void *priv
, int cpu
)
113 static int client_timestamp_begin(const struct lttng_kernel_ring_buffer_config
*config
,
114 struct lttng_kernel_ring_buffer
*buf
, uint64_t *timestamp_begin
)
119 static int client_timestamp_end(const struct lttng_kernel_ring_buffer_config
*config
,
120 struct lttng_kernel_ring_buffer
*bufb
,
121 uint64_t *timestamp_end
)
126 static int client_events_discarded(const struct lttng_kernel_ring_buffer_config
*config
,
127 struct lttng_kernel_ring_buffer
*bufb
,
128 uint64_t *events_discarded
)
133 static int client_current_timestamp(const struct lttng_kernel_ring_buffer_config
*config
,
134 struct lttng_kernel_ring_buffer
*bufb
,
140 static int client_content_size(const struct lttng_kernel_ring_buffer_config
*config
,
141 struct lttng_kernel_ring_buffer
*bufb
,
142 uint64_t *content_size
)
147 static int client_packet_size(const struct lttng_kernel_ring_buffer_config
*config
,
148 struct lttng_kernel_ring_buffer
*bufb
,
149 uint64_t *packet_size
)
154 static int client_stream_id(const struct lttng_kernel_ring_buffer_config
*config
,
155 struct lttng_kernel_ring_buffer
*bufb
,
161 static int client_sequence_number(const struct lttng_kernel_ring_buffer_config
*config
,
162 struct lttng_kernel_ring_buffer
*bufb
,
169 int client_instance_id(const struct lttng_kernel_ring_buffer_config
*config
,
170 struct lttng_kernel_ring_buffer
*bufb
,
176 static void client_record_get(const struct lttng_kernel_ring_buffer_config
*config
,
177 struct lttng_kernel_ring_buffer_channel
*chan
, struct lttng_kernel_ring_buffer
*buf
,
178 size_t offset
, size_t *header_len
,
179 size_t *payload_len
, u64
*timestamp
)
181 struct event_notifier_record_header header
;
184 ret
= lib_ring_buffer_read(&buf
->backend
, offset
, &header
,
185 offsetof(struct event_notifier_record_header
, header_end
));
186 CHAN_WARN_ON(chan
, ret
!= offsetof(struct event_notifier_record_header
, header_end
));
187 *header_len
= offsetof(struct event_notifier_record_header
, header_end
);
188 *payload_len
= header
.payload_len
;
192 static const struct lttng_kernel_ring_buffer_config client_config
= {
193 .cb
.ring_buffer_clock_read
= client_ring_buffer_clock_read
,
194 .cb
.record_header_size
= client_record_header_size
,
195 .cb
.subbuffer_header_size
= client_packet_header_size
,
196 .cb
.buffer_begin
= client_buffer_begin
,
197 .cb
.buffer_end
= client_buffer_end
,
198 .cb
.buffer_create
= client_buffer_create
,
199 .cb
.buffer_finalize
= client_buffer_finalize
,
200 .cb
.record_get
= client_record_get
,
203 .alloc
= RING_BUFFER_ALLOC_GLOBAL
,
204 .sync
= RING_BUFFER_SYNC_GLOBAL
,
205 .mode
= RING_BUFFER_MODE_TEMPLATE
,
206 .backend
= RING_BUFFER_PAGE
,
207 .output
= RING_BUFFER_OUTPUT_TEMPLATE
,
208 .oops
= RING_BUFFER_OOPS_CONSISTENCY
,
209 .ipi
= RING_BUFFER_NO_IPI_BARRIER
,
210 .wakeup
= RING_BUFFER_WAKEUP_BY_WRITER
,
214 void release_priv_ops(void *priv_ops
)
216 module_put(THIS_MODULE
);
220 void lttng_channel_destroy(struct lttng_kernel_ring_buffer_channel
*chan
)
222 channel_destroy(chan
);
226 struct lttng_kernel_ring_buffer_channel
*_channel_create(const char *name
,
227 void *priv
, void *buf_addr
,
228 size_t subbuf_size
, size_t num_subbuf
,
229 unsigned int switch_timer_interval
,
230 unsigned int read_timer_interval
)
232 struct lttng_event_notifier_group
*event_notifier_group
= priv
;
233 struct lttng_kernel_ring_buffer_channel
*chan
;
235 chan
= channel_create(&client_config
, name
,
236 event_notifier_group
, buf_addr
,
237 subbuf_size
, num_subbuf
, switch_timer_interval
,
238 read_timer_interval
);
241 * Ensure this module is not unloaded before we finish
242 * using lttng_relay_transport.ops.
244 if (!try_module_get(THIS_MODULE
)) {
245 printk(KERN_WARNING
"LTTng: Can't lock event_notifier transport module.\n");
248 chan
->backend
.priv_ops
= <tng_relay_transport
.ops
;
249 chan
->backend
.release_priv_ops
= release_priv_ops
;
254 lttng_channel_destroy(chan
);
259 struct lttng_kernel_ring_buffer
*lttng_buffer_read_open(struct lttng_kernel_ring_buffer_channel
*chan
)
261 struct lttng_kernel_ring_buffer
*buf
;
263 buf
= channel_get_ring_buffer(&client_config
, chan
, 0);
264 if (!lib_ring_buffer_open_read(buf
))
270 int lttng_buffer_has_read_closed_stream(struct lttng_kernel_ring_buffer_channel
*chan
)
272 struct lttng_kernel_ring_buffer
*buf
;
275 for_each_channel_cpu(cpu
, chan
) {
276 buf
= channel_get_ring_buffer(&client_config
, chan
, cpu
);
277 if (!atomic_long_read(&buf
->active_readers
))
284 void lttng_buffer_read_close(struct lttng_kernel_ring_buffer
*buf
)
286 lib_ring_buffer_release_read(buf
);
290 void lttng_write_event_notifier_header(const struct lttng_kernel_ring_buffer_config
*config
,
291 struct lttng_kernel_ring_buffer_ctx
*ctx
)
295 WARN_ON_ONCE(ctx
->data_size
> U32_MAX
);
297 data_size
= (uint32_t) ctx
->data_size
;
299 lib_ring_buffer_write(config
, ctx
, &data_size
, sizeof(data_size
));
301 lib_ring_buffer_align_ctx(ctx
, ctx
->largest_align
);
305 int lttng_event_reserve(struct lttng_kernel_ring_buffer_ctx
*ctx
)
307 struct lttng_kernel_ring_buffer_channel
*chan
= ctx
->client_priv
;
310 memset(&ctx
->priv
, 0, sizeof(ctx
->priv
));
311 ctx
->priv
.chan
= chan
;
313 ret
= lib_ring_buffer_reserve(&client_config
, ctx
, NULL
);
316 lib_ring_buffer_backend_get_pages(&client_config
, ctx
,
317 &ctx
->priv
.backend_pages
);
319 lttng_write_event_notifier_header(&client_config
, ctx
);
324 void lttng_event_commit(struct lttng_kernel_ring_buffer_ctx
*ctx
)
326 lib_ring_buffer_commit(&client_config
, ctx
);
330 void lttng_event_write(struct lttng_kernel_ring_buffer_ctx
*ctx
, const void *src
,
331 size_t len
, size_t alignment
)
333 lib_ring_buffer_align_ctx(ctx
, alignment
);
334 lib_ring_buffer_write(&client_config
, ctx
, src
, len
);
338 void lttng_event_write_from_user(struct lttng_kernel_ring_buffer_ctx
*ctx
,
339 const void __user
*src
, size_t len
, size_t alignment
)
341 lib_ring_buffer_align_ctx(ctx
, alignment
);
342 lib_ring_buffer_copy_from_user_inatomic(&client_config
, ctx
, src
, len
);
346 void lttng_event_memset(struct lttng_kernel_ring_buffer_ctx
*ctx
,
349 lib_ring_buffer_memset(&client_config
, ctx
, c
, len
);
353 void lttng_event_strcpy(struct lttng_kernel_ring_buffer_ctx
*ctx
, const char *src
,
356 lib_ring_buffer_strcpy(&client_config
, ctx
, src
, len
, '#');
360 size_t lttng_packet_avail_size(struct lttng_kernel_ring_buffer_channel
*chan
)
362 unsigned long o_begin
;
363 struct lttng_kernel_ring_buffer
*buf
;
365 buf
= chan
->backend
.buf
; /* Only for global buffer ! */
366 o_begin
= v_read(&client_config
, &buf
->offset
);
367 if (subbuf_offset(o_begin
, chan
) != 0) {
368 return chan
->backend
.subbuf_size
- subbuf_offset(o_begin
, chan
);
370 return chan
->backend
.subbuf_size
- subbuf_offset(o_begin
, chan
)
371 - sizeof(struct event_notifier_packet_header
);
376 wait_queue_head_t
*lttng_get_writer_buf_wait_queue(struct lttng_kernel_ring_buffer_channel
*chan
, int cpu
)
378 struct lttng_kernel_ring_buffer
*buf
= channel_get_ring_buffer(&client_config
,
380 return &buf
->write_wait
;
384 wait_queue_head_t
*lttng_get_hp_wait_queue(struct lttng_kernel_ring_buffer_channel
*chan
)
386 return &chan
->hp_wait
;
390 int lttng_is_finalized(struct lttng_kernel_ring_buffer_channel
*chan
)
392 return lib_ring_buffer_channel_is_finalized(chan
);
396 int lttng_is_disabled(struct lttng_kernel_ring_buffer_channel
*chan
)
398 return lib_ring_buffer_channel_is_disabled(chan
);
401 static struct lttng_transport lttng_relay_transport
= {
402 .name
= "relay-" RING_BUFFER_MODE_TEMPLATE_STRING
,
403 .owner
= THIS_MODULE
,
405 .priv
= __LTTNG_COMPOUND_LITERAL(struct lttng_kernel_channel_buffer_ops_private
, {
406 .pub
= <tng_relay_transport
.ops
,
407 .channel_create
= _channel_create
,
408 .channel_destroy
= lttng_channel_destroy
,
409 .buffer_read_open
= lttng_buffer_read_open
,
410 .buffer_has_read_closed_stream
=
411 lttng_buffer_has_read_closed_stream
,
412 .buffer_read_close
= lttng_buffer_read_close
,
413 .packet_avail_size
= lttng_packet_avail_size
,
414 .get_writer_buf_wait_queue
= lttng_get_writer_buf_wait_queue
,
415 .get_hp_wait_queue
= lttng_get_hp_wait_queue
,
416 .is_finalized
= lttng_is_finalized
,
417 .is_disabled
= lttng_is_disabled
,
418 .timestamp_begin
= client_timestamp_begin
,
419 .timestamp_end
= client_timestamp_end
,
420 .events_discarded
= client_events_discarded
,
421 .content_size
= client_content_size
,
422 .packet_size
= client_packet_size
,
423 .stream_id
= client_stream_id
,
424 .current_timestamp
= client_current_timestamp
,
425 .sequence_number
= client_sequence_number
,
426 .instance_id
= client_instance_id
,
428 .event_reserve
= lttng_event_reserve
,
429 .event_commit
= lttng_event_commit
,
430 .event_write_from_user
= lttng_event_write_from_user
,
431 .event_memset
= lttng_event_memset
,
432 .event_write
= lttng_event_write
,
433 .event_strcpy
= lttng_event_strcpy
,
437 static int __init
lttng_ring_buffer_event_notifier_client_init(void)
440 * This vmalloc sync all also takes care of the lib ring buffer
441 * vmalloc'd module pages when it is built as a module into LTTng.
443 wrapper_vmalloc_sync_mappings();
444 lttng_transport_register(<tng_relay_transport
);
448 module_init(lttng_ring_buffer_event_notifier_client_init
);
450 static void __exit
lttng_ring_buffer_event_notifier_client_exit(void)
452 lttng_transport_unregister(<tng_relay_transport
);
455 module_exit(lttng_ring_buffer_event_notifier_client_exit
);
457 MODULE_LICENSE("GPL and additional rights");
458 MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers@efficios.com>");
459 MODULE_DESCRIPTION("LTTng ring buffer " RING_BUFFER_MODE_TEMPLATE_STRING
461 MODULE_VERSION(__stringify(LTTNG_MODULES_MAJOR_VERSION
) "."
462 __stringify(LTTNG_MODULES_MINOR_VERSION
) "."
463 __stringify(LTTNG_MODULES_PATCHLEVEL_VERSION
)
464 LTTNG_MODULES_EXTRAVERSION
);