Update nohz
[lttng-modules.git] / ltt-ring-buffer-client.h
CommitLineData
7514523f 1/*
3d084699 2 * ltt-ring-buffer-client.h
7514523f
MD
3 *
4 * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 *
3d084699 6 * LTTng lib ring buffer client template.
7514523f
MD
7 *
8 * Dual LGPL v2.1/GPL v2 license.
9 */
10
11#include <linux/module.h>
c0e31d2e 12#include <linux/types.h>
b13f3ebe 13#include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */
f3bc08c5 14#include "wrapper/trace-clock.h"
c0e31d2e 15#include "ltt-events.h"
7514523f
MD
16#include "ltt-tracer.h"
17
7514523f
MD
18static const struct lib_ring_buffer_config client_config;
19
20static u64 client_ring_buffer_clock_read(struct channel *chan)
21{
22 return lib_ring_buffer_clock_read(chan);
23}
24
1e2015dc 25static
7514523f
MD
26size_t client_record_header_size(const struct lib_ring_buffer_config *config,
27 struct channel *chan, size_t offset,
28 size_t data_size,
29 size_t *pre_header_padding,
30 unsigned int rflags,
31 struct lib_ring_buffer_ctx *ctx)
32{
33 return record_header_size(config, chan, offset, data_size,
34 pre_header_padding, rflags, ctx);
35}
36
37/**
1c25284c 38 * client_packet_header_size - called on buffer-switch to a new sub-buffer
7514523f
MD
39 *
40 * Return header size without padding after the structure. Don't use packed
41 * structure because gcc generates inefficient code on some architectures
42 * (powerpc, mips..)
43 */
1c25284c 44static size_t client_packet_header_size(void)
7514523f 45{
1c25284c 46 return offsetof(struct packet_header, header_end);
7514523f
MD
47}
48
49static void client_buffer_begin(struct lib_ring_buffer *buf, u64 tsc,
50 unsigned int subbuf_idx)
51{
52 struct channel *chan = buf->backend.chan;
1c25284c
MD
53 struct packet_header *header =
54 (struct packet_header *)
7514523f
MD
55 lib_ring_buffer_offset_address(&buf->backend,
56 subbuf_idx * chan->backend.subbuf_size);
57
1c25284c
MD
58 header->timestamp_begin = tsc;
59 header->content_size = 0xFFFFFFFF; /* for debugging */
60 write_trace_header(&client_config, header);
7514523f
MD
61}
62
63/*
64 * offset is assumed to never be 0 here : never deliver a completely empty
65 * subbuffer. data_size is between 1 and subbuf_size.
66 */
67static void client_buffer_end(struct lib_ring_buffer *buf, u64 tsc,
68 unsigned int subbuf_idx, unsigned long data_size)
69{
70 struct channel *chan = buf->backend.chan;
1c25284c
MD
71 struct packet_header *header =
72 (struct packet_header *)
7514523f
MD
73 lib_ring_buffer_offset_address(&buf->backend,
74 subbuf_idx * chan->backend.subbuf_size);
75 unsigned long records_lost = 0;
76
1c25284c
MD
77 header->content_size = data_size;
78 header->packet_size = PAGE_ALIGN(data_size);
79 header->timestamp_end = tsc;
7514523f
MD
80 records_lost += lib_ring_buffer_get_records_lost_full(&client_config, buf);
81 records_lost += lib_ring_buffer_get_records_lost_wrap(&client_config, buf);
82 records_lost += lib_ring_buffer_get_records_lost_big(&client_config, buf);
83 header->events_lost = records_lost;
7514523f
MD
84}
85
86static int client_buffer_create(struct lib_ring_buffer *buf, void *priv,
87 int cpu, const char *name)
88{
1c25284c 89 return 0;
7514523f
MD
90}
91
92static void client_buffer_finalize(struct lib_ring_buffer *buf, void *priv, int cpu)
93{
7514523f
MD
94}
95
96static const struct lib_ring_buffer_config client_config = {
97 .cb.ring_buffer_clock_read = client_ring_buffer_clock_read,
98 .cb.record_header_size = client_record_header_size,
1c25284c 99 .cb.subbuffer_header_size = client_packet_header_size,
7514523f
MD
100 .cb.buffer_begin = client_buffer_begin,
101 .cb.buffer_end = client_buffer_end,
102 .cb.buffer_create = client_buffer_create,
103 .cb.buffer_finalize = client_buffer_finalize,
104
105 .tsc_bits = 32,
106 .alloc = RING_BUFFER_ALLOC_PER_CPU,
107 .sync = RING_BUFFER_SYNC_PER_CPU,
3d084699 108 .mode = RING_BUFFER_MODE_TEMPLATE,
7514523f
MD
109 .backend = RING_BUFFER_PAGE,
110 .output = RING_BUFFER_SPLICE,
111 .oops = RING_BUFFER_OOPS_CONSISTENCY,
112 .ipi = RING_BUFFER_IPI_BARRIER,
113 .wakeup = RING_BUFFER_WAKEUP_BY_TIMER,
114};
115
1e2015dc 116static
1c25284c
MD
117struct channel *_channel_create(const char *name,
118 struct ltt_session *session, void *buf_addr,
119 size_t subbuf_size, size_t num_subbuf,
120 unsigned int switch_timer_interval,
121 unsigned int read_timer_interval)
7514523f 122{
1c25284c 123 return channel_create(&client_config, name, session, buf_addr,
7514523f
MD
124 subbuf_size, num_subbuf, switch_timer_interval,
125 read_timer_interval);
7514523f
MD
126}
127
1e2015dc 128static
7514523f
MD
129void ltt_channel_destroy(struct channel *chan)
130{
7514523f 131 channel_destroy(chan);
7514523f
MD
132}
133
ad1c05e1
MD
134static
135struct lib_ring_buffer *ltt_buffer_read_open(struct channel *chan)
136{
137 struct lib_ring_buffer *buf;
138 int cpu;
139
1c25284c
MD
140 for_each_channel_cpu(cpu, chan) {
141 buf = channel_get_ring_buffer(&client_config, chan, cpu);
ad1c05e1
MD
142 if (!lib_ring_buffer_open_read(buf))
143 return buf;
144 }
145 return NULL;
146}
147
148static
1c25284c 149void ltt_buffer_read_close(struct lib_ring_buffer *buf)
ad1c05e1
MD
150{
151 lib_ring_buffer_release_read(buf);
1c25284c
MD
152
153}
154
155int ltt_event_reserve(struct lib_ring_buffer_ctx *ctx)
156{
157 int ret, cpu;
158
159 cpu = lib_ring_buffer_get_cpu(&client_config);
160 if (cpu < 0)
161 return -EPERM;
162 ctx->cpu = cpu;
163
164 ret = lib_ring_buffer_reserve(&client_config, ctx);
165 if (ret)
166 goto put;
167 return ret;
168
169put:
170 lib_ring_buffer_put_cpu(&client_config);
171 return ret;
ad1c05e1
MD
172}
173
1c25284c
MD
174void ltt_event_commit(struct lib_ring_buffer_ctx *ctx)
175{
176 lib_ring_buffer_commit(&client_config, ctx);
177 lib_ring_buffer_put_cpu(&client_config);
178}
179
e763dbf5
MD
180void ltt_event_write(struct lib_ring_buffer_ctx *ctx, const void *src,
181 size_t len)
182{
183 lib_ring_buffer_write(&client_config, ctx, src, len);
184}
1c25284c 185
7514523f 186static struct ltt_transport ltt_relay_transport = {
3d084699 187 .name = "relay-" RING_BUFFER_MODE_TEMPLATE_STRING,
7514523f
MD
188 .owner = THIS_MODULE,
189 .ops = {
1c25284c
MD
190 .channel_create = _channel_create,
191 .channel_destroy = ltt_channel_destroy,
ad1c05e1
MD
192 .buffer_read_open = ltt_buffer_read_open,
193 .buffer_read_close = ltt_buffer_read_close,
1c25284c
MD
194 .event_reserve = ltt_event_reserve,
195 .event_commit = ltt_event_commit,
e763dbf5 196 .event_write = ltt_event_write,
7514523f
MD
197 },
198};
199
3d084699 200static int __init ltt_ring_buffer_client_init(void)
7514523f 201{
a509e133
MD
202 /*
203 * This vmalloc sync all also takes care of the lib ring buffer
204 * vmalloc'd module pages when it is built as a module into LTTng.
205 */
6d2a620c 206 wrapper_vmalloc_sync_all();
7514523f
MD
207 printk(KERN_INFO "LTT : ltt ring buffer client init\n");
208 ltt_transport_register(&ltt_relay_transport);
209 return 0;
210}
211
1c25284c
MD
212module_init(ltt_ring_buffer_client_init);
213
3d084699 214static void __exit ltt_ring_buffer_client_exit(void)
7514523f
MD
215{
216 printk(KERN_INFO "LTT : ltt ring buffer client exit\n");
217 ltt_transport_unregister(&ltt_relay_transport);
218}
219
1c25284c
MD
220module_exit(ltt_ring_buffer_client_exit);
221
7514523f
MD
222MODULE_LICENSE("GPL and additional rights");
223MODULE_AUTHOR("Mathieu Desnoyers");
3d084699
MD
224MODULE_DESCRIPTION("LTTng ring buffer " RING_BUFFER_MODE_TEMPLATE_STRING
225 " client");
This page took 0.034952 seconds and 4 git commands to generate.