kmalloc, kfree, etc => malloc, free, etc
[ust.git] / libust / channels.c
1 /*
2 * ltt/ltt-channels.c
3 *
4 * (C) Copyright 2008 - Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
5 *
6 * LTTng channel management.
7 *
8 * Author:
9 * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26 #include <stdlib.h>
27 #include <ust/kernelcompat.h>
28 #include <ust/marker.h>
29 #include "channels.h"
30 #include "usterr.h"
31
32 /*
33 * ltt_channel_mutex may be nested inside the LTT trace mutex.
34 * ltt_channel_mutex mutex may be nested inside markers mutex.
35 */
36 static DEFINE_MUTEX(ltt_channel_mutex);
37 static LIST_HEAD(ltt_channels);
38 /*
39 * Index of next channel in array. Makes sure that as long as a trace channel is
40 * allocated, no array index will be re-used when a channel is freed and then
41 * another channel is allocated. This index is cleared and the array indexeds
42 * get reassigned when the index_kref goes back to 0, which indicates that no
43 * more trace channels are allocated.
44 */
45 static unsigned int free_index;
46 static struct kref index_kref; /* Keeps track of allocated trace channels */
47
48 static struct ltt_channel_setting *lookup_channel(const char *name)
49 {
50 struct ltt_channel_setting *iter;
51
52 list_for_each_entry(iter, &ltt_channels, list)
53 if (strcmp(name, iter->name) == 0)
54 return iter;
55 return NULL;
56 }
57
58 /*
59 * Must be called when channel refcount falls to 0 _and_ also when the last
60 * trace is freed. This function is responsible for compacting the channel and
61 * event IDs when no users are active.
62 *
63 * Called with lock_markers() and channels mutex held.
64 */
65 static void release_channel_setting(struct kref *kref)
66 {
67 struct ltt_channel_setting *setting = container_of(kref,
68 struct ltt_channel_setting, kref);
69 struct ltt_channel_setting *iter;
70
71 if (uatomic_read(&index_kref.refcount) == 0
72 && uatomic_read(&setting->kref.refcount) == 0) {
73 list_del(&setting->list);
74 free(setting);
75
76 free_index = 0;
77 list_for_each_entry(iter, &ltt_channels, list) {
78 iter->index = free_index++;
79 iter->free_event_id = 0;
80 }
81 /* FIXME: why not run this? */
82 //ust// markers_compact_event_ids();
83 }
84 }
85
86 /*
87 * Perform channel index compaction when the last trace channel is freed.
88 *
89 * Called with lock_markers() and channels mutex held.
90 */
91 static void release_trace_channel(struct kref *kref)
92 {
93 struct ltt_channel_setting *iter, *n;
94
95 list_for_each_entry_safe(iter, n, &ltt_channels, list)
96 release_channel_setting(&iter->kref);
97 }
98
99 /**
100 * ltt_channels_register - Register a trace channel.
101 * @name: channel name
102 *
103 * Uses refcounting.
104 */
105 int ltt_channels_register(const char *name)
106 {
107 struct ltt_channel_setting *setting;
108 int ret = 0;
109
110 mutex_lock(&ltt_channel_mutex);
111 setting = lookup_channel(name);
112 if (setting) {
113 if (uatomic_read(&setting->kref.refcount) == 0)
114 goto init_kref;
115 else {
116 kref_get(&setting->kref);
117 goto end;
118 }
119 }
120 setting = zmalloc(sizeof(*setting));
121 if (!setting) {
122 ret = -ENOMEM;
123 goto end;
124 }
125 list_add(&setting->list, &ltt_channels);
126 strncpy(setting->name, name, PATH_MAX-1);
127 setting->index = free_index++;
128 init_kref:
129 kref_init(&setting->kref);
130 end:
131 mutex_unlock(&ltt_channel_mutex);
132 return ret;
133 }
134 //ust// EXPORT_SYMBOL_GPL(ltt_channels_register);
135
136 /**
137 * ltt_channels_unregister - Unregister a trace channel.
138 * @name: channel name
139 *
140 * Must be called with markers mutex held.
141 */
142 int ltt_channels_unregister(const char *name)
143 {
144 struct ltt_channel_setting *setting;
145 int ret = 0;
146
147 mutex_lock(&ltt_channel_mutex);
148 setting = lookup_channel(name);
149 if (!setting || uatomic_read(&setting->kref.refcount) == 0) {
150 ret = -ENOENT;
151 goto end;
152 }
153 kref_put(&setting->kref, release_channel_setting);
154 end:
155 mutex_unlock(&ltt_channel_mutex);
156 return ret;
157 }
158 //ust// EXPORT_SYMBOL_GPL(ltt_channels_unregister);
159
160 /**
161 * ltt_channels_set_default - Set channel default behavior.
162 * @name: default channel name
163 * @subbuf_size: size of the subbuffers
164 * @subbuf_cnt: number of subbuffers
165 */
166 int ltt_channels_set_default(const char *name,
167 unsigned int subbuf_size,
168 unsigned int subbuf_cnt)
169 {
170 struct ltt_channel_setting *setting;
171 int ret = 0;
172
173 mutex_lock(&ltt_channel_mutex);
174 setting = lookup_channel(name);
175 if (!setting || uatomic_read(&setting->kref.refcount) == 0) {
176 ret = -ENOENT;
177 goto end;
178 }
179 setting->subbuf_size = subbuf_size;
180 setting->subbuf_cnt = subbuf_cnt;
181 end:
182 mutex_unlock(&ltt_channel_mutex);
183 return ret;
184 }
185 //ust// EXPORT_SYMBOL_GPL(ltt_channels_set_default);
186
187 /**
188 * ltt_channels_get_name_from_index - get channel name from channel index
189 * @index: channel index
190 *
191 * Allows to lookup the channel name given its index. Done to keep the name
192 * information outside of each trace channel instance.
193 */
194 const char *ltt_channels_get_name_from_index(unsigned int index)
195 {
196 struct ltt_channel_setting *iter;
197
198 list_for_each_entry(iter, &ltt_channels, list)
199 if (iter->index == index && uatomic_read(&iter->kref.refcount))
200 return iter->name;
201 return NULL;
202 }
203 //ust// EXPORT_SYMBOL_GPL(ltt_channels_get_name_from_index);
204
205 static struct ltt_channel_setting *
206 ltt_channels_get_setting_from_name(const char *name)
207 {
208 struct ltt_channel_setting *iter;
209
210 list_for_each_entry(iter, &ltt_channels, list)
211 if (!strcmp(iter->name, name)
212 && uatomic_read(&iter->kref.refcount))
213 return iter;
214 return NULL;
215 }
216
217 /**
218 * ltt_channels_get_index_from_name - get channel index from channel name
219 * @name: channel name
220 *
221 * Allows to lookup the channel index given its name. Done to keep the name
222 * information outside of each trace channel instance.
223 * Returns -1 if not found.
224 */
225 int ltt_channels_get_index_from_name(const char *name)
226 {
227 struct ltt_channel_setting *setting;
228
229 setting = ltt_channels_get_setting_from_name(name);
230 if (setting)
231 return setting->index;
232 else
233 return -1;
234 }
235 //ust// EXPORT_SYMBOL_GPL(ltt_channels_get_index_from_name);
236
237 /**
238 * ltt_channels_trace_alloc - Allocate channel structures for a trace
239 * @subbuf_size: subbuffer size. 0 uses default.
240 * @subbuf_cnt: number of subbuffers per per-cpu buffers. 0 uses default.
241 * @flags: Default channel flags
242 *
243 * Use the current channel list to allocate the channels for a trace.
244 * Called with trace lock held. Does not perform the trace buffer allocation,
245 * because we must let the user overwrite specific channel sizes.
246 */
247 struct ust_channel *ltt_channels_trace_alloc(unsigned int *nr_channels,
248 int overwrite,
249 int active)
250 {
251 struct ust_channel *channel = NULL;
252 struct ltt_channel_setting *iter;
253
254 mutex_lock(&ltt_channel_mutex);
255 if (!free_index) {
256 WARN("ltt_channels_trace_alloc: no free_index; are there any probes connected?");
257 goto end;
258 }
259 if (!uatomic_read(&index_kref.refcount))
260 kref_init(&index_kref);
261 else
262 kref_get(&index_kref);
263 *nr_channels = free_index;
264 channel = zmalloc(sizeof(struct ust_channel) * free_index);
265 if (!channel) {
266 WARN("ltt_channel_struct: channel null after alloc");
267 goto end;
268 }
269 list_for_each_entry(iter, &ltt_channels, list) {
270 if (!uatomic_read(&iter->kref.refcount))
271 continue;
272 channel[iter->index].subbuf_size = iter->subbuf_size;
273 channel[iter->index].subbuf_cnt = iter->subbuf_cnt;
274 channel[iter->index].overwrite = overwrite;
275 channel[iter->index].active = active;
276 channel[iter->index].channel_name = iter->name;
277 }
278 end:
279 mutex_unlock(&ltt_channel_mutex);
280 return channel;
281 }
282 //ust// EXPORT_SYMBOL_GPL(ltt_channels_trace_alloc);
283
284 /**
285 * ltt_channels_trace_free - Free one trace's channels
286 * @channels: channels to free
287 *
288 * Called with trace lock held. The actual channel buffers must be freed before
289 * this function is called.
290 */
291 void ltt_channels_trace_free(struct ust_channel *channels)
292 {
293 lock_markers();
294 mutex_lock(&ltt_channel_mutex);
295 free(channels);
296 kref_put(&index_kref, release_trace_channel);
297 mutex_unlock(&ltt_channel_mutex);
298 unlock_markers();
299 }
300 //ust// EXPORT_SYMBOL_GPL(ltt_channels_trace_free);
301
302 /**
303 * _ltt_channels_get_event_id - get next event ID for a marker
304 * @channel: channel name
305 * @name: event name
306 *
307 * Returns a unique event ID (for this channel) or < 0 on error.
308 * Must be called with channels mutex held.
309 */
310 int _ltt_channels_get_event_id(const char *channel, const char *name)
311 {
312 struct ltt_channel_setting *setting;
313 int ret;
314
315 setting = ltt_channels_get_setting_from_name(channel);
316 if (!setting) {
317 ret = -ENOENT;
318 goto end;
319 }
320 if (strcmp(channel, "metadata") == 0) {
321 if (strcmp(name, "core_marker_id") == 0)
322 ret = 0;
323 else if (strcmp(name, "core_marker_format") == 0)
324 ret = 1;
325 else if (strcmp(name, "testev") == 0)
326 ret = 2;
327 else
328 ret = -ENOENT;
329 goto end;
330 }
331 if (setting->free_event_id == EVENTS_PER_CHANNEL - 1) {
332 ret = -ENOSPC;
333 goto end;
334 }
335 ret = setting->free_event_id++;
336 end:
337 return ret;
338 }
339
340 /**
341 * ltt_channels_get_event_id - get next event ID for a marker
342 * @channel: channel name
343 * @name: event name
344 *
345 * Returns a unique event ID (for this channel) or < 0 on error.
346 */
347 int ltt_channels_get_event_id(const char *channel, const char *name)
348 {
349 int ret;
350
351 mutex_lock(&ltt_channel_mutex);
352 ret = _ltt_channels_get_event_id(channel, name);
353 mutex_unlock(&ltt_channel_mutex);
354 return ret;
355 }
356
357 //ust// MODULE_LICENSE("GPL");
358 //ust// MODULE_AUTHOR("Mathieu Desnoyers");
359 //ust// MODULE_DESCRIPTION("Linux Trace Toolkit Next Generation Channel Management");
This page took 0.035673 seconds and 4 git commands to generate.