From: Julien Desfossez Date: Mon, 15 Jun 2015 20:33:47 +0000 (-0400) Subject: Generate and export the sequence number X-Git-Tag: v2.8.0-rc1~11 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=1ff31389b;p=lttng-ust.git Generate and export the sequence number This allows the viewer to identify the gaps between trace packets. This is a locked-step with the corresponding commit in lttng-tools. Signed-off-by: Julien Desfossez Acked-by: Mathieu Desnoyers Signed-off-by: Mathieu Desnoyers --- diff --git a/include/lttng/ust-ctl.h b/include/lttng/ust-ctl.h index d3c50c5c..f62c5022 100644 --- a/include/lttng/ust-ctl.h +++ b/include/lttng/ust-ctl.h @@ -252,6 +252,8 @@ int ustctl_get_stream_id(struct ustctl_consumer_stream *stream, uint64_t *stream_id); int ustctl_get_current_timestamp(struct ustctl_consumer_stream *stream, uint64_t *ts); +int ustctl_get_sequence_number(struct ustctl_consumer_stream *stream, + uint64_t *seq); /* returns whether UST has perf counters support. */ int ustctl_has_perf_counters(void); diff --git a/liblttng-ust-ctl/ustctl.c b/liblttng-ust-ctl/ustctl.c index 10fb9c49..fcb6f0d5 100644 --- a/liblttng-ust-ctl/ustctl.c +++ b/liblttng-ust-ctl/ustctl.c @@ -1708,6 +1708,23 @@ int ustctl_get_current_timestamp(struct ustctl_consumer_stream *stream, return client_cb->current_timestamp(buf, handle, ts); } +int ustctl_get_sequence_number(struct ustctl_consumer_stream *stream, + uint64_t *seq) +{ + struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb; + struct lttng_ust_lib_ring_buffer *buf; + struct lttng_ust_shm_handle *handle; + + if (!stream || !seq) + return -EINVAL; + buf = stream->buf; + handle = stream->chan->chan->handle; + client_cb = get_client_cb(buf, handle); + if (!client_cb || !client_cb->sequence_number) + return -ENOSYS; + return client_cb->sequence_number(buf, handle, seq); +} + #if defined(__x86_64__) || defined(__i386__) int ustctl_has_perf_counters(void) diff --git a/liblttng-ust/lttng-rb-clients.h b/liblttng-ust/lttng-rb-clients.h index 85d4e1bc..788f0754 100644 --- a/liblttng-ust/lttng-rb-clients.h +++ b/liblttng-ust/lttng-rb-clients.h @@ -43,6 +43,8 @@ struct lttng_ust_client_lib_ring_buffer_client_cb { int (*current_timestamp) (struct lttng_ust_lib_ring_buffer *buf, struct lttng_ust_shm_handle *handle, uint64_t *ts); + int (*sequence_number) (struct lttng_ust_lib_ring_buffer *buf, + struct lttng_ust_shm_handle *handle, uint64_t *seq); }; #endif /* _LTTNG_RB_CLIENT_H */ diff --git a/liblttng-ust/lttng-ring-buffer-client.h b/liblttng-ust/lttng-ring-buffer-client.h index 536a31a8..07dc4700 100644 --- a/liblttng-ust/lttng-ring-buffer-client.h +++ b/liblttng-ust/lttng-ring-buffer-client.h @@ -53,6 +53,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. @@ -339,6 +340,7 @@ static void client_buffer_begin(struct lttng_ust_lib_ring_buffer *buf, uint64_t subbuf_idx * chan->backend.subbuf_size, handle); struct lttng_channel *lttng_chan = channel_get_private(chan); + uint64_t cnt = shmp_index(handle, buf->backend.buf_cnt, subbuf_idx)->seq_cnt; assert(header); if (!header) @@ -351,6 +353,7 @@ static void client_buffer_begin(struct lttng_ust_lib_ring_buffer *buf, uint64_t 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 * cnt + subbuf_idx; header->ctx.events_discarded = 0; header->ctx.cpu_id = buf->backend.cpu; } @@ -506,6 +509,17 @@ static int client_current_timestamp(struct lttng_ust_lib_ring_buffer *buf, return 0; } +static int client_sequence_number(struct lttng_ust_lib_ring_buffer *buf, + struct lttng_ust_shm_handle *handle, + uint64_t *seq) +{ + struct packet_header *header; + + header = client_packet_header(buf, handle); + *seq = header->ctx.packet_seq_num; + return 0; +} + static const struct lttng_ust_client_lib_ring_buffer_client_cb client_cb = { .parent = { @@ -526,6 +540,7 @@ struct lttng_ust_client_lib_ring_buffer_client_cb client_cb = { .packet_size = client_packet_size, .stream_id = client_stream_id, .current_timestamp = client_current_timestamp, + .sequence_number = client_sequence_number, }; static const struct lttng_ust_lib_ring_buffer_config client_config = { diff --git a/libringbuffer/backend_internal.h b/libringbuffer/backend_internal.h index 79f8bdea..df3617ca 100644 --- a/libringbuffer/backend_internal.h +++ b/libringbuffer/backend_internal.h @@ -310,6 +310,14 @@ unsigned long subbuffer_get_data_size( return shmp(handle, pages->shmp)->data_size; } +static inline +void subbuffer_inc_packet_count(const struct lttng_ust_lib_ring_buffer_config *config, + struct lttng_ust_lib_ring_buffer_backend *bufb, + unsigned long idx, struct lttng_ust_shm_handle *handle) +{ + shmp_index(handle, bufb->buf_cnt, idx)->seq_cnt++; +} + /** * lib_ring_buffer_clear_noref - Clear the noref subbuffer flag, called by * writer. diff --git a/libringbuffer/backend_types.h b/libringbuffer/backend_types.h index a53fb322..83fe0487 100644 --- a/libringbuffer/backend_types.h +++ b/libringbuffer/backend_types.h @@ -42,6 +42,16 @@ struct lttng_ust_lib_ring_buffer_backend_subbuffer { unsigned long id; /* backend subbuffer identifier */ }; +struct lttng_ust_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. */ @@ -58,6 +68,8 @@ struct lttng_ust_lib_ring_buffer_backend { DECLARE_SHMP(struct lttng_ust_lib_ring_buffer_backend_subbuffer, buf_wsb); /* ring_buffer_backend_subbuffer for reader */ struct lttng_ust_lib_ring_buffer_backend_subbuffer buf_rsb; + /* Array of lib_ring_buffer_backend_counts for the packet counter */ + DECLARE_SHMP(struct lttng_ust_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/libringbuffer/frontend_internal.h b/libringbuffer/frontend_internal.h index 51b652d2..00b9508d 100644 --- a/libringbuffer/frontend_internal.h +++ b/libringbuffer/frontend_internal.h @@ -446,6 +446,12 @@ void lib_ring_buffer_check_deliver(const struct lttng_ust_lib_ring_buffer_config handle), handle); + /* + * Increment the packet counter while we have exclusive + * access. + */ + subbuffer_inc_packet_count(config, &buf->backend, idx, handle); + /* * Set noref flag and offset for this subbuffer id. * Contains a memory barrier that ensures counter stores diff --git a/libringbuffer/ring_buffer_backend.c b/libringbuffer/ring_buffer_backend.c index 2e688b40..961f118a 100644 --- a/libringbuffer/ring_buffer_backend.c +++ b/libringbuffer/ring_buffer_backend.c @@ -117,6 +117,14 @@ int lib_ring_buffer_backend_allocate(const struct lttng_ust_lib_ring_buffer_conf else bufb->buf_rsb.id = subbuffer_id(config, 0, 1, 0); + /* Allocate subbuffer packet counter table */ + align_shm(shmobj, __alignof__(struct lttng_ust_lib_ring_buffer_backend_subbuffer)); + set_shmp(bufb->buf_cnt, zalloc_shm(shmobj, + sizeof(struct lttng_ust_lib_ring_buffer_backend_counts) + * num_subbuf)); + if (caa_unlikely(!shmp(handle, bufb->buf_cnt))) + goto free_wsb; + /* Assign pages to page index */ for (i = 0; i < num_subbuf_alloc; i++) { struct lttng_ust_lib_ring_buffer_backend_pages_shmp *sbp; @@ -141,6 +149,8 @@ int lib_ring_buffer_backend_allocate(const struct lttng_ust_lib_ring_buffer_conf } return 0; +free_wsb: + /* bufb->buf_wsb will be freed by shm teardown */ free_array: /* bufb->array[i] will be freed by shm teardown */ memory_map_error: