Generate and export the sequence number
authorJulien Desfossez <jdesfossez@efficios.com>
Mon, 15 Jun 2015 20:33:47 +0000 (16:33 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 4 Mar 2016 00:52:04 +0000 (19:52 -0500)
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 <jdesfossez@efficios.com>
Acked-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
include/lttng/ust-ctl.h
liblttng-ust-ctl/ustctl.c
liblttng-ust/lttng-rb-clients.h
liblttng-ust/lttng-ring-buffer-client.h
libringbuffer/backend_internal.h
libringbuffer/backend_types.h
libringbuffer/frontend_internal.h
libringbuffer/ring_buffer_backend.c

index d3c50c5cbd6a326b8e6907de08deb46a1fcb2612..f62c50225c76f0a1dc0aa5713a4bef86edfaa35c 100644 (file)
@@ -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);
index 10fb9c4921f36ba4b4955fe90b892aeb9ce08e9b..fcb6f0d55c398f2cc534d7f8aa27c5f4e21b5657 100644 (file)
@@ -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)
index 85d4e1bcbfe1477cd85a340af3bb750367bbcd0c..788f07547137799c5d8ba30fa2d63d21d6ef80a2 100644 (file)
@@ -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 */
index 536a31a8db7591a8c78b291fbad7f3143485f355..07dc4700afdd842066a03ccd41c460db1f7f949a 100644 (file)
@@ -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 = {
index 79f8bdeaea9ad933f4956f6eaf641be8416b092c..df3617cacd76dccdd756d870cf56d0e477b8f387 100644 (file)
@@ -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.
index a53fb322ec109bb2fc5c9cc275e5f0118dd67bf5..83fe04871dd26f0885b8859065b8d14cf277a552 100644 (file)
@@ -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.
index 51b652d2a3d2ed5dbb9eb41d0942a522bd4c86a7..00b9508d4df54768767fbe0aaff401cb0f965b0d 100644 (file)
@@ -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
index 2e688b40f4810e1a80c57b7296edafaed7e97c14..961f118a088f587ed60172d265d6c09c578b5106 100644 (file)
@@ -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:
This page took 0.034116 seconds and 4 git commands to generate.