1a23afef473c352e6ea61271c929fad7e599584a
4 * (C) Copyright 2008 - Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
6 * LTTng channel management.
9 * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
12 //ust// #include <linux/module.h>
13 //ust// #include <linux/ltt-channels.h>
14 //ust// #include <linux/mutex.h>
15 //ust// #include <linux/vmalloc.h>
17 #include "kernelcompat.h"
21 * ltt_channel_mutex may be nested inside the LTT trace mutex.
22 * ltt_channel_mutex mutex may be nested inside markers mutex.
24 static DEFINE_MUTEX(ltt_channel_mutex
);
25 static LIST_HEAD(ltt_channels
);
27 * Index of next channel in array. Makes sure that as long as a trace channel is
28 * allocated, no array index will be re-used when a channel is freed and then
29 * another channel is allocated. This index is cleared and the array indexeds
30 * get reassigned when the index_kref goes back to 0, which indicates that no
31 * more trace channels are allocated.
33 static unsigned int free_index
;
34 static struct kref index_kref
; /* Keeps track of allocated trace channels */
36 static struct ltt_channel_setting
*lookup_channel(const char *name
)
38 struct ltt_channel_setting
*iter
;
40 list_for_each_entry(iter
, <t_channels
, list
)
41 if (strcmp(name
, iter
->name
) == 0)
47 * Must be called when channel refcount falls to 0 _and_ also when the last
48 * trace is freed. This function is responsible for compacting the channel and
49 * event IDs when no users are active.
51 * Called with lock_markers() and channels mutex held.
53 static void release_channel_setting(struct kref
*kref
)
55 struct ltt_channel_setting
*setting
= container_of(kref
,
56 struct ltt_channel_setting
, kref
);
57 struct ltt_channel_setting
*iter
;
59 if (atomic_read(&index_kref
.refcount
) == 0
60 && atomic_read(&setting
->kref
.refcount
) == 0) {
61 list_del(&setting
->list
);
65 list_for_each_entry(iter
, <t_channels
, list
) {
66 iter
->index
= free_index
++;
67 iter
->free_event_id
= 0;
69 //ust// markers_compact_event_ids();
74 * Perform channel index compaction when the last trace channel is freed.
76 * Called with lock_markers() and channels mutex held.
78 static void release_trace_channel(struct kref
*kref
)
80 struct ltt_channel_setting
*iter
, *n
;
82 list_for_each_entry_safe(iter
, n
, <t_channels
, list
)
83 release_channel_setting(&iter
->kref
);
87 * ltt_channels_register - Register a trace channel.
92 int ltt_channels_register(const char *name
)
94 struct ltt_channel_setting
*setting
;
97 mutex_lock(<t_channel_mutex
);
98 setting
= lookup_channel(name
);
100 if (atomic_read(&setting
->kref
.refcount
) == 0)
103 kref_get(&setting
->kref
);
107 setting
= kzalloc(sizeof(*setting
), GFP_KERNEL
);
112 list_add(&setting
->list
, <t_channels
);
113 strncpy(setting
->name
, name
, PATH_MAX
-1);
114 setting
->index
= free_index
++;
116 kref_init(&setting
->kref
);
118 mutex_unlock(<t_channel_mutex
);
121 //ust// EXPORT_SYMBOL_GPL(ltt_channels_register);
124 * ltt_channels_unregister - Unregister a trace channel.
125 * @name: channel name
127 * Must be called with markers mutex held.
129 int ltt_channels_unregister(const char *name
)
131 struct ltt_channel_setting
*setting
;
134 mutex_lock(<t_channel_mutex
);
135 setting
= lookup_channel(name
);
136 if (!setting
|| atomic_read(&setting
->kref
.refcount
) == 0) {
140 kref_put(&setting
->kref
, release_channel_setting
);
142 mutex_unlock(<t_channel_mutex
);
145 //ust// EXPORT_SYMBOL_GPL(ltt_channels_unregister);
148 * ltt_channels_set_default - Set channel default behavior.
149 * @name: default channel name
150 * @subbuf_size: size of the subbuffers
151 * @subbuf_cnt: number of subbuffers
153 int ltt_channels_set_default(const char *name
,
154 unsigned int subbuf_size
,
155 unsigned int subbuf_cnt
)
157 struct ltt_channel_setting
*setting
;
160 mutex_lock(<t_channel_mutex
);
161 setting
= lookup_channel(name
);
162 if (!setting
|| atomic_read(&setting
->kref
.refcount
) == 0) {
166 setting
->subbuf_size
= subbuf_size
;
167 setting
->subbuf_cnt
= subbuf_cnt
;
169 mutex_unlock(<t_channel_mutex
);
172 //ust// EXPORT_SYMBOL_GPL(ltt_channels_set_default);
175 * ltt_channels_get_name_from_index - get channel name from channel index
176 * @index: channel index
178 * Allows to lookup the channel name given its index. Done to keep the name
179 * information outside of each trace channel instance.
181 const char *ltt_channels_get_name_from_index(unsigned int index
)
183 struct ltt_channel_setting
*iter
;
185 list_for_each_entry(iter
, <t_channels
, list
)
186 if (iter
->index
== index
&& atomic_read(&iter
->kref
.refcount
))
190 //ust// EXPORT_SYMBOL_GPL(ltt_channels_get_name_from_index);
192 static struct ltt_channel_setting
*
193 ltt_channels_get_setting_from_name(const char *name
)
195 struct ltt_channel_setting
*iter
;
197 list_for_each_entry(iter
, <t_channels
, list
)
198 if (!strcmp(iter
->name
, name
)
199 && atomic_read(&iter
->kref
.refcount
))
205 * ltt_channels_get_index_from_name - get channel index from channel name
206 * @name: channel name
208 * Allows to lookup the channel index given its name. Done to keep the name
209 * information outside of each trace channel instance.
210 * Returns -1 if not found.
212 int ltt_channels_get_index_from_name(const char *name
)
214 struct ltt_channel_setting
*setting
;
216 setting
= ltt_channels_get_setting_from_name(name
);
218 return setting
->index
;
222 //ust// EXPORT_SYMBOL_GPL(ltt_channels_get_index_from_name);
225 * ltt_channels_trace_alloc - Allocate channel structures for a trace
226 * @subbuf_size: subbuffer size. 0 uses default.
227 * @subbuf_cnt: number of subbuffers per per-cpu buffers. 0 uses default.
228 * @flags: Default channel flags
230 * Use the current channel list to allocate the channels for a trace.
231 * Called with trace lock held. Does not perform the trace buffer allocation,
232 * because we must let the user overwrite specific channel sizes.
234 struct ltt_channel_struct
*ltt_channels_trace_alloc(unsigned int *nr_channels
,
238 struct ltt_channel_struct
*channel
= NULL
;
239 struct ltt_channel_setting
*iter
;
241 mutex_lock(<t_channel_mutex
);
244 if (!atomic_read(&index_kref
.refcount
))
245 kref_init(&index_kref
);
247 kref_get(&index_kref
);
248 *nr_channels
= free_index
;
249 channel
= kzalloc(sizeof(struct ltt_channel_struct
) * free_index
,
253 list_for_each_entry(iter
, <t_channels
, list
) {
254 if (!atomic_read(&iter
->kref
.refcount
))
256 channel
[iter
->index
].subbuf_size
= iter
->subbuf_size
;
257 channel
[iter
->index
].subbuf_cnt
= iter
->subbuf_cnt
;
258 channel
[iter
->index
].overwrite
= overwrite
;
259 channel
[iter
->index
].active
= active
;
260 channel
[iter
->index
].channel_name
= iter
->name
;
263 mutex_unlock(<t_channel_mutex
);
266 //ust// EXPORT_SYMBOL_GPL(ltt_channels_trace_alloc);
269 * ltt_channels_trace_free - Free one trace's channels
270 * @channels: channels to free
272 * Called with trace lock held. The actual channel buffers must be freed before
273 * this function is called.
275 void ltt_channels_trace_free(struct ltt_channel_struct
*channels
)
278 mutex_lock(<t_channel_mutex
);
280 kref_put(&index_kref
, release_trace_channel
);
281 mutex_unlock(<t_channel_mutex
);
284 //ust// EXPORT_SYMBOL_GPL(ltt_channels_trace_free);
287 * _ltt_channels_get_event_id - get next event ID for a marker
288 * @channel: channel name
291 * Returns a unique event ID (for this channel) or < 0 on error.
292 * Must be called with channels mutex held.
294 int _ltt_channels_get_event_id(const char *channel
, const char *name
)
296 struct ltt_channel_setting
*setting
;
299 setting
= ltt_channels_get_setting_from_name(channel
);
304 if (strcmp(channel
, "metadata") == 0) {
305 if (strcmp(name
, "core_marker_id") == 0)
307 else if (strcmp(name
, "core_marker_format") == 0)
313 if (setting
->free_event_id
== EVENTS_PER_CHANNEL
- 1) {
317 ret
= setting
->free_event_id
++;
323 * ltt_channels_get_event_id - get next event ID for a marker
324 * @channel: channel name
327 * Returns a unique event ID (for this channel) or < 0 on error.
329 int ltt_channels_get_event_id(const char *channel
, const char *name
)
333 mutex_lock(<t_channel_mutex
);
334 ret
= _ltt_channels_get_event_id(channel
, name
);
335 mutex_unlock(<t_channel_mutex
);
339 //ust// MODULE_LICENSE("GPL");
340 //ust// MODULE_AUTHOR("Mathieu Desnoyers");
341 //ust// MODULE_DESCRIPTION("Linux Trace Toolkit Next Generation Channel Management");
This page took 0.037203 seconds and 3 git commands to generate.