Add a packet sequence number
authorJulien Desfossez <jdesfossez@efficios.com>
Sat, 1 Aug 2015 04:02:33 +0000 (00:02 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sun, 2 Aug 2015 15:34:47 +0000 (11:34 -0400)
This allows the viewer to identify the gaps between trace packets.

Signed-off-by: Julien Desfossez <jdesfossez@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
lib/ringbuffer/backend_internal.h
lib/ringbuffer/backend_types.h
lib/ringbuffer/frontend_internal.h
lib/ringbuffer/ring_buffer_backend.c
lttng-abi.c
lttng-abi.h
lttng-events.c
lttng-events.h
lttng-ring-buffer-client.h
lttng-ring-buffer-metadata-client.h

index 35b26f77190edb9d1588f9ace92866f304fe1053..04a7ae17db7ea7fcba964f1d64092c5de7409b22 100644 (file)
@@ -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.
index 1577c812bb93c1df71cb5f736d8c1de6c8a933f6..8c53d0754eee633e4bf958c11a82f77fbb95322e 100644 (file)
@@ -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.
index 47c080297ebd45ffd723de7c78caa6130fa672d3..d170e9abd46b27b2cf269bfd1ae40ea33413e8ac 100644 (file)
@@ -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
index 3cc22d77b2d9ad5c2ed428fed783b9055a5f97d3..5466325f10a3b95535cf6270128254d35d656074 100644 (file)
@@ -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);
index 8f63ad94c8fb053d9178aa91aa71d14d317f4e1b..586116dae39f6f5f50726191d90951d029bbea7e 100644 (file)
@@ -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);
index ab54cf8dc50ec06b6ca5a504ff173bdfeb6d8bc0..2d342c1bfafc0d3d3da605f59c074796a277fae0 100644 (file)
@@ -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 */
index 9769f89de2aa78bef23410cf1dce84fdaf0c4584..c213b719fa4802876a6605c43829d0ccaf0736fb 100644 (file)
@@ -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"
index 484534c4272948208a0b426468282c9ae78d8873..d2a039e8f664cacf5aea2d91b86aafdd7e31acaa 100644 (file)
@@ -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 {
index 7055e770734e52a6f339f3c6b78e1c7913f07a1d..34493333bcc8a0055db535cf262a319e09b92021 100644 (file)
@@ -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,
        },
 };
 
index 9e0353042517e5fbb38dd191778aab51e3ed7800..446df89772ac885a90fc639d426f868ff53e1549 100644 (file)
@@ -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,
        },
 };
 
This page took 0.03143 seconds and 4 git commands to generate.