#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
+#include <linux/uuid.h>
#include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */
#include "ltt-events.h"
#include "ltt-tracer.h"
return NULL;
INIT_LIST_HEAD(&session->chan);
INIT_LIST_HEAD(&session->events);
+ uuid_le_gen(&session->uuid);
list_add(&session->list, &sessions);
mutex_unlock(&sessions_mutex);
return session;
ret != -ENOBUFS || !ret;
}),
msecs_to_jiffies(LTTNG_METADATA_TIMEOUT_MSEC));
- if (waitret || ret) {
+ if (!waitret || waitret == -ERESTARTSYS || ret) {
printk(KERN_WARNING "LTTng: Failure to write metadata to buffers (%s)\n",
waitret == -ERESTARTSYS ? "interrupted" :
(ret == -ENOBUFS ? "timeout" : "I/O error"));
+ printk("waitret %d retval %d\n", waitret, ret);
if (waitret == -ERESTARTSYS)
ret = waitret;
goto end;
*/
ret = lttng_metadata_printf(session,
" } aligned(%u);\n"
- "};\n", ltt_get_header_alignment());
+ "};\n\n", ltt_get_header_alignment());
if (ret)
goto end;
"stream {\n"
" id = %u;\n"
" event.header := %s;\n",
- "};\n",
+ "};\n\n",
chan->id,
chan->header_type == 1 ? "struct event_header_compact" :
"struct event_header_large");
static
int _ltt_session_metadata_statedump(struct ltt_session *session)
{
+ char uuid_s[37];
struct ltt_channel *chan;
struct ltt_event *event;
int ret = 0;
return -EPERM;
}
+ snprintf(uuid_s, sizeof(uuid_s),
+ "%x%x%x%x-%x%x-%x%x-%x%x-%x%x%x%x%x%x",
+ uuid_s[0], uuid_s[1], uuid_s[2], uuid_s[3],
+ uuid_s[4], uuid_s[5], uuid_s[6], uuid_s[7],
+ uuid_s[8], uuid_s[9], uuid_s[10], uuid_s[11],
+ uuid_s[12], uuid_s[13], uuid_s[14], uuid_s[15]);
+
+ ret = lttng_metadata_printf(session,
+ "typealias integer {size = 8; align = %u; signed = false; } := uint8_t;\n"
+ "typealias integer {size = 32; align = %u; signed = false; } := uint32_t;\n"
+ "typealias integer {size = 64; align = %u; signed = false; } := uint64_t;\n"
+ "\n"
+ "trace {\n"
+ " major = %u;\n"
+ " minor = %u;\n"
+ " uuid = %s;\n"
+ " byte_order = %s;\n"
+ " packet.header := struct {\n"
+ " uint32_t magic;\n"
+ " uint8_t trace_uuid[16];\n"
+ " uint32_t stream_id;\n"
+ " uint64_t timestamp_begin;\n"
+ " uint64_t timestamp_end;\n"
+ " uint32_t content_size;\n"
+ " uint32_t packet_size;\n"
+ " uint32_t events_lost;\n"
+ " };\n",
+ "};\n\n",
+ ltt_alignof(uint8_t) * CHAR_BIT,
+ ltt_alignof(uint32_t) * CHAR_BIT,
+ ltt_alignof(uint64_t) * CHAR_BIT,
+ CTF_VERSION_MAJOR,
+ CTF_VERSION_MINOR,
+ uuid_s,
+#ifdef __BIG_ENDIAN
+ "be"
+#else
+ "le"
+#endif
+ );
+ if (ret)
+ goto end;
+
skip_session:
list_for_each_entry(chan, &session->chan, list) {
ret = _ltt_channel_metadata_statedump(session, chan);
*/
#include <linux/list.h>
+#include <linux/uuid.h>
#include "ltt-debugfs-abi.h"
struct ltt_channel;
.u.basic.integer = \
{ \
.size = sizeof(_type), \
- .alignment = __alignof__(_type), \
+ .alignment = ltt_alignof(_type) * CHAR_BIT, \
.signedness = is_signed_type(_type), \
.reverse_byte_order = _byte_order != __BYTE_ORDER, \
}, \
struct list_head events; /* Event list head */
struct list_head list; /* Session list */
unsigned int free_chan_id; /* Next chan ID to allocate */
+ uuid_le uuid; /* Trace session unique ID */
int metadata_dumped:1;
};
#include "ltt-events.h"
#include "ltt-tracer.h"
+/*
+ * Keep the natural field alignment for _each field_ within this structure if
+ * you ever add/remove a field from this header. Packed attribute is not used
+ * because gcc generates poor code on at least powerpc and mips. Don't ever
+ * let gcc add padding between the structure elements.
+ */
+struct packet_header {
+ uint32_t magic; /*
+ * Trace magic number.
+ * contains endianness information.
+ */
+ uint8_t trace_uuid[16];
+ uint32_t stream_id;
+ uint64_t timestamp_begin; /* Cycle count at subbuffer start */
+ uint64_t timestamp_end; /* Cycle count at subbuffer end */
+ uint32_t content_size; /* Size of data in subbuffer */
+ uint32_t packet_size; /* Subbuffer size (include padding) */
+ uint32_t events_lost; /*
+ * Events lost in this subbuffer since
+ * the beginning of the trace.
+ * (may overflow)
+ */
+#if 0
+ uint64_t start_time_sec; /* NTP-corrected start time */
+ uint64_t start_time_usec;
+ uint64_t start_freq; /*
+ * Frequency at trace start,
+ * used all along the trace.
+ */
+ uint32_t freq_scale; /* Frequency scaling (divisor) */
+#endif //0
+ uint8_t header_end[0]; /* End of header */
+};
+
+
static inline notrace u64 lib_ring_buffer_clock_read(struct channel *chan)
{
return trace_clock_read64();
ltt_write_event_header_slow(config, ctx, eID, event_size);
}
-/**
- * ltt_write_trace_header - Write trace header
- * @priv: Private data (struct trace)
- * @header: Memory address where the information must be written to
- */
-static __inline__
-void write_trace_header(const struct lib_ring_buffer_config *config,
- struct packet_header *header)
-{
- header->magic = CTF_MAGIC_NUMBER;
-#if 0
- /* TODO: move start time to metadata */
- header->major_version = LTT_TRACER_VERSION_MAJOR;
- header->minor_version = LTT_TRACER_VERSION_MINOR;
- header->arch_size = sizeof(void *);
- header->alignment = lib_ring_buffer_get_alignment(config);
- header->start_time_sec = ltt_chan->session->start_time.tv_sec;
- header->start_time_usec = ltt_chan->session->start_time.tv_usec;
- header->start_freq = ltt_chan->session->start_freq;
- header->freq_scale = ltt_chan->session->freq_scale;
-#endif //0
-}
-
void ltt_write_event_header_slow(const struct lib_ring_buffer_config *config,
struct lib_ring_buffer_ctx *ctx,
u16 eID, u32 event_size)
(struct packet_header *)
lib_ring_buffer_offset_address(&buf->backend,
subbuf_idx * chan->backend.subbuf_size);
+ struct ltt_session *session = channel_get_private(chan);
+ header->magic = CTF_MAGIC_NUMBER;
+ memcpy(header->trace_uuid, session->uuid.b, sizeof(session->uuid));
header->timestamp_begin = tsc;
+ header->timestamp_end = 0;
header->content_size = 0xFFFFFFFF; /* for debugging */
- write_trace_header(&client_config, header);
+ header->packet_size = 0xFFFFFFFF;
+ header->events_lost = 0;
+#if 0
+ header->start_time_sec = ltt_chan->session->start_time.tv_sec;
+ header->start_time_usec = ltt_chan->session->start_time.tv_usec;
+ header->start_freq = ltt_chan->session->start_freq;
+ header->freq_scale = ltt_chan->session->freq_scale;
+#endif //0
}
/*
subbuf_idx * chan->backend.subbuf_size);
unsigned long records_lost = 0;
+ header->timestamp_end = tsc;
header->content_size = data_size;
header->packet_size = PAGE_ALIGN(data_size);
- header->timestamp_end = tsc;
records_lost += lib_ring_buffer_get_records_lost_full(&client_config, buf);
records_lost += lib_ring_buffer_get_records_lost_wrap(&client_config, buf);
records_lost += lib_ring_buffer_get_records_lost_big(&client_config, buf);
(struct metadata_packet_header *)
lib_ring_buffer_offset_address(&buf->backend,
subbuf_idx * chan->backend.subbuf_size);
+ struct ltt_session *session = channel_get_private(chan);
header->magic = TSDL_MAGIC_NUMBER;
- /* TODO */
- //header->trace_uuid = ; /* Unique Universal Identifier */
+ memcpy(header->trace_uuid, session->uuid.b, sizeof(session->uuid));
header->checksum = 0; /* 0 if unused */
header->content_size = 0xFFFFFFFF; /* in bits, for debugging */
header->packet_size = 0xFFFFFFFF; /* in bits, for debugging */
unsigned int subbuf_idx, unsigned long data_size)
{
struct channel *chan = buf->backend.chan;
- struct packet_header *header =
+ struct metadata_packet_header *header =
(struct packet_header *)
lib_ring_buffer_offset_address(&buf->backend,
subbuf_idx * chan->backend.subbuf_size);
#define LTT_MAX_SMALL_SIZE 0xFFFFU
+#ifdef RING_BUFFER_ALIGN
static inline
size_t ltt_get_header_alignment(void)
{
-#ifdef RING_BUFFER_ALIGN
return sizeof(struct event_header) * CHAR_BIT;
+}
+
+#define ltt_alignof(type) __alignof__(type)
#else
+static inline
+size_t ltt_get_header_alignment(void)
+{
return CHAR_BIT;
-#endif
}
-/*
- * We use asm/timex.h : cpu_khz/HZ variable in here : we might have to deal
- * specifically with CPU frequency scaling someday, so using an interpolation
- * between the start and end of buffer values is not flexible enough. Using an
- * immediate frequency value permits to calculate directly the times for parts
- * of a buffer that would be before a frequency change.
- *
- * Keep the natural field alignment for _each field_ within this structure if
- * you ever add/remove a field from this header. Packed attribute is not used
- * because gcc generates poor code on at least powerpc and mips. Don't ever
- * let gcc add padding between the structure elements.
- */
-struct packet_header {
- uint32_t magic; /*
- * Trace magic number.
- * contains endianness information.
- */
- uint8_t trace_uuid[16];
- uint32_t stream_id;
- uint64_t timestamp_begin; /* Cycle count at subbuffer start */
- uint64_t timestamp_end; /* Cycle count at subbuffer end */
- uint32_t content_size; /* Size of data in subbuffer */
- uint32_t packet_size; /* Subbuffer size (include padding) */
- uint32_t events_lost; /*
- * Events lost in this subbuffer since
- * the beginning of the trace.
- * (may overflow)
- */
- /* TODO: move to metadata */
-#if 0
- uint8_t major_version;
- uint8_t minor_version;
- uint8_t arch_size; /* Architecture pointer size */
- uint8_t alignment; /* LTT data alignment */
- uint64_t start_time_sec; /* NTP-corrected start time */
- uint64_t start_time_usec;
- uint64_t start_freq; /*
- * Frequency at trace start,
- * used all along the trace.
- */
- uint32_t freq_scale; /* Frequency scaling (divisor) */
-#endif //0
- uint8_t header_end[0]; /* End of header */
-};
+#define ltt_alignof(type) 1
+#endif
/* Tracer properties */
#define CTF_MAGIC_NUMBER 0xC1FC1FC1
#define TSDL_MAGIC_NUMBER 0x75D11D57
-#define LTT_TRACER_VERSION_MAJOR 3
-#define LTT_TRACER_VERSION_MINOR 0
+#define CTF_VERSION_MAJOR 0
+#define CTF_VERSION_MINOR 1
/*
* Number of milliseconds to retry before failing metadata writes on buffer full
#undef __field
#define __field(_type, _item) \
- __event_len += lib_ring_buffer_align(__event_len, __alignof__(_type)); \
+ __event_len += lib_ring_buffer_align(__event_len, ltt_alignof(_type)); \
__event_len += sizeof(_type);
#undef __field_ext
#undef __array
#define __array(_type, _item, _length) \
- __event_len += lib_ring_buffer_align(__event_len, __alignof__(_type)); \
+ __event_len += lib_ring_buffer_align(__event_len, ltt_alignof(_type)); \
__event_len += sizeof(_type) * (_length);
#undef __dynamic_array
#define __dynamic_array(_type, _item, _length) \
- __event_len += lib_ring_buffer_align(__event_len, __alignof__(u32)); \
+ __event_len += lib_ring_buffer_align(__event_len, ltt_alignof(u32)); \
__event_len += sizeof(u32); \
- __event_len += lib_ring_buffer_align(__event_len, __alignof__(_type)); \
+ __event_len += lib_ring_buffer_align(__event_len, ltt_alignof(_type)); \
__event_len += sizeof(_type) * (_length);
#undef __string
#undef __field
#define __field(_type, _item) \
- __event_align = max_t(size_t, __event_align, __alignof__(_type));
+ __event_align = max_t(size_t, __event_align, ltt_alignof(_type));
#undef __field_ext
#define __field_ext(_type, _item, _filter_type) __field(_type, _item)
#undef __array
#define __array(_type, _item, _length) \
- __event_align = max_t(size_t, __event_align, __alignof__(_type));
+ __event_align = max_t(size_t, __event_align, ltt_alignof(_type));
#undef __dynamic_array
#define __dynamic_array(_type, _item, _length) \
- __event_align = max_t(size_t, __event_align, __alignof__(u32)); \
- __event_align = max_t(size_t, __event_align, __alignof__(_type));
+ __event_align = max_t(size_t, __event_align, ltt_alignof(u32)); \
+ __event_align = max_t(size_t, __event_align, ltt_alignof(_type));
#undef __string
#define __string(_item, _src)
__assign_##dest: \
{ \
__typeof__(__typemap.dest) __tmp = (src); \
- lib_ring_buffer_align_ctx(&ctx, __alignof__(__tmp)); \
+ lib_ring_buffer_align_ctx(&ctx, ltt_alignof(__tmp)); \
__chan->ops->event_write(&ctx, &__tmp, sizeof(__tmp)); \
} \
goto __end_field_##dest;
#undef tp_memcpy
#define tp_memcpy(dest, src, len) \
__assign_##dest: \
- lib_ring_buffer_align_ctx(&ctx, __alignof__(__typemap.dest)); \
+ if (0) \
+ (void) __typemap.dest; \
+ lib_ring_buffer_align_ctx(&ctx, ltt_alignof(__typemap.dest)); \
__chan->ops->event_write(&ctx, src, len); \
goto __end_field_##dest;
__assign_##dest##_1: \
{ \
u32 __tmpl = (len); \
- lib_ring_buffer_align_ctx(&ctx, __alignof__(u32)); \
+ lib_ring_buffer_align_ctx(&ctx, ltt_alignof(u32)); \
__chan->ops->event_write(&ctx, &__tmpl, sizeof(u32)); \
} \
goto __end_field_##dest##_1; \
__assign_##dest##_2: \
- lib_ring_buffer_align_ctx(&ctx, __alignof__(__typemap.dest)); \
+ lib_ring_buffer_align_ctx(&ctx, ltt_alignof(__typemap.dest)); \
__chan->ops->event_write(&ctx, src, len); \
goto __end_field_##dest##_2;
#include <linux/seq_file.h>
#include "lttng.h"
#include "../ltt-events.h"
+#include "../ltt-tracer.h"
#ifdef __KERNEL__
# include <asm/byteorder.h>