4 * (C) Copyright 2008 - Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
6 * LTTng channel management.
9 * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
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.
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.
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
26 //ust// #include <linux/module.h>
27 //ust// #include <linux/ltt-channels.h>
28 //ust// #include <linux/mutex.h>
29 //ust// #include <linux/vmalloc.h>
31 #include <ust/kernelcompat.h>
34 #include <ust/marker.h>
37 * ltt_channel_mutex may be nested inside the LTT trace mutex.
38 * ltt_channel_mutex mutex may be nested inside markers mutex.
40 static DEFINE_MUTEX(ltt_channel_mutex
);
41 static LIST_HEAD(ltt_channels
);
43 * Index of next channel in array. Makes sure that as long as a trace channel is
44 * allocated, no array index will be re-used when a channel is freed and then
45 * another channel is allocated. This index is cleared and the array indexeds
46 * get reassigned when the index_kref goes back to 0, which indicates that no
47 * more trace channels are allocated.
49 static unsigned int free_index
;
50 static struct kref index_kref
; /* Keeps track of allocated trace channels */
52 static struct ltt_channel_setting
*lookup_channel(const char *name
)
54 struct ltt_channel_setting
*iter
;
56 list_for_each_entry(iter
, <t_channels
, list
)
57 if (strcmp(name
, iter
->name
) == 0)
63 * Must be called when channel refcount falls to 0 _and_ also when the last
64 * trace is freed. This function is responsible for compacting the channel and
65 * event IDs when no users are active.
67 * Called with lock_markers() and channels mutex held.
69 static void release_channel_setting(struct kref
*kref
)
71 struct ltt_channel_setting
*setting
= container_of(kref
,
72 struct ltt_channel_setting
, kref
);
73 struct ltt_channel_setting
*iter
;
75 if (atomic_read(&index_kref
.refcount
) == 0
76 && atomic_read(&setting
->kref
.refcount
) == 0) {
77 list_del(&setting
->list
);
81 list_for_each_entry(iter
, <t_channels
, list
) {
82 iter
->index
= free_index
++;
83 iter
->free_event_id
= 0;
85 //ust// markers_compact_event_ids();
90 * Perform channel index compaction when the last trace channel is freed.
92 * Called with lock_markers() and channels mutex held.
94 static void release_trace_channel(struct kref
*kref
)
96 struct ltt_channel_setting
*iter
, *n
;
98 list_for_each_entry_safe(iter
, n
, <t_channels
, list
)
99 release_channel_setting(&iter
->kref
);
103 * ltt_channels_register - Register a trace channel.
104 * @name: channel name
108 int ltt_channels_register(const char *name
)
110 struct ltt_channel_setting
*setting
;
113 mutex_lock(<t_channel_mutex
);
114 setting
= lookup_channel(name
);
116 if (atomic_read(&setting
->kref
.refcount
) == 0)
119 kref_get(&setting
->kref
);
123 setting
= kzalloc(sizeof(*setting
), GFP_KERNEL
);
128 list_add(&setting
->list
, <t_channels
);
129 strncpy(setting
->name
, name
, PATH_MAX
-1);
130 setting
->index
= free_index
++;
132 kref_init(&setting
->kref
);
134 mutex_unlock(<t_channel_mutex
);
137 //ust// EXPORT_SYMBOL_GPL(ltt_channels_register);
140 * ltt_channels_unregister - Unregister a trace channel.
141 * @name: channel name
143 * Must be called with markers mutex held.
145 int ltt_channels_unregister(const char *name
)
147 struct ltt_channel_setting
*setting
;
150 mutex_lock(<t_channel_mutex
);
151 setting
= lookup_channel(name
);
152 if (!setting
|| atomic_read(&setting
->kref
.refcount
) == 0) {
156 kref_put(&setting
->kref
, release_channel_setting
);
158 mutex_unlock(<t_channel_mutex
);
161 //ust// EXPORT_SYMBOL_GPL(ltt_channels_unregister);
164 * ltt_channels_set_default - Set channel default behavior.
165 * @name: default channel name
166 * @subbuf_size: size of the subbuffers
167 * @subbuf_cnt: number of subbuffers
169 int ltt_channels_set_default(const char *name
,
170 unsigned int subbuf_size
,
171 unsigned int subbuf_cnt
)
173 struct ltt_channel_setting
*setting
;
176 mutex_lock(<t_channel_mutex
);
177 setting
= lookup_channel(name
);
178 if (!setting
|| atomic_read(&setting
->kref
.refcount
) == 0) {
182 setting
->subbuf_size
= subbuf_size
;
183 setting
->subbuf_cnt
= subbuf_cnt
;
185 mutex_unlock(<t_channel_mutex
);
188 //ust// EXPORT_SYMBOL_GPL(ltt_channels_set_default);
191 * ltt_channels_get_name_from_index - get channel name from channel index
192 * @index: channel index
194 * Allows to lookup the channel name given its index. Done to keep the name
195 * information outside of each trace channel instance.
197 const char *ltt_channels_get_name_from_index(unsigned int index
)
199 struct ltt_channel_setting
*iter
;
201 list_for_each_entry(iter
, <t_channels
, list
)
202 if (iter
->index
== index
&& atomic_read(&iter
->kref
.refcount
))
206 //ust// EXPORT_SYMBOL_GPL(ltt_channels_get_name_from_index);
208 static struct ltt_channel_setting
*
209 ltt_channels_get_setting_from_name(const char *name
)
211 struct ltt_channel_setting
*iter
;
213 list_for_each_entry(iter
, <t_channels
, list
)
214 if (!strcmp(iter
->name
, name
)
215 && atomic_read(&iter
->kref
.refcount
))
221 * ltt_channels_get_index_from_name - get channel index from channel name
222 * @name: channel name
224 * Allows to lookup the channel index given its name. Done to keep the name
225 * information outside of each trace channel instance.
226 * Returns -1 if not found.
228 int ltt_channels_get_index_from_name(const char *name
)
230 struct ltt_channel_setting
*setting
;
232 setting
= ltt_channels_get_setting_from_name(name
);
234 return setting
->index
;
238 //ust// EXPORT_SYMBOL_GPL(ltt_channels_get_index_from_name);
241 * ltt_channels_trace_alloc - Allocate channel structures for a trace
242 * @subbuf_size: subbuffer size. 0 uses default.
243 * @subbuf_cnt: number of subbuffers per per-cpu buffers. 0 uses default.
244 * @flags: Default channel flags
246 * Use the current channel list to allocate the channels for a trace.
247 * Called with trace lock held. Does not perform the trace buffer allocation,
248 * because we must let the user overwrite specific channel sizes.
250 struct ltt_channel_struct
*ltt_channels_trace_alloc(unsigned int *nr_channels
,
254 struct ltt_channel_struct
*channel
= NULL
;
255 struct ltt_channel_setting
*iter
;
257 mutex_lock(<t_channel_mutex
);
259 WARN("ltt_channels_trace_alloc: no free_index; are there any probes connected?");
262 if (!atomic_read(&index_kref
.refcount
))
263 kref_init(&index_kref
);
265 kref_get(&index_kref
);
266 *nr_channels
= free_index
;
267 channel
= kzalloc(sizeof(struct ltt_channel_struct
) * free_index
,
270 WARN("ltt_channel_struct: channel null after alloc");
273 list_for_each_entry(iter
, <t_channels
, list
) {
274 if (!atomic_read(&iter
->kref
.refcount
))
276 channel
[iter
->index
].subbuf_size
= iter
->subbuf_size
;
277 channel
[iter
->index
].subbuf_cnt
= iter
->subbuf_cnt
;
278 channel
[iter
->index
].overwrite
= overwrite
;
279 channel
[iter
->index
].active
= active
;
280 channel
[iter
->index
].channel_name
= iter
->name
;
283 mutex_unlock(<t_channel_mutex
);
286 //ust// EXPORT_SYMBOL_GPL(ltt_channels_trace_alloc);
289 * ltt_channels_trace_free - Free one trace's channels
290 * @channels: channels to free
292 * Called with trace lock held. The actual channel buffers must be freed before
293 * this function is called.
295 void ltt_channels_trace_free(struct ltt_channel_struct
*channels
)
298 mutex_lock(<t_channel_mutex
);
300 kref_put(&index_kref
, release_trace_channel
);
301 mutex_unlock(<t_channel_mutex
);
304 //ust// EXPORT_SYMBOL_GPL(ltt_channels_trace_free);
307 * _ltt_channels_get_event_id - get next event ID for a marker
308 * @channel: channel name
311 * Returns a unique event ID (for this channel) or < 0 on error.
312 * Must be called with channels mutex held.
314 int _ltt_channels_get_event_id(const char *channel
, const char *name
)
316 struct ltt_channel_setting
*setting
;
319 setting
= ltt_channels_get_setting_from_name(channel
);
324 if (strcmp(channel
, "metadata") == 0) {
325 if (strcmp(name
, "core_marker_id") == 0)
327 else if (strcmp(name
, "core_marker_format") == 0)
329 else if (strcmp(name
, "testev") == 0)
335 if (setting
->free_event_id
== EVENTS_PER_CHANNEL
- 1) {
339 ret
= setting
->free_event_id
++;
345 * ltt_channels_get_event_id - get next event ID for a marker
346 * @channel: channel name
349 * Returns a unique event ID (for this channel) or < 0 on error.
351 int ltt_channels_get_event_id(const char *channel
, const char *name
)
355 mutex_lock(<t_channel_mutex
);
356 ret
= _ltt_channels_get_event_id(channel
, name
);
357 mutex_unlock(<t_channel_mutex
);
361 //ust// MODULE_LICENSE("GPL");
362 //ust// MODULE_AUTHOR("Mathieu Desnoyers");
363 //ust// MODULE_DESCRIPTION("Linux Trace Toolkit Next Generation Channel Management");
This page took 0.037184 seconds and 4 git commands to generate.