abb2986c4689a4354d7e49648ea9ce7ca2f0e91a
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
27 #include <ust/kernelcompat.h>
28 #include <ust/marker.h>
33 * ltt_channel_mutex may be nested inside the LTT trace mutex.
34 * ltt_channel_mutex mutex may be nested inside markers mutex.
36 static DEFINE_MUTEX(ltt_channel_mutex
);
37 static LIST_HEAD(ltt_channels
);
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.
45 static unsigned int free_index
;
46 static struct kref index_kref
; /* Keeps track of allocated trace channels */
48 static struct ltt_channel_setting
*lookup_channel(const char *name
)
50 struct ltt_channel_setting
*iter
;
52 list_for_each_entry(iter
, <t_channels
, list
)
53 if (strcmp(name
, iter
->name
) == 0)
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.
63 * Called with lock_markers() and channels mutex held.
65 static void release_channel_setting(struct kref
*kref
)
67 struct ltt_channel_setting
*setting
= container_of(kref
,
68 struct ltt_channel_setting
, kref
);
69 struct ltt_channel_setting
*iter
;
71 if (uatomic_read(&index_kref
.refcount
) == 0
72 && uatomic_read(&setting
->kref
.refcount
) == 0) {
73 list_del(&setting
->list
);
77 list_for_each_entry(iter
, <t_channels
, list
) {
78 iter
->index
= free_index
++;
79 iter
->free_event_id
= 0;
81 /* FIXME: why not run this? */
82 //ust// markers_compact_event_ids();
87 * Perform channel index compaction when the last trace channel is freed.
89 * Called with lock_markers() and channels mutex held.
91 static void release_trace_channel(struct kref
*kref
)
93 struct ltt_channel_setting
*iter
, *n
;
95 list_for_each_entry_safe(iter
, n
, <t_channels
, list
)
96 release_channel_setting(&iter
->kref
);
100 * ltt_channels_register - Register a trace channel.
101 * @name: channel name
105 int ltt_channels_register(const char *name
)
107 struct ltt_channel_setting
*setting
;
110 mutex_lock(<t_channel_mutex
);
111 setting
= lookup_channel(name
);
113 if (uatomic_read(&setting
->kref
.refcount
) == 0)
116 kref_get(&setting
->kref
);
120 setting
= zmalloc(sizeof(*setting
));
125 list_add(&setting
->list
, <t_channels
);
126 strncpy(setting
->name
, name
, PATH_MAX
-1);
127 setting
->index
= free_index
++;
129 kref_init(&setting
->kref
);
131 mutex_unlock(<t_channel_mutex
);
134 //ust// EXPORT_SYMBOL_GPL(ltt_channels_register);
137 * ltt_channels_unregister - Unregister a trace channel.
138 * @name: channel name
140 * Must be called with markers mutex held.
142 int ltt_channels_unregister(const char *name
)
144 struct ltt_channel_setting
*setting
;
147 mutex_lock(<t_channel_mutex
);
148 setting
= lookup_channel(name
);
149 if (!setting
|| uatomic_read(&setting
->kref
.refcount
) == 0) {
153 kref_put(&setting
->kref
, release_channel_setting
);
155 mutex_unlock(<t_channel_mutex
);
158 //ust// EXPORT_SYMBOL_GPL(ltt_channels_unregister);
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
166 int ltt_channels_set_default(const char *name
,
167 unsigned int subbuf_size
,
168 unsigned int subbuf_cnt
)
170 struct ltt_channel_setting
*setting
;
173 mutex_lock(<t_channel_mutex
);
174 setting
= lookup_channel(name
);
175 if (!setting
|| uatomic_read(&setting
->kref
.refcount
) == 0) {
179 setting
->subbuf_size
= subbuf_size
;
180 setting
->subbuf_cnt
= subbuf_cnt
;
182 mutex_unlock(<t_channel_mutex
);
185 //ust// EXPORT_SYMBOL_GPL(ltt_channels_set_default);
188 * ltt_channels_get_name_from_index - get channel name from channel index
189 * @index: channel index
191 * Allows to lookup the channel name given its index. Done to keep the name
192 * information outside of each trace channel instance.
194 const char *ltt_channels_get_name_from_index(unsigned int index
)
196 struct ltt_channel_setting
*iter
;
198 list_for_each_entry(iter
, <t_channels
, list
)
199 if (iter
->index
== index
&& uatomic_read(&iter
->kref
.refcount
))
203 //ust// EXPORT_SYMBOL_GPL(ltt_channels_get_name_from_index);
205 static struct ltt_channel_setting
*
206 ltt_channels_get_setting_from_name(const char *name
)
208 struct ltt_channel_setting
*iter
;
210 list_for_each_entry(iter
, <t_channels
, list
)
211 if (!strcmp(iter
->name
, name
)
212 && uatomic_read(&iter
->kref
.refcount
))
218 * ltt_channels_get_index_from_name - get channel index from channel name
219 * @name: channel name
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.
225 int ltt_channels_get_index_from_name(const char *name
)
227 struct ltt_channel_setting
*setting
;
229 setting
= ltt_channels_get_setting_from_name(name
);
231 return setting
->index
;
235 //ust// EXPORT_SYMBOL_GPL(ltt_channels_get_index_from_name);
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
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.
247 struct ust_channel
*ltt_channels_trace_alloc(unsigned int *nr_channels
,
251 struct ust_channel
*channel
= NULL
;
252 struct ltt_channel_setting
*iter
;
254 mutex_lock(<t_channel_mutex
);
256 WARN("ltt_channels_trace_alloc: no free_index; are there any probes connected?");
259 if (!uatomic_read(&index_kref
.refcount
))
260 kref_init(&index_kref
);
262 kref_get(&index_kref
);
263 *nr_channels
= free_index
;
264 channel
= zmalloc(sizeof(struct ust_channel
) * free_index
);
266 WARN("ltt_channel_struct: channel null after alloc");
269 list_for_each_entry(iter
, <t_channels
, list
) {
270 if (!uatomic_read(&iter
->kref
.refcount
))
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
;
279 mutex_unlock(<t_channel_mutex
);
282 //ust// EXPORT_SYMBOL_GPL(ltt_channels_trace_alloc);
285 * ltt_channels_trace_free - Free one trace's channels
286 * @channels: channels to free
288 * Called with trace lock held. The actual channel buffers must be freed before
289 * this function is called.
291 void ltt_channels_trace_free(struct ust_channel
*channels
)
294 mutex_lock(<t_channel_mutex
);
296 kref_put(&index_kref
, release_trace_channel
);
297 mutex_unlock(<t_channel_mutex
);
300 //ust// EXPORT_SYMBOL_GPL(ltt_channels_trace_free);
303 * _ltt_channels_get_event_id - get next event ID for a marker
304 * @channel: channel name
307 * Returns a unique event ID (for this channel) or < 0 on error.
308 * Must be called with channels mutex held.
310 int _ltt_channels_get_event_id(const char *channel
, const char *name
)
312 struct ltt_channel_setting
*setting
;
315 setting
= ltt_channels_get_setting_from_name(channel
);
320 if (strcmp(channel
, "metadata") == 0) {
321 if (strcmp(name
, "core_marker_id") == 0)
323 else if (strcmp(name
, "core_marker_format") == 0)
325 else if (strcmp(name
, "testev") == 0)
331 if (setting
->free_event_id
== EVENTS_PER_CHANNEL
- 1) {
335 ret
= setting
->free_event_id
++;
341 * ltt_channels_get_event_id - get next event ID for a marker
342 * @channel: channel name
345 * Returns a unique event ID (for this channel) or < 0 on error.
347 int ltt_channels_get_event_id(const char *channel
, const char *name
)
351 mutex_lock(<t_channel_mutex
);
352 ret
= _ltt_channels_get_event_id(channel
, name
);
353 mutex_unlock(<t_channel_mutex
);
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.088313 seconds and 3 git commands to generate.