From 5b3cf4f924befda843a7736daf84f8ecae5e86a4 Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Sat, 1 Aug 2015 00:02:33 -0400 Subject: [PATCH] Add a packet sequence number This allows the viewer to identify the gaps between trace packets. Signed-off-by: Julien Desfossez Signed-off-by: Mathieu Desnoyers --- lib/ringbuffer/backend_internal.h | 8 ++++++++ lib/ringbuffer/backend_types.h | 12 ++++++++++++ lib/ringbuffer/frontend_internal.h | 6 ++++++ lib/ringbuffer/ring_buffer_backend.c | 12 ++++++++++++ lttng-abi.c | 18 ++++++++++++++++++ lttng-abi.h | 5 +++++ lttng-events.c | 1 + lttng-events.h | 3 +++ lttng-ring-buffer-client.h | 16 ++++++++++++++++ lttng-ring-buffer-metadata-client.h | 8 ++++++++ 10 files changed, 89 insertions(+) diff --git a/lib/ringbuffer/backend_internal.h b/lib/ringbuffer/backend_internal.h index 35b26f77..04a7ae17 100644 --- a/lib/ringbuffer/backend_internal.h +++ b/lib/ringbuffer/backend_internal.h @@ -309,6 +309,14 @@ unsigned long subbuffer_get_data_size( return pages->data_size; } +static inline +void subbuffer_inc_packet_count(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_backend *bufb, + unsigned long idx) +{ + bufb->buf_cnt[idx].seq_cnt++; +} + /** * lib_ring_buffer_clear_noref - Clear the noref subbuffer flag, called by * writer. diff --git a/lib/ringbuffer/backend_types.h b/lib/ringbuffer/backend_types.h index 1577c812..8c53d075 100644 --- a/lib/ringbuffer/backend_types.h +++ b/lib/ringbuffer/backend_types.h @@ -44,6 +44,16 @@ struct lib_ring_buffer_backend_subbuffer { unsigned long id; /* backend subbuffer identifier */ }; +struct lib_ring_buffer_backend_counts { + /* + * Counter specific to the sub-buffer location within the ring buffer. + * The actual sequence number of the packet within the entire ring + * buffer can be derived from the formula nr_subbuffers * seq_cnt + + * subbuf_idx. + */ + uint64_t seq_cnt; /* packet sequence number */ +}; + /* * Forward declaration of frontend-specific channel and ring_buffer. */ @@ -55,6 +65,8 @@ struct lib_ring_buffer_backend { struct lib_ring_buffer_backend_subbuffer *buf_wsb; /* ring_buffer_backend_subbuffer for reader */ struct lib_ring_buffer_backend_subbuffer buf_rsb; + /* Array of lib_ring_buffer_backend_counts for the packet counter */ + struct lib_ring_buffer_backend_counts *buf_cnt; /* * Pointer array of backend pages, for whole buffer. * Indexed by ring_buffer_backend_subbuffer identifier (id) index. diff --git a/lib/ringbuffer/frontend_internal.h b/lib/ringbuffer/frontend_internal.h index 47c08029..d170e9ab 100644 --- a/lib/ringbuffer/frontend_internal.h +++ b/lib/ringbuffer/frontend_internal.h @@ -367,6 +367,12 @@ void lib_ring_buffer_check_deliver(const struct lib_ring_buffer_config *config, buf, idx)); + /* + * Increment the packet counter while we have exclusive + * access. + */ + subbuffer_inc_packet_count(config, &buf->backend, idx); + /* * Set noref flag and offset for this subbuffer id. * Contains a memory barrier that ensures counter stores diff --git a/lib/ringbuffer/ring_buffer_backend.c b/lib/ringbuffer/ring_buffer_backend.c index 3cc22d77..5466325f 100644 --- a/lib/ringbuffer/ring_buffer_backend.c +++ b/lib/ringbuffer/ring_buffer_backend.c @@ -125,6 +125,15 @@ int lib_ring_buffer_backend_allocate(const struct lib_ring_buffer_config *config else bufb->buf_rsb.id = subbuffer_id(config, 0, 1, 0); + /* Allocate subbuffer packet counter table */ + bufb->buf_cnt = kzalloc_node(ALIGN( + sizeof(struct lib_ring_buffer_backend_counts) + * num_subbuf, + 1 << INTERNODE_CACHE_SHIFT), + GFP_KERNEL, cpu_to_node(max(bufb->cpu, 0))); + if (unlikely(!bufb->buf_cnt)) + goto free_wsb; + /* Assign pages to page index */ for (i = 0; i < num_subbuf_alloc; i++) { for (j = 0; j < num_pages_per_subbuf; j++) { @@ -148,6 +157,8 @@ int lib_ring_buffer_backend_allocate(const struct lib_ring_buffer_config *config kfree(pages); return 0; +free_wsb: + kfree(bufb->buf_wsb); free_array: for (i = 0; (i < num_subbuf_alloc && bufb->array[i]); i++) kfree(bufb->array[i]); @@ -187,6 +198,7 @@ void lib_ring_buffer_backend_free(struct lib_ring_buffer_backend *bufb) num_subbuf_alloc++; kfree(bufb->buf_wsb); + kfree(bufb->buf_cnt); for (i = 0; i < num_subbuf_alloc; i++) { for (j = 0; j < bufb->num_pages_per_subbuf; j++) __free_page(bufb->array[i]->p[j].page); diff --git a/lttng-abi.c b/lttng-abi.c index 8f63ad94..586116da 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 ab54cf8d..2d342c1b 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 9769f89d..c213b719 100644 --- a/lttng-events.c +++ b/lttng-events.c @@ -1852,6 +1852,7 @@ int _lttng_stream_packet_context_declare(struct lttng_session *session) " uint64_clock_monotonic_t timestamp_end;\n" " uint64_t content_size;\n" " uint64_t packet_size;\n" + " uint64_t packet_seq_num;\n" " unsigned long events_discarded;\n" " uint32_t cpu_id;\n" "};\n\n" diff --git a/lttng-events.h b/lttng-events.h index 484534c4..d2a039e8 100644 --- a/lttng-events.h +++ b/lttng-events.h @@ -358,6 +358,9 @@ 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); }; struct lttng_transport { diff --git a/lttng-ring-buffer-client.h b/lttng-ring-buffer-client.h index 7055e770..34493333 100644 --- a/lttng-ring-buffer-client.h +++ b/lttng-ring-buffer-client.h @@ -64,6 +64,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. @@ -355,6 +356,9 @@ 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 = chan->backend.num_subbuf * \ + buf->backend.buf_cnt[subbuf_idx].seq_cnt + \ + subbuf_idx; header->ctx.events_discarded = 0; header->ctx.cpu_id = buf->backend.cpu; } @@ -470,6 +474,17 @@ 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); + + *seq = header->ctx.packet_seq_num; + + return 0; +} + 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, @@ -700,6 +715,7 @@ 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, }, }; diff --git a/lttng-ring-buffer-metadata-client.h b/lttng-ring-buffer-metadata-client.h index 9e035304..446df897 100644 --- a/lttng-ring-buffer-metadata-client.h +++ b/lttng-ring-buffer-metadata-client.h @@ -199,6 +199,13 @@ 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 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 +412,7 @@ 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, }, }; -- 2.34.1