00cac1608a341c980a89939e230d88d5f6461a89
[deliverable/lttng-modules.git] / ltt-ring-buffer-client.h
1 /*
2 * ltt-ring-buffer-client.h
3 *
4 * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 *
6 * LTTng lib ring buffer client template.
7 *
8 * Dual LGPL v2.1/GPL v2 license.
9 */
10
11 #include <linux/module.h>
12 #include <linux/types.h>
13 #include "wrapper/symbols.h" /* for wrapper_vmalloc_sync_all() */
14 #include "wrapper/trace-clock.h"
15 #include "ltt-events.h"
16 #include "ltt-tracer.h"
17
18 static const struct lib_ring_buffer_config client_config;
19
20 static u64 client_ring_buffer_clock_read(struct channel *chan)
21 {
22 return lib_ring_buffer_clock_read(chan);
23 }
24
25 static
26 size_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 /**
38 * client_packet_header_size - called on buffer-switch to a new sub-buffer
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 */
44 static size_t client_packet_header_size(void)
45 {
46 return offsetof(struct packet_header, header_end);
47 }
48
49 static void client_buffer_begin(struct lib_ring_buffer *buf, u64 tsc,
50 unsigned int subbuf_idx)
51 {
52 struct channel *chan = buf->backend.chan;
53 struct packet_header *header =
54 (struct packet_header *)
55 lib_ring_buffer_offset_address(&buf->backend,
56 subbuf_idx * chan->backend.subbuf_size);
57
58 header->timestamp_begin = tsc;
59 header->content_size = 0xFFFFFFFF; /* for debugging */
60 write_trace_header(&client_config, header);
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 */
67 static 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;
71 struct packet_header *header =
72 (struct packet_header *)
73 lib_ring_buffer_offset_address(&buf->backend,
74 subbuf_idx * chan->backend.subbuf_size);
75 unsigned long records_lost = 0;
76
77 header->content_size = data_size;
78 header->packet_size = PAGE_ALIGN(data_size);
79 header->timestamp_end = tsc;
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;
84 }
85
86 static int client_buffer_create(struct lib_ring_buffer *buf, void *priv,
87 int cpu, const char *name)
88 {
89 return 0;
90 }
91
92 static void client_buffer_finalize(struct lib_ring_buffer *buf, void *priv, int cpu)
93 {
94 }
95
96 static 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,
99 .cb.subbuffer_header_size = client_packet_header_size,
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,
108 .mode = RING_BUFFER_MODE_TEMPLATE,
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
116 static
117 struct 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)
122 {
123 return channel_create(&client_config, name, session, buf_addr,
124 subbuf_size, num_subbuf, switch_timer_interval,
125 read_timer_interval);
126 }
127
128 static
129 void ltt_channel_destroy(struct channel *chan)
130 {
131 channel_destroy(chan);
132 }
133
134 static
135 struct lib_ring_buffer *ltt_buffer_read_open(struct channel *chan)
136 {
137 struct lib_ring_buffer *buf;
138 int cpu;
139
140 for_each_channel_cpu(cpu, chan) {
141 buf = channel_get_ring_buffer(&client_config, chan, cpu);
142 if (!lib_ring_buffer_open_read(buf))
143 return buf;
144 }
145 return NULL;
146 }
147
148 static
149 void ltt_buffer_read_close(struct lib_ring_buffer *buf)
150 {
151 lib_ring_buffer_release_read(buf);
152
153 }
154
155 int 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
169 put:
170 lib_ring_buffer_put_cpu(&client_config);
171 return ret;
172 }
173
174 void 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
180 void 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 }
185
186 static struct ltt_transport ltt_relay_transport = {
187 .name = "relay-" RING_BUFFER_MODE_TEMPLATE_STRING,
188 .owner = THIS_MODULE,
189 .ops = {
190 .channel_create = _channel_create,
191 .channel_destroy = ltt_channel_destroy,
192 .buffer_read_open = ltt_buffer_read_open,
193 .buffer_read_close = ltt_buffer_read_close,
194 .event_reserve = ltt_event_reserve,
195 .event_commit = ltt_event_commit,
196 .event_write = ltt_event_write,
197 },
198 };
199
200 static int __init ltt_ring_buffer_client_init(void)
201 {
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 */
206 wrapper_vmalloc_sync_all();
207 printk(KERN_INFO "LTT : ltt ring buffer client init\n");
208 ltt_transport_register(&ltt_relay_transport);
209 return 0;
210 }
211
212 module_init(ltt_ring_buffer_client_init);
213
214 static void __exit ltt_ring_buffer_client_exit(void)
215 {
216 printk(KERN_INFO "LTT : ltt ring buffer client exit\n");
217 ltt_transport_unregister(&ltt_relay_transport);
218 }
219
220 module_exit(ltt_ring_buffer_client_exit);
221
222 MODULE_LICENSE("GPL and additional rights");
223 MODULE_AUTHOR("Mathieu Desnoyers");
224 MODULE_DESCRIPTION("LTTng ring buffer " RING_BUFFER_MODE_TEMPLATE_STRING
225 " client");
This page took 0.035597 seconds and 4 git commands to generate.