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"
22 * ltt_channel_mutex may be nested inside the LTT trace mutex.
23 * ltt_channel_mutex mutex may be nested inside markers mutex.
25 static DEFINE_MUTEX(ltt_channel_mutex
);
26 static LIST_HEAD(ltt_channels
);
28 * Index of next channel in array. Makes sure that as long as a trace channel is
29 * allocated, no array index will be re-used when a channel is freed and then
30 * another channel is allocated. This index is cleared and the array indexeds
31 * get reassigned when the index_kref goes back to 0, which indicates that no
32 * more trace channels are allocated.
34 static unsigned int free_index
;
35 static struct kref index_kref
; /* Keeps track of allocated trace channels */
37 static struct ltt_channel_setting
*lookup_channel(const char *name
)
39 struct ltt_channel_setting
*iter
;
41 list_for_each_entry(iter
, <t_channels
, list
)
42 if (strcmp(name
, iter
->name
) == 0)
48 * Must be called when channel refcount falls to 0 _and_ also when the last
49 * trace is freed. This function is responsible for compacting the channel and
50 * event IDs when no users are active.
52 * Called with lock_markers() and channels mutex held.
54 static void release_channel_setting(struct kref
*kref
)
56 struct ltt_channel_setting
*setting
= container_of(kref
,
57 struct ltt_channel_setting
, kref
);
58 struct ltt_channel_setting
*iter
;
60 if (atomic_read(&index_kref
.refcount
) == 0
61 && atomic_read(&setting
->kref
.refcount
) == 0) {
62 list_del(&setting
->list
);
66 list_for_each_entry(iter
, <t_channels
, list
) {
67 iter
->index
= free_index
++;
68 iter
->free_event_id
= 0;
70 //ust// markers_compact_event_ids();
75 * Perform channel index compaction when the last trace channel is freed.
77 * Called with lock_markers() and channels mutex held.
79 static void release_trace_channel(struct kref
*kref
)
81 struct ltt_channel_setting
*iter
, *n
;
83 list_for_each_entry_safe(iter
, n
, <t_channels
, list
)
84 release_channel_setting(&iter
->kref
);
88 * ltt_channels_register - Register a trace channel.
93 int ltt_channels_register(const char *name
)
95 struct ltt_channel_setting
*setting
;
98 mutex_lock(<t_channel_mutex
);
99 setting
= lookup_channel(name
);
101 if (atomic_read(&setting
->kref
.refcount
) == 0)
104 kref_get(&setting
->kref
);
108 setting
= kzalloc(sizeof(*setting
), GFP_KERNEL
);
113 list_add(&setting
->list
, <t_channels
);
114 strncpy(setting
->name
, name
, PATH_MAX
-1);
115 setting
->index
= free_index
++;
117 kref_init(&setting
->kref
);
119 mutex_unlock(<t_channel_mutex
);
122 //ust// EXPORT_SYMBOL_GPL(ltt_channels_register);
125 * ltt_channels_unregister - Unregister a trace channel.
126 * @name: channel name
128 * Must be called with markers mutex held.
130 int ltt_channels_unregister(const char *name
)
132 struct ltt_channel_setting
*setting
;
135 mutex_lock(<t_channel_mutex
);
136 setting
= lookup_channel(name
);
137 if (!setting
|| atomic_read(&setting
->kref
.refcount
) == 0) {
141 kref_put(&setting
->kref
, release_channel_setting
);
143 mutex_unlock(<t_channel_mutex
);
146 //ust// EXPORT_SYMBOL_GPL(ltt_channels_unregister);
149 * ltt_channels_set_default - Set channel default behavior.
150 * @name: default channel name
151 * @subbuf_size: size of the subbuffers
152 * @subbuf_cnt: number of subbuffers
154 int ltt_channels_set_default(const char *name
,
155 unsigned int subbuf_size
,
156 unsigned int subbuf_cnt
)
158 struct ltt_channel_setting
*setting
;
161 mutex_lock(<t_channel_mutex
);
162 setting
= lookup_channel(name
);
163 if (!setting
|| atomic_read(&setting
->kref
.refcount
) == 0) {
167 setting
->subbuf_size
= subbuf_size
;
168 setting
->subbuf_cnt
= subbuf_cnt
;
170 mutex_unlock(<t_channel_mutex
);
173 //ust// EXPORT_SYMBOL_GPL(ltt_channels_set_default);
176 * ltt_channels_get_name_from_index - get channel name from channel index
177 * @index: channel index
179 * Allows to lookup the channel name given its index. Done to keep the name
180 * information outside of each trace channel instance.
182 const char *ltt_channels_get_name_from_index(unsigned int index
)
184 struct ltt_channel_setting
*iter
;
186 list_for_each_entry(iter
, <t_channels
, list
)
187 if (iter
->index
== index
&& atomic_read(&iter
->kref
.refcount
))
191 //ust// EXPORT_SYMBOL_GPL(ltt_channels_get_name_from_index);
193 static struct ltt_channel_setting
*
194 ltt_channels_get_setting_from_name(const char *name
)
196 struct ltt_channel_setting
*iter
;
198 list_for_each_entry(iter
, <t_channels
, list
)
199 if (!strcmp(iter
->name
, name
)
200 && atomic_read(&iter
->kref
.refcount
))
206 * ltt_channels_get_index_from_name - get channel index from channel name
207 * @name: channel name
209 * Allows to lookup the channel index given its name. Done to keep the name
210 * information outside of each trace channel instance.
211 * Returns -1 if not found.
213 int ltt_channels_get_index_from_name(const char *name
)
215 struct ltt_channel_setting
*setting
;
217 setting
= ltt_channels_get_setting_from_name(name
);
219 return setting
->index
;
223 //ust// EXPORT_SYMBOL_GPL(ltt_channels_get_index_from_name);
226 * ltt_channels_trace_alloc - Allocate channel structures for a trace
227 * @subbuf_size: subbuffer size. 0 uses default.
228 * @subbuf_cnt: number of subbuffers per per-cpu buffers. 0 uses default.
229 * @flags: Default channel flags
231 * Use the current channel list to allocate the channels for a trace.
232 * Called with trace lock held. Does not perform the trace buffer allocation,
233 * because we must let the user overwrite specific channel sizes.
235 struct ltt_channel_struct
*ltt_channels_trace_alloc(unsigned int *nr_channels
,
239 struct ltt_channel_struct
*channel
= NULL
;
240 struct ltt_channel_setting
*iter
;
242 mutex_lock(<t_channel_mutex
);
244 WARN("ltt_channels_trace_alloc: no free_index; are there any probes connected?");
247 if (!atomic_read(&index_kref
.refcount
))
248 kref_init(&index_kref
);
250 kref_get(&index_kref
);
251 *nr_channels
= free_index
;
252 channel
= kzalloc(sizeof(struct ltt_channel_struct
) * free_index
,
255 WARN("ltt_channel_struct: channel null after alloc");
258 list_for_each_entry(iter
, <t_channels
, list
) {
259 if (!atomic_read(&iter
->kref
.refcount
))
261 channel
[iter
->index
].subbuf_size
= iter
->subbuf_size
;
262 channel
[iter
->index
].subbuf_cnt
= iter
->subbuf_cnt
;
263 channel
[iter
->index
].overwrite
= overwrite
;
264 channel
[iter
->index
].active
= active
;
265 channel
[iter
->index
].channel_name
= iter
->name
;
268 mutex_unlock(<t_channel_mutex
);
271 //ust// EXPORT_SYMBOL_GPL(ltt_channels_trace_alloc);
274 * ltt_channels_trace_free - Free one trace's channels
275 * @channels: channels to free
277 * Called with trace lock held. The actual channel buffers must be freed before
278 * this function is called.
280 void ltt_channels_trace_free(struct ltt_channel_struct
*channels
)
283 mutex_lock(<t_channel_mutex
);
285 kref_put(&index_kref
, release_trace_channel
);
286 mutex_unlock(<t_channel_mutex
);
289 //ust// EXPORT_SYMBOL_GPL(ltt_channels_trace_free);
292 * _ltt_channels_get_event_id - get next event ID for a marker
293 * @channel: channel name
296 * Returns a unique event ID (for this channel) or < 0 on error.
297 * Must be called with channels mutex held.
299 int _ltt_channels_get_event_id(const char *channel
, const char *name
)
301 struct ltt_channel_setting
*setting
;
304 setting
= ltt_channels_get_setting_from_name(channel
);
309 if (strcmp(channel
, "metadata") == 0) {
310 if (strcmp(name
, "core_marker_id") == 0)
312 else if (strcmp(name
, "core_marker_format") == 0)
318 if (setting
->free_event_id
== EVENTS_PER_CHANNEL
- 1) {
322 ret
= setting
->free_event_id
++;
328 * ltt_channels_get_event_id - get next event ID for a marker
329 * @channel: channel name
332 * Returns a unique event ID (for this channel) or < 0 on error.
334 int ltt_channels_get_event_id(const char *channel
, const char *name
)
338 mutex_lock(<t_channel_mutex
);
339 ret
= _ltt_channels_get_event_id(channel
, name
);
340 mutex_unlock(<t_channel_mutex
);
344 //ust// MODULE_LICENSE("GPL");
345 //ust// MODULE_AUTHOR("Mathieu Desnoyers");
346 //ust// MODULE_DESCRIPTION("Linux Trace Toolkit Next Generation Channel Management");
This page took 0.040772 seconds and 4 git commands to generate.