Fix: update writeback instrumentation for kernel 4.14
[lttng-modules.git] / lttng-ring-buffer-client.h
index 7055e770734e52a6f339f3c6b78e1c7913f07a1d..48d304293b95c4f7baa84ee44784810928f1ce77 100644 (file)
 
 #include <linux/module.h>
 #include <linux/types.h>
-#include "lib/bitfield.h"
-#include "wrapper/vmalloc.h"   /* for wrapper_vmalloc_sync_all() */
-#include "wrapper/trace-clock.h"
-#include "lttng-events.h"
-#include "lttng-tracer.h"
-#include "wrapper/ringbuffer/frontend_types.h"
+#include <lib/bitfield.h>
+#include <wrapper/vmalloc.h>   /* for wrapper_vmalloc_sync_all() */
+#include <wrapper/trace-clock.h>
+#include <lttng-events.h>
+#include <lttng-tracer.h>
+#include <wrapper/ringbuffer/frontend_types.h>
 
 #define LTTNG_COMPACT_EVENT_BITS       5
 #define LTTNG_COMPACT_TSC_BITS         27
@@ -57,6 +57,7 @@ struct packet_header {
                                         */
        uint8_t uuid[16];
        uint32_t stream_id;
+       uint64_t stream_instance_id;
 
        struct {
                /* Stream packet context */
@@ -64,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.
@@ -74,6 +76,10 @@ struct packet_header {
        } ctx;
 };
 
+struct lttng_client_ctx {
+       size_t packet_context_len;
+       size_t event_context_len;
+};
 
 static inline notrace u64 lib_ring_buffer_clock_read(struct channel *chan)
 {
@@ -81,17 +87,31 @@ static inline notrace u64 lib_ring_buffer_clock_read(struct channel *chan)
 }
 
 static inline
-size_t ctx_get_size(size_t offset, struct lttng_ctx *ctx)
+size_t ctx_get_aligned_size(size_t offset, struct lttng_ctx *ctx,
+               size_t ctx_len)
 {
-       int i;
        size_t orig_offset = offset;
 
        if (likely(!ctx))
                return 0;
        offset += lib_ring_buffer_align(offset, ctx->largest_align);
+       offset += ctx_len;
+       return offset - orig_offset;
+}
+
+static inline
+void ctx_get_struct_size(struct lttng_ctx *ctx, size_t *ctx_len)
+{
+       int i;
+       size_t offset = 0;
+
+       if (likely(!ctx)) {
+               *ctx_len = 0;
+               return;
+       }
        for (i = 0; i < ctx->nr_fields; i++)
                offset += ctx->fields[i].get_size(offset);
-       return offset - orig_offset;
+       *ctx_len = offset;
 }
 
 static inline
@@ -122,13 +142,15 @@ void ctx_record(struct lib_ring_buffer_ctx *bufctx,
  * contains.
  */
 static __inline__
-unsigned char record_header_size(const struct lib_ring_buffer_config *config,
+size_t record_header_size(const struct lib_ring_buffer_config *config,
                                 struct channel *chan, size_t offset,
                                 size_t *pre_header_padding,
-                                struct lib_ring_buffer_ctx *ctx)
+                                struct lib_ring_buffer_ctx *ctx,
+                                struct lttng_client_ctx *client_ctx)
 {
        struct lttng_channel *lttng_chan = channel_get_private(chan);
-       struct lttng_event *event = ctx->priv;
+       struct lttng_probe_ctx *lttng_probe_ctx = ctx->priv;
+       struct lttng_event *event = lttng_probe_ctx->event;
        size_t orig_offset = offset;
        size_t padding;
 
@@ -167,14 +189,16 @@ unsigned char record_header_size(const struct lib_ring_buffer_config *config,
                padding = 0;
                WARN_ON_ONCE(1);
        }
-       offset += ctx_get_size(offset, event->ctx);
-       offset += ctx_get_size(offset, lttng_chan->ctx);
+       offset += ctx_get_aligned_size(offset, lttng_chan->ctx,
+                       client_ctx->packet_context_len);
+       offset += ctx_get_aligned_size(offset, event->ctx,
+                       client_ctx->event_context_len);
 
        *pre_header_padding = padding;
        return offset - orig_offset;
 }
 
-#include "wrapper/ringbuffer/api.h"
+#include <wrapper/ringbuffer/api.h>
 
 static
 void lttng_write_event_header_slow(const struct lib_ring_buffer_config *config,
@@ -196,7 +220,8 @@ void lttng_write_event_header(const struct lib_ring_buffer_config *config,
                            uint32_t event_id)
 {
        struct lttng_channel *lttng_chan = channel_get_private(ctx->chan);
-       struct lttng_event *event = ctx->priv;
+       struct lttng_probe_ctx *lttng_probe_ctx = ctx->priv;
+       struct lttng_event *event = lttng_probe_ctx->event;
 
        if (unlikely(ctx->rflags))
                goto slow_path;
@@ -247,7 +272,8 @@ void lttng_write_event_header_slow(const struct lib_ring_buffer_config *config,
                                 uint32_t event_id)
 {
        struct lttng_channel *lttng_chan = channel_get_private(ctx->chan);
-       struct lttng_event *event = ctx->priv;
+       struct lttng_probe_ctx *lttng_probe_ctx = ctx->priv;
+       struct lttng_event *event = lttng_probe_ctx->event;
 
        switch (lttng_chan->header_type) {
        case 1: /* compact */
@@ -319,10 +345,11 @@ static
 size_t client_record_header_size(const struct lib_ring_buffer_config *config,
                                 struct channel *chan, size_t offset,
                                 size_t *pre_header_padding,
-                                struct lib_ring_buffer_ctx *ctx)
+                                struct lib_ring_buffer_ctx *ctx,
+                                void *client_ctx)
 {
        return record_header_size(config, chan, offset,
-                                 pre_header_padding, ctx);
+                                 pre_header_padding, ctx, client_ctx);
 }
 
 /**
@@ -351,10 +378,14 @@ static void client_buffer_begin(struct lib_ring_buffer *buf, u64 tsc,
        header->magic = CTF_MAGIC_NUMBER;
        memcpy(header->uuid, session->uuid.b, sizeof(session->uuid));
        header->stream_id = lttng_chan->id;
+       header->stream_instance_id = buf->backend.cpu;
        header->ctx.timestamp_begin = 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 +501,28 @@ 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
+int client_instance_id(const struct lib_ring_buffer_config *config,
+               struct lib_ring_buffer *buf,
+               uint64_t *id)
+{
+       struct packet_header *header = client_packet_header(config, buf);
+       *id = header->stream_instance_id;
+
+       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,
@@ -572,10 +625,17 @@ int lttng_event_reserve(struct lib_ring_buffer_ctx *ctx,
                      uint32_t event_id)
 {
        struct lttng_channel *lttng_chan = channel_get_private(ctx->chan);
+       struct lttng_probe_ctx *lttng_probe_ctx = ctx->priv;
+       struct lttng_event *event = lttng_probe_ctx->event;
+       struct lttng_client_ctx client_ctx;
        int ret, cpu;
 
+       /* Compute internal size of context structures. */
+       ctx_get_struct_size(lttng_chan->ctx, &client_ctx.packet_context_len);
+       ctx_get_struct_size(event->ctx, &client_ctx.event_context_len);
+
        cpu = lib_ring_buffer_get_cpu(&client_config);
-       if (cpu < 0)
+       if (unlikely(cpu < 0))
                return -EPERM;
        ctx->cpu = cpu;
 
@@ -592,9 +652,11 @@ int lttng_event_reserve(struct lib_ring_buffer_ctx *ctx,
                WARN_ON_ONCE(1);
        }
 
-       ret = lib_ring_buffer_reserve(&client_config, ctx);
-       if (ret)
+       ret = lib_ring_buffer_reserve(&client_config, ctx, &client_ctx);
+       if (unlikely(ret))
                goto put;
+       lib_ring_buffer_backend_get_pages(&client_config, ctx,
+                       &ctx->backend_pages);
        lttng_write_event_header(&client_config, ctx, event_id);
        return 0;
 put:
@@ -700,6 +762,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,
+               .instance_id = client_instance_id,
        },
 };
 
This page took 0.027295 seconds and 4 git commands to generate.