1 /* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
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 timestamp
,
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 timestamp
,
99 unsigned int subbuf_idx
, unsigned long data_size
,
100 const struct lttng_kernel_ring_buffer_ctx
*ctx
)
104 static int client_buffer_create(struct lttng_kernel_ring_buffer
*buf
, void *priv
,
105 int cpu
, const char *name
)
110 static void client_buffer_finalize(struct lttng_kernel_ring_buffer
*buf
, void *priv
, int cpu
)
114 static int client_timestamp_begin(const struct lttng_kernel_ring_buffer_config
*config
,
115 struct lttng_kernel_ring_buffer
*buf
, uint64_t *timestamp_begin
)
120 static int client_timestamp_end(const struct lttng_kernel_ring_buffer_config
*config
,
121 struct lttng_kernel_ring_buffer
*bufb
,
122 uint64_t *timestamp_end
)
127 static int client_events_discarded(const struct lttng_kernel_ring_buffer_config
*config
,
128 struct lttng_kernel_ring_buffer
*bufb
,
129 uint64_t *events_discarded
)
134 static int client_current_timestamp(const struct lttng_kernel_ring_buffer_config
*config
,
135 struct lttng_kernel_ring_buffer
*bufb
,
141 static int client_content_size(const struct lttng_kernel_ring_buffer_config
*config
,
142 struct lttng_kernel_ring_buffer
*bufb
,
143 uint64_t *content_size
)
148 static int client_packet_size(const struct lttng_kernel_ring_buffer_config
*config
,
149 struct lttng_kernel_ring_buffer
*bufb
,
150 uint64_t *packet_size
)
155 static int client_stream_id(const struct lttng_kernel_ring_buffer_config
*config
,
156 struct lttng_kernel_ring_buffer
*bufb
,
162 static int client_sequence_number(const struct lttng_kernel_ring_buffer_config
*config
,
163 struct lttng_kernel_ring_buffer
*bufb
,
170 int client_instance_id(const struct lttng_kernel_ring_buffer_config
*config
,
171 struct lttng_kernel_ring_buffer
*bufb
,
177 static void client_record_get(const struct lttng_kernel_ring_buffer_config
*config
,
178 struct lttng_kernel_ring_buffer_channel
*chan
, struct lttng_kernel_ring_buffer
*buf
,
179 size_t offset
, size_t *header_len
,
180 size_t *payload_len
, u64
*timestamp
)
182 struct event_notifier_record_header header
;
185 ret
= lib_ring_buffer_read(&buf
->backend
, offset
, &header
,
186 offsetof(struct event_notifier_record_header
, header_end
));
187 CHAN_WARN_ON(chan
, ret
!= offsetof(struct event_notifier_record_header
, header_end
));
188 *header_len
= offsetof(struct event_notifier_record_header
, header_end
);
189 *payload_len
= header
.payload_len
;
193 static const struct lttng_kernel_ring_buffer_config client_config
= {
194 .cb
.ring_buffer_clock_read
= client_ring_buffer_clock_read
,
195 .cb
.record_header_size
= client_record_header_size
,
196 .cb
.subbuffer_header_size
= client_packet_header_size
,
197 .cb
.buffer_begin
= client_buffer_begin
,
198 .cb
.buffer_end
= client_buffer_end
,
199 .cb
.buffer_create
= client_buffer_create
,
200 .cb
.buffer_finalize
= client_buffer_finalize
,
201 .cb
.record_get
= client_record_get
,
204 .alloc
= RING_BUFFER_ALLOC_GLOBAL
,
205 .sync
= RING_BUFFER_SYNC_GLOBAL
,
206 .mode
= RING_BUFFER_MODE_TEMPLATE
,
207 .backend
= RING_BUFFER_PAGE
,
208 .output
= RING_BUFFER_OUTPUT_TEMPLATE
,
209 .oops
= RING_BUFFER_OOPS_CONSISTENCY
,
210 .ipi
= RING_BUFFER_NO_IPI_BARRIER
,
211 .wakeup
= RING_BUFFER_WAKEUP_BY_WRITER
,
215 void release_priv_ops(void *priv_ops
)
217 module_put(THIS_MODULE
);
221 void lttng_channel_destroy(struct lttng_kernel_ring_buffer_channel
*chan
)
223 channel_destroy(chan
);
227 struct lttng_kernel_ring_buffer_channel
*_channel_create(const char *name
,
228 void *priv
, void *buf_addr
,
229 size_t subbuf_size
, size_t num_subbuf
,
230 unsigned int switch_timer_interval
,
231 unsigned int read_timer_interval
)
233 struct lttng_event_notifier_group
*event_notifier_group
= priv
;
234 struct lttng_kernel_ring_buffer_channel
*chan
;
236 chan
= channel_create(&client_config
, name
,
237 event_notifier_group
, buf_addr
,
238 subbuf_size
, num_subbuf
, switch_timer_interval
,
239 read_timer_interval
);
242 * Ensure this module is not unloaded before we finish
243 * using lttng_relay_transport.ops.
245 if (!try_module_get(THIS_MODULE
)) {
246 printk(KERN_WARNING
"LTTng: Can't lock event_notifier transport module.\n");
249 chan
->backend
.priv_ops
= <tng_relay_transport
.ops
;
250 chan
->backend
.release_priv_ops
= release_priv_ops
;
255 lttng_channel_destroy(chan
);
260 struct lttng_kernel_ring_buffer
*lttng_buffer_read_open(struct lttng_kernel_ring_buffer_channel
*chan
)
262 struct lttng_kernel_ring_buffer
*buf
;
264 buf
= channel_get_ring_buffer(&client_config
, chan
, 0);
265 if (!lib_ring_buffer_open_read(buf
))
271 int lttng_buffer_has_read_closed_stream(struct lttng_kernel_ring_buffer_channel
*chan
)
273 struct lttng_kernel_ring_buffer
*buf
;
276 for_each_channel_cpu(cpu
, chan
) {
277 buf
= channel_get_ring_buffer(&client_config
, chan
, cpu
);
278 if (!atomic_long_read(&buf
->active_readers
))
285 void lttng_buffer_read_close(struct lttng_kernel_ring_buffer
*buf
)
287 lib_ring_buffer_release_read(buf
);
291 void lttng_write_event_notifier_header(const struct lttng_kernel_ring_buffer_config
*config
,
292 struct lttng_kernel_ring_buffer_ctx
*ctx
)
296 WARN_ON_ONCE(ctx
->data_size
> U32_MAX
);
298 data_size
= (uint32_t) ctx
->data_size
;
300 lib_ring_buffer_write(config
, ctx
, &data_size
, sizeof(data_size
));
302 lib_ring_buffer_align_ctx(ctx
, ctx
->largest_align
);
306 int lttng_event_reserve(struct lttng_kernel_ring_buffer_ctx
*ctx
)
308 struct lttng_kernel_ring_buffer_channel
*chan
= ctx
->client_priv
;
311 memset(&ctx
->priv
, 0, sizeof(ctx
->priv
));
312 ctx
->priv
.chan
= chan
;
314 ret
= lib_ring_buffer_reserve(&client_config
, ctx
, NULL
);
317 lib_ring_buffer_backend_get_pages(&client_config
, ctx
,
318 &ctx
->priv
.backend_pages
);
320 lttng_write_event_notifier_header(&client_config
, ctx
);
325 void lttng_event_commit(struct lttng_kernel_ring_buffer_ctx
*ctx
)
327 lib_ring_buffer_commit(&client_config
, ctx
);
331 void lttng_event_write(struct lttng_kernel_ring_buffer_ctx
*ctx
, const void *src
,
332 size_t len
, size_t alignment
)
334 lib_ring_buffer_align_ctx(ctx
, alignment
);
335 lib_ring_buffer_write(&client_config
, ctx
, src
, len
);
339 void lttng_event_write_from_user(struct lttng_kernel_ring_buffer_ctx
*ctx
,
340 const void __user
*src
, size_t len
, size_t alignment
)
342 lib_ring_buffer_align_ctx(ctx
, alignment
);
343 lib_ring_buffer_copy_from_user_inatomic(&client_config
, ctx
, src
, len
);
347 void lttng_event_memset(struct lttng_kernel_ring_buffer_ctx
*ctx
,
350 lib_ring_buffer_memset(&client_config
, ctx
, c
, len
);
354 void lttng_event_strcpy(struct lttng_kernel_ring_buffer_ctx
*ctx
, const char *src
,
357 lib_ring_buffer_strcpy(&client_config
, ctx
, src
, len
, '#');
361 size_t lttng_packet_avail_size(struct lttng_kernel_ring_buffer_channel
*chan
)
363 unsigned long o_begin
;
364 struct lttng_kernel_ring_buffer
*buf
;
366 buf
= chan
->backend
.buf
; /* Only for global buffer ! */
367 o_begin
= v_read(&client_config
, &buf
->offset
);
368 if (subbuf_offset(o_begin
, chan
) != 0) {
369 return chan
->backend
.subbuf_size
- subbuf_offset(o_begin
, chan
);
371 return chan
->backend
.subbuf_size
- subbuf_offset(o_begin
, chan
)
372 - sizeof(struct event_notifier_packet_header
);
377 wait_queue_head_t
*lttng_get_writer_buf_wait_queue(struct lttng_kernel_ring_buffer_channel
*chan
, int cpu
)
379 struct lttng_kernel_ring_buffer
*buf
= channel_get_ring_buffer(&client_config
,
381 return &buf
->write_wait
;
385 wait_queue_head_t
*lttng_get_hp_wait_queue(struct lttng_kernel_ring_buffer_channel
*chan
)
387 return &chan
->hp_wait
;
391 int lttng_is_finalized(struct lttng_kernel_ring_buffer_channel
*chan
)
393 return lib_ring_buffer_channel_is_finalized(chan
);
397 int lttng_is_disabled(struct lttng_kernel_ring_buffer_channel
*chan
)
399 return lib_ring_buffer_channel_is_disabled(chan
);
402 static struct lttng_transport lttng_relay_transport
= {
403 .name
= "relay-" RING_BUFFER_MODE_TEMPLATE_STRING
,
404 .owner
= THIS_MODULE
,
406 .priv
= __LTTNG_COMPOUND_LITERAL(struct lttng_kernel_channel_buffer_ops_private
, {
407 .pub
= <tng_relay_transport
.ops
,
408 .channel_create
= _channel_create
,
409 .channel_destroy
= lttng_channel_destroy
,
410 .buffer_read_open
= lttng_buffer_read_open
,
411 .buffer_has_read_closed_stream
=
412 lttng_buffer_has_read_closed_stream
,
413 .buffer_read_close
= lttng_buffer_read_close
,
414 .packet_avail_size
= lttng_packet_avail_size
,
415 .get_writer_buf_wait_queue
= lttng_get_writer_buf_wait_queue
,
416 .get_hp_wait_queue
= lttng_get_hp_wait_queue
,
417 .is_finalized
= lttng_is_finalized
,
418 .is_disabled
= lttng_is_disabled
,
419 .timestamp_begin
= client_timestamp_begin
,
420 .timestamp_end
= client_timestamp_end
,
421 .events_discarded
= client_events_discarded
,
422 .content_size
= client_content_size
,
423 .packet_size
= client_packet_size
,
424 .stream_id
= client_stream_id
,
425 .current_timestamp
= client_current_timestamp
,
426 .sequence_number
= client_sequence_number
,
427 .instance_id
= client_instance_id
,
429 .event_reserve
= lttng_event_reserve
,
430 .event_commit
= lttng_event_commit
,
431 .event_write_from_user
= lttng_event_write_from_user
,
432 .event_memset
= lttng_event_memset
,
433 .event_write
= lttng_event_write
,
434 .event_strcpy
= lttng_event_strcpy
,
438 static int __init
lttng_ring_buffer_event_notifier_client_init(void)
441 * This vmalloc sync all also takes care of the lib ring buffer
442 * vmalloc'd module pages when it is built as a module into LTTng.
444 wrapper_vmalloc_sync_mappings();
445 lttng_transport_register(<tng_relay_transport
);
449 module_init(lttng_ring_buffer_event_notifier_client_init
);
451 static void __exit
lttng_ring_buffer_event_notifier_client_exit(void)
453 lttng_transport_unregister(<tng_relay_transport
);
456 module_exit(lttng_ring_buffer_event_notifier_client_exit
);
458 MODULE_LICENSE("GPL and additional rights");
459 MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers@efficios.com>");
460 MODULE_DESCRIPTION("LTTng ring buffer " RING_BUFFER_MODE_TEMPLATE_STRING
462 MODULE_VERSION(__stringify(LTTNG_MODULES_MAJOR_VERSION
) "."
463 __stringify(LTTNG_MODULES_MINOR_VERSION
) "."
464 __stringify(LTTNG_MODULES_PATCHLEVEL_VERSION
)
465 LTTNG_MODULES_EXTRAVERSION
);