[lttng-dev] [MODULES PATCH 2/3] Add a packet sequence number
Julien Desfossez
jdesfossez at efficios.com
Mon Jul 13 11:09:24 EDT 2015
This allows the viewer to identify the gaps between trace packets.
Signed-off-by: Julien Desfossez <jdesfossez at efficios.com>
---
lttng-abi.c | 18 +++++++++++++++
lttng-abi.h | 5 ++++
lttng-events.c | 46 +++++++++++++++++++++++++------------
lttng-events.h | 4 ++++
lttng-ring-buffer-client.h | 35 ++++++++++++++++++++++++++++
lttng-ring-buffer-metadata-client.h | 15 ++++++++++++
6 files changed, 108 insertions(+), 15 deletions(-)
diff --git a/lttng-abi.c b/lttng-abi.c
index 8f63ad9..586116d 100644
--- a/lttng-abi.c
+++ b/lttng-abi.c
@@ -1508,6 +1508,15 @@ static long lttng_stream_ring_buffer_ioctl(struct file *filp,
goto error;
return put_u64(ts, arg);
}
+ case LTTNG_RING_BUFFER_GET_SEQ_NUM:
+ {
+ uint64_t seq;
+
+ ret = ops->sequence_number(config, buf, &seq);
+ if (ret < 0)
+ goto error;
+ return put_u64(seq, arg);
+ }
default:
return lib_ring_buffer_file_operations.unlocked_ioctl(filp,
cmd, arg);
@@ -1594,6 +1603,15 @@ static long lttng_stream_ring_buffer_compat_ioctl(struct file *filp,
goto error;
return put_u64(ts, arg);
}
+ case LTTNG_RING_BUFFER_COMPAT_GET_SEQ_NUM:
+ {
+ uint64_t seq;
+
+ ret = ops->sequence_number(config, buf, &seq);
+ if (ret < 0)
+ goto error;
+ return put_u64(seq, arg);
+ }
default:
return lib_ring_buffer_file_operations.compat_ioctl(filp,
cmd, arg);
diff --git a/lttng-abi.h b/lttng-abi.h
index ab54cf8..2d342c1 100644
--- a/lttng-abi.h
+++ b/lttng-abi.h
@@ -228,6 +228,8 @@ struct lttng_kernel_filter_bytecode {
#define LTTNG_RING_BUFFER_GET_STREAM_ID _IOR(0xF6, 0x25, uint64_t)
/* returns the current timestamp */
#define LTTNG_RING_BUFFER_GET_CURRENT_TIMESTAMP _IOR(0xF6, 0x26, uint64_t)
+/* returns the packet sequence number */
+#define LTTNG_RING_BUFFER_GET_SEQ_NUM _IOR(0xF6, 0x27, uint64_t)
#ifdef CONFIG_COMPAT
/* returns the timestamp begin of the current sub-buffer */
@@ -251,6 +253,9 @@ struct lttng_kernel_filter_bytecode {
/* returns the current timestamp */
#define LTTNG_RING_BUFFER_COMPAT_GET_CURRENT_TIMESTAMP \
LTTNG_RING_BUFFER_GET_CURRENT_TIMESTAMP
+/* returns the packet sequence number */
+#define LTTNG_RING_BUFFER_COMPAT_GET_SEQ_NUM \
+ LTTNG_RING_BUFFER_GET_SEQ_NUM
#endif /* CONFIG_COMPAT */
#endif /* _LTTNG_ABI_H */
diff --git a/lttng-events.c b/lttng-events.c
index 3cbfcbf..319ba5a 100644
--- a/lttng-events.c
+++ b/lttng-events.c
@@ -76,6 +76,9 @@ static
int _lttng_session_metadata_statedump(struct lttng_session *session);
static
void _lttng_metadata_channel_hangup(struct lttng_metadata_stream *stream);
+static
+int _lttng_stream_packet_context_declare(struct lttng_session *session,
+ struct lttng_channel *chan);
void synchronize_trace(void)
{
@@ -1808,14 +1811,22 @@ int _lttng_channel_metadata_statedump(struct lttng_session *session,
ret = lttng_metadata_printf(session,
"stream {\n"
" id = %u;\n"
- " event.header := %s;\n"
- " packet.context := struct packet_context;\n",
+ " event.header := %s;\n",
chan->id,
chan->header_type == 1 ? "struct event_header_compact" :
"struct event_header_large");
if (ret)
goto end;
+ ret = lttng_metadata_printf(session,
+ " packet.context := ");
+ if (ret)
+ goto end;
+
+ ret = _lttng_stream_packet_context_declare(session, chan);
+ if (ret)
+ goto end;
+
if (chan->ctx) {
ret = lttng_metadata_printf(session,
" event.context := struct {\n");
@@ -1844,18 +1855,27 @@ end:
* Must be called with sessions_mutex held.
*/
static
-int _lttng_stream_packet_context_declare(struct lttng_session *session)
+int _lttng_stream_packet_context_declare(struct lttng_session *session,
+ struct lttng_channel *chan)
{
+ unsigned int field_size = 64;
+ /* subbuf_size cannot be 0, so we can use fls_long(x - 1) directly. */
+ unsigned int padding = fls_long(chan->ops->subbuf_size(chan->chan) - 1);
+
return lttng_metadata_printf(session,
"struct packet_context {\n"
- " uint64_clock_monotonic_t timestamp_begin;\n"
- " uint64_clock_monotonic_t timestamp_end;\n"
- " uint64_t content_size;\n"
- " uint64_t packet_size;\n"
- " unsigned long events_discarded;\n"
- " uint32_t cpu_id;\n"
- "};\n\n"
- );
+ " uint64_clock_monotonic_t timestamp_begin;\n"
+ " uint64_clock_monotonic_t timestamp_end;\n"
+ " uint64_t content_size;\n"
+ " uint64_t packet_size;\n"
+ " integer { size = %u; signed = false;"
+ " align = 1; } packet_seq_num_padding;\n"
+ " integer { size = %u; signed = false;"
+ " align = 1; } packet_seq_num;\n"
+ " unsigned long events_discarded;\n"
+ " uint32_t cpu_id;\n"
+ " };\n\n",
+ padding, field_size - padding);
}
/*
@@ -2067,10 +2087,6 @@ int _lttng_session_metadata_statedump(struct lttng_session *session)
if (ret)
goto end;
- ret = _lttng_stream_packet_context_declare(session);
- if (ret)
- goto end;
-
ret = _lttng_event_header_declare(session);
if (ret)
goto end;
diff --git a/lttng-events.h b/lttng-events.h
index 484534c..c8afd8f 100644
--- a/lttng-events.h
+++ b/lttng-events.h
@@ -358,6 +358,10 @@ struct lttng_channel_ops {
int (*current_timestamp) (const struct lib_ring_buffer_config *config,
struct lib_ring_buffer *bufb,
uint64_t *ts);
+ int (*sequence_number) (const struct lib_ring_buffer_config *config,
+ struct lib_ring_buffer *bufb,
+ uint64_t *seq);
+ uint64_t (*subbuf_size)(struct channel *chan);
};
struct lttng_transport {
diff --git a/lttng-ring-buffer-client.h b/lttng-ring-buffer-client.h
index 72fbf18..69cc99e 100644
--- a/lttng-ring-buffer-client.h
+++ b/lttng-ring-buffer-client.h
@@ -65,6 +65,7 @@ struct packet_header {
uint64_t timestamp_end; /* Cycle count at subbuffer end */
uint64_t content_size; /* Size of data in subbuffer */
uint64_t packet_size; /* Subbuffer size (include padding) */
+ uint64_t packet_seq_num; /* Packet sequence number */
unsigned long events_discarded; /*
* Events lost in this subbuffer since
* the beginning of the trace.
@@ -348,6 +349,10 @@ static void client_buffer_begin(struct lib_ring_buffer *buf, u64 tsc,
subbuf_idx * chan->backend.subbuf_size);
struct lttng_channel *lttng_chan = channel_get_private(chan);
struct lttng_session *session = lttng_chan->session;
+ /* subbuf_size cannot be 0 so we can use fls_long(x - 1) directly. */
+ unsigned long seq_num_offset =
+ fls_long(chan->backend.subbuf_size - 1);
+ unsigned int field_size = sizeof(header->ctx.packet_seq_num) * CHAR_BIT;
header->magic = CTF_MAGIC_NUMBER;
memcpy(header->uuid, session->uuid.b, sizeof(session->uuid));
@@ -357,6 +362,14 @@ static void client_buffer_begin(struct lib_ring_buffer *buf, u64 tsc,
header->ctx.timestamp_end = 0;
header->ctx.content_size = ~0ULL; /* for debugging */
header->ctx.packet_size = ~0ULL;
+ header->ctx.packet_seq_num = 0;
+ /*
+ * vread returns an unsigned long, the bt_bitfield_write adds the
+ * complement of padding.
+ */
+ bt_bitfield_write(&header->ctx.packet_seq_num, unsigned long,
+ seq_num_offset, field_size - seq_num_offset,
+ v_read(&client_config, &buf->offset) >> seq_num_offset);
header->ctx.events_discarded = 0;
header->ctx.cpu_id = buf->backend.cpu;
}
@@ -472,6 +485,26 @@ static int client_current_timestamp(const struct lib_ring_buffer_config *config,
return 0;
}
+static int client_sequence_number(const struct lib_ring_buffer_config *config,
+ struct lib_ring_buffer *buf,
+ uint64_t *seq)
+{
+ struct packet_header *header = client_packet_header(config, buf);
+ struct channel *chan = buf->backend.chan;
+
+ /* subbuf_size cannot be 0, so we can use fls_long(x - 1) directly. */
+ *seq = header->ctx.packet_seq_num >>
+ (fls_long(chan->backend.subbuf_size - 1));
+
+ return 0;
+}
+
+static
+uint64_t client_get_subbuf_size(struct channel *chan)
+{
+ return chan->backend.subbuf_size;
+}
+
static const struct lib_ring_buffer_config client_config = {
.cb.ring_buffer_clock_read = client_ring_buffer_clock_read,
.cb.record_header_size = client_record_header_size,
@@ -702,6 +735,8 @@ static struct lttng_transport lttng_relay_transport = {
.packet_size = client_packet_size,
.stream_id = client_stream_id,
.current_timestamp = client_current_timestamp,
+ .sequence_number = client_sequence_number,
+ .subbuf_size = client_get_subbuf_size,
},
};
diff --git a/lttng-ring-buffer-metadata-client.h b/lttng-ring-buffer-metadata-client.h
index 9e03530..da94aeb 100644
--- a/lttng-ring-buffer-metadata-client.h
+++ b/lttng-ring-buffer-metadata-client.h
@@ -199,6 +199,19 @@ static int client_stream_id(const struct lib_ring_buffer_config *config,
return -ENOSYS;
}
+static int client_sequence_number(const struct lib_ring_buffer_config *config,
+ struct lib_ring_buffer *bufb,
+ uint64_t *seq)
+{
+ return -ENOSYS;
+}
+
+static
+uint64_t client_get_subbuf_size(struct channel *chan)
+{
+ return -ENOSYS;
+}
+
static const struct lib_ring_buffer_config client_config = {
.cb.ring_buffer_clock_read = client_ring_buffer_clock_read,
.cb.record_header_size = client_record_header_size,
@@ -405,6 +418,8 @@ static struct lttng_transport lttng_relay_transport = {
.packet_size = client_packet_size,
.stream_id = client_stream_id,
.current_timestamp = client_current_timestamp,
+ .sequence_number = client_sequence_number,
+ .subbuf_size = client_get_subbuf_size,
},
};
--
1.9.1
More information about the lttng-dev
mailing list