4 * (C) Copyright 2005-2008 -
5 * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 * Karim Yaghmour (karim@opersys.com)
23 * Tom Zanussi (zanussi@us.ibm.com)
24 * Bob Wisniewski (bob@watson.ibm.com)
26 * Bob Wisniewski (bob@watson.ibm.com)
29 * 22/09/06, Move to the marker/probes mechanism.
30 * 19/10/05, Complete lockless mechanism.
31 * 27/05/05, Modular redesign and rewrite.
35 #include <urcu/rculist.h>
37 #include <ust/clock.h>
39 #include "tracercore.h"
41 #include "usterr_signal_safe.h"
43 struct chan_info_struct chan_infos
[] = {
44 [LTT_CHANNEL_METADATA
] = {
46 LTT_DEFAULT_SUBBUF_SIZE_LOW
,
47 LTT_DEFAULT_N_SUBBUFS_LOW
,
51 LTT_DEFAULT_SUBBUF_SIZE_HIGH
,
52 LTT_DEFAULT_N_SUBBUFS_HIGH
,
56 static enum ltt_channels
get_channel_type_from_name(const char *name
)
61 return LTT_CHANNEL_UST
;
63 for (i
= 0; i
< ARRAY_SIZE(chan_infos
); i
++)
64 if (chan_infos
[i
].name
&& !strcmp(name
, chan_infos
[i
].name
))
65 return (enum ltt_channels
)i
;
67 return LTT_CHANNEL_UST
;
70 static CDS_LIST_HEAD(ltt_transport_list
);
71 /* transport mutex, nests inside traces mutex (ltt_lock_traces) */
72 static DEFINE_MUTEX(ltt_transport_mutex
);
74 * ltt_transport_register - LTT transport registration
75 * @transport: transport structure
77 * Registers a transport which can be used as output to extract the data out of
78 * LTTng. The module calling this registration function must ensure that no
79 * trap-inducing code will be executed by the transport functions. E.g.
80 * vmalloc_sync_all() must be called between a vmalloc and the moment the memory
81 * is made visible to the transport function. This registration acts as a
82 * vmalloc_sync_all. Therefore, only if the module allocates virtual memory
83 * after its registration must it synchronize the TLBs.
85 void ltt_transport_register(struct ltt_transport
*transport
)
87 pthread_mutex_lock(<t_transport_mutex
);
88 cds_list_add_tail(&transport
->node
, <t_transport_list
);
89 pthread_mutex_unlock(<t_transport_mutex
);
93 * ltt_transport_unregister - LTT transport unregistration
94 * @transport: transport structure
96 void ltt_transport_unregister(struct ltt_transport
*transport
)
98 pthread_mutex_lock(<t_transport_mutex
);
99 cds_list_del(&transport
->node
);
100 pthread_mutex_unlock(<t_transport_mutex
);
103 static inline int is_channel_overwrite(enum ltt_channels chan
,
104 enum trace_mode mode
)
107 case LTT_TRACE_NORMAL
:
109 case LTT_TRACE_FLIGHT
:
111 case LTT_CHANNEL_METADATA
:
116 case LTT_TRACE_HYBRID
:
118 case LTT_CHANNEL_METADATA
:
128 static void trace_async_wakeup(struct ust_trace
*trace
)
131 struct ust_channel
*chan
;
133 /* Must check each channel for pending read wakeup */
134 for (i
= 0; i
< trace
->nr_channels
; i
++) {
135 chan
= &trace
->channels
[i
];
137 trace
->ops
->wakeup_channel(chan
);
142 * _ltt_trace_find - find a trace by given name.
143 * trace_name: trace name
145 * Returns a pointer to the trace structure, NULL if not found.
147 struct ust_trace
*_ltt_trace_find(const char *trace_name
)
149 struct ust_trace
*trace
;
151 cds_list_for_each_entry(trace
, <t_traces
.head
, list
)
152 if (!strncmp(trace
->trace_name
, trace_name
, NAME_MAX
))
158 /* _ltt_trace_find_setup :
159 * find a trace in setup list by given name.
161 * Returns a pointer to the trace structure, NULL if not found.
163 struct ust_trace
*_ltt_trace_find_setup(const char *trace_name
)
165 struct ust_trace
*trace
;
167 cds_list_for_each_entry(trace
, <t_traces
.setup_head
, list
)
168 if (!strncmp(trace
->trace_name
, trace_name
, NAME_MAX
))
175 * ltt_release_transport - Release an LTT transport
176 * @kref : reference count on the transport
178 void ltt_release_transport(struct urcu_ref
*urcu_ref
)
184 * ltt_release_trace - Release a LTT trace
185 * @kref : reference count on the trace
187 void ltt_release_trace(struct urcu_ref
*urcu_ref
)
189 struct ust_trace
*trace
= _ust_container_of(urcu_ref
,
190 struct ust_trace
, urcu_ref
);
191 ltt_channels_trace_free(trace
->channels
);
195 static inline void prepare_chan_size_num(unsigned int *subbuf_size
,
196 unsigned int *n_subbufs
)
198 /* Make sure the subbuffer size is larger than a page */
199 *subbuf_size
= max_t(unsigned int, *subbuf_size
, PAGE_SIZE
);
201 /* round to next power of 2 */
202 *subbuf_size
= 1 << get_count_order(*subbuf_size
);
203 *n_subbufs
= 1 << get_count_order(*n_subbufs
);
205 /* Subbuf size and number must both be power of two */
206 WARN_ON(hweight32(*subbuf_size
) != 1);
207 WARN_ON(hweight32(*n_subbufs
) != 1);
210 int _ltt_trace_setup(const char *trace_name
)
213 struct ust_trace
*new_trace
= NULL
;
216 enum ltt_channels chantype
;
218 if (_ltt_trace_find_setup(trace_name
)) {
219 ERR("Trace name %s already used", trace_name
);
224 if (_ltt_trace_find(trace_name
)) {
225 ERR("Trace name %s already used", trace_name
);
230 new_trace
= zmalloc(sizeof(struct ust_trace
));
232 ERR("Unable to allocate memory for trace %s", trace_name
);
236 strncpy(new_trace
->trace_name
, trace_name
, NAME_MAX
);
237 new_trace
->channels
= ltt_channels_trace_alloc(&new_trace
->nr_channels
,
238 ust_channels_overwrite_by_default
,
239 ust_channels_request_collection_by_default
, 1);
240 if (!new_trace
->channels
) {
241 ERR("Unable to allocate memory for chaninfo %s\n", trace_name
);
247 * Force metadata channel to active, no overwrite.
249 metadata_index
= ltt_channels_get_index_from_name("metadata");
250 WARN_ON(metadata_index
< 0);
251 new_trace
->channels
[metadata_index
].overwrite
= 0;
252 new_trace
->channels
[metadata_index
].active
= 1;
255 * Set hardcoded tracer defaults for some channels
257 for (chan
= 0; chan
< new_trace
->nr_channels
; chan
++) {
258 if (!(new_trace
->channels
[chan
].active
))
261 chantype
= get_channel_type_from_name(
262 ltt_channels_get_name_from_index(chan
));
263 new_trace
->channels
[chan
].subbuf_size
=
264 chan_infos
[chantype
].def_subbufsize
;
265 new_trace
->channels
[chan
].subbuf_cnt
=
266 chan_infos
[chantype
].def_subbufcount
;
269 cds_list_add(&new_trace
->list
, <t_traces
.setup_head
);
279 int ltt_trace_setup(const char *trace_name
)
283 ret
= _ltt_trace_setup(trace_name
);
288 /* must be called from within a traces lock. */
289 static void _ltt_trace_free(struct ust_trace
*trace
)
291 cds_list_del(&trace
->list
);
295 int ltt_trace_set_type(const char *trace_name
, const char *trace_type
)
298 struct ust_trace
*trace
;
299 struct ltt_transport
*tran_iter
, *transport
= NULL
;
303 trace
= _ltt_trace_find_setup(trace_name
);
305 ERR("Trace not found %s", trace_name
);
310 pthread_mutex_lock(<t_transport_mutex
);
311 cds_list_for_each_entry(tran_iter
, <t_transport_list
, node
) {
312 if (!strcmp(tran_iter
->name
, trace_type
)) {
313 transport
= tran_iter
;
317 pthread_mutex_unlock(<t_transport_mutex
);
320 ERR("Transport %s is not present", trace_type
);
325 trace
->transport
= transport
;
332 int ltt_trace_set_channel_subbufsize(const char *trace_name
,
333 const char *channel_name
, unsigned int size
)
336 struct ust_trace
*trace
;
341 trace
= _ltt_trace_find_setup(trace_name
);
343 ERR("Trace not found %s", trace_name
);
348 index
= ltt_channels_get_index_from_name(channel_name
);
350 ERR("Channel %s not found", channel_name
);
354 trace
->channels
[index
].subbuf_size
= size
;
361 int ltt_trace_set_channel_subbufcount(const char *trace_name
,
362 const char *channel_name
, unsigned int cnt
)
365 struct ust_trace
*trace
;
370 trace
= _ltt_trace_find_setup(trace_name
);
372 ERR("Trace not found %s", trace_name
);
377 index
= ltt_channels_get_index_from_name(channel_name
);
379 ERR("Channel %s not found", channel_name
);
383 trace
->channels
[index
].subbuf_cnt
= cnt
;
390 int ltt_trace_set_channel_enable(const char *trace_name
,
391 const char *channel_name
, unsigned int enable
)
394 struct ust_trace
*trace
;
399 trace
= _ltt_trace_find_setup(trace_name
);
401 ERR("Trace not found %s", trace_name
);
407 * Datas in metadata channel(marker info) is necessary to be able to
408 * read the trace, we always enable this channel.
410 if (!enable
&& !strcmp(channel_name
, "metadata")) {
411 ERR("Trying to disable metadata channel");
416 index
= ltt_channels_get_index_from_name(channel_name
);
418 ERR("Channel %s not found", channel_name
);
423 trace
->channels
[index
].active
= enable
;
430 int ltt_trace_set_channel_overwrite(const char *trace_name
,
431 const char *channel_name
, unsigned int overwrite
)
434 struct ust_trace
*trace
;
439 trace
= _ltt_trace_find_setup(trace_name
);
441 ERR("Trace not found %s", trace_name
);
447 * Always put the metadata channel in non-overwrite mode :
448 * This is a very low traffic channel and it can't afford to have its
449 * data overwritten : this data (marker info) is necessary to be
450 * able to read the trace.
452 if (overwrite
&& !strcmp(channel_name
, "metadata")) {
453 ERR("Trying to set metadata channel to overwrite mode");
458 index
= ltt_channels_get_index_from_name(channel_name
);
460 ERR("Channel %s not found", channel_name
);
465 trace
->channels
[index
].overwrite
= overwrite
;
472 int ltt_trace_alloc(const char *trace_name
)
475 struct ust_trace
*trace
;
476 unsigned int subbuf_size
, subbuf_cnt
;
478 const char *channel_name
;
482 if (_ltt_trace_find(trace_name
)) { /* Trace already allocated */
487 trace
= _ltt_trace_find_setup(trace_name
);
489 ERR("Trace not found %s", trace_name
);
494 urcu_ref_init(&trace
->urcu_ref
);
495 urcu_ref_init(&trace
->ltt_transport_urcu_ref
);
497 trace
->freq_scale
= trace_clock_freq_scale();
499 if (!trace
->transport
) {
500 ERR("Transport is not set");
502 goto transport_error
;
504 trace
->ops
= &trace
->transport
->ops
;
506 trace
->start_freq
= trace_clock_frequency();
507 trace
->start_tsc
= trace_clock_read64();
508 gettimeofday(&trace
->start_time
, NULL
); //ust// changed /* FIXME: is this ok? */
510 for (chan
= 0; chan
< trace
->nr_channels
; chan
++) {
511 if (!(trace
->channels
[chan
].active
))
514 channel_name
= ltt_channels_get_name_from_index(chan
);
515 WARN_ON(!channel_name
);
516 subbuf_size
= trace
->channels
[chan
].subbuf_size
;
517 subbuf_cnt
= trace
->channels
[chan
].subbuf_cnt
;
518 prepare_chan_size_num(&subbuf_size
, &subbuf_cnt
);
519 err
= trace
->ops
->create_channel(trace_name
, trace
,
521 &trace
->channels
[chan
],
524 trace
->channels
[chan
].overwrite
);
526 ERR("Cannot create channel %s", channel_name
);
527 goto create_channel_error
;
531 cds_list_del(&trace
->list
);
532 cds_list_add_rcu(&trace
->list
, <t_traces
.head
);
538 create_channel_error
:
539 for (chan
--; chan
>= 0; chan
--)
540 if (trace
->channels
[chan
].active
)
541 trace
->ops
->remove_channel(&trace
->channels
[chan
]);
549 /* Must be called while sure that trace is in the list. */
550 static int _ltt_trace_destroy(struct ust_trace
*trace
)
559 ERR("Can't destroy trace %s : tracer is active", trace
->trace_name
);
564 cds_list_del_rcu(&trace
->list
);
574 /* Sleepable part of the destroy */
575 static void __ltt_trace_destroy(struct ust_trace
*trace
, int drop
)
578 struct ust_channel
*chan
;
581 for (i
= 0; i
< trace
->nr_channels
; i
++) {
582 chan
= &trace
->channels
[i
];
584 trace
->ops
->finish_channel(chan
);
589 * The currently destroyed trace is not in the trace list anymore,
590 * so it's safe to call the async wakeup ourself. It will deliver
591 * the last subbuffers.
593 trace_async_wakeup(trace
);
595 for (i
= 0; i
< trace
->nr_channels
; i
++) {
596 chan
= &trace
->channels
[i
];
598 trace
->ops
->remove_channel(chan
);
601 urcu_ref_put(&trace
->ltt_transport_urcu_ref
, ltt_release_transport
);
603 urcu_ref_put(&trace
->urcu_ref
, ltt_release_trace
);
606 int ltt_trace_destroy(const char *trace_name
, int drop
)
609 struct ust_trace
*trace
;
613 trace
= _ltt_trace_find(trace_name
);
615 err
= _ltt_trace_destroy(trace
);
621 __ltt_trace_destroy(trace
, drop
);
626 trace
= _ltt_trace_find_setup(trace_name
);
628 _ltt_trace_free(trace
);
640 /* must be called from within a traces lock. */
641 static int _ltt_trace_start(struct ust_trace
*trace
)
650 DBG("Tracing already active for trace %s", trace
->trace_name
);
652 /* Read by trace points without protection : be careful */
653 ltt_traces
.num_active_traces
++;
660 int ltt_trace_start(const char *trace_name
)
663 struct ust_trace
*trace
;
667 trace
= _ltt_trace_find(trace_name
);
668 err
= _ltt_trace_start(trace
);
675 * Call the process-wide state dump.
676 * Notice that there is no protection on the trace : that's exactly
677 * why we iterate on the list and check for trace equality instead of
678 * directly using this trace handle inside the logging function: we want
679 * to record events only in a single trace in the trace session list.
682 ltt_dump_ust_marker_state(trace
);
692 /* must be called from within traces lock */
693 static int _ltt_trace_stop(struct ust_trace
*trace
)
702 DBG("LTT : Tracing not active for trace %s", trace
->trace_name
);
705 ltt_traces
.num_active_traces
--;
713 int ltt_trace_stop(const char *trace_name
)
716 struct ust_trace
*trace
;
719 trace
= _ltt_trace_find(trace_name
);
720 err
= _ltt_trace_stop(trace
);