Update version to 0.16
[ust.git] / libust / tracer.h
index b2ac930293badb95aaef2e66430fb847b5030f4c..4f72d7ad637e5e39de20df4b386fba84dd1e497e 100644 (file)
 
 #include <sys/types.h>
 #include <stdarg.h>
-//#include "list.h"
-#include "kernelcompat.h"
-#include "buffer.h"
-#include "relay.h"
+#include <ust/marker.h>
+#include <ust/marker-internal.h>
+#include <ust/probe-internal.h>
+#include <ust/core.h>
+#include <ust/compat.h>
 #include "channels.h"
 #include "tracercore.h"
-#include "marker.h"
+#include "tracerconst.h"
+#include "buffers.h"
 
 /* Number of bytes to log with a read/write event */
 #define LTT_LOG_RW_SIZE                        32L
 #define LTT_ARCH_VARIANT               LTT_ARCH_VARIANT_NONE
 #endif
 
-struct ltt_active_marker;
+struct ltt_active_ust_marker;
 
-/* Maximum number of callbacks per marker */
+/* Maximum number of callbacks per ust_marker */
 #define LTT_NR_CALLBACKS       10
 
 struct ltt_serialize_closure;
 struct ltt_probe_private_data;
 
-/* Serialization callback '%k' */
-typedef size_t (*ltt_serialize_cb)(struct rchan_buf *buf, size_t buf_offset,
-                       struct ltt_serialize_closure *closure,
-                       void *serialize_private, int *largest_align,
-                       const char *fmt, va_list *args);
-
 struct ltt_serialize_closure {
        ltt_serialize_cb *callbacks;
        long cb_args[LTT_NR_CALLBACKS];
        unsigned int cb_idx;
 };
 
-extern size_t ltt_serialize_data(struct rchan_buf *buf, size_t buf_offset,
+extern size_t ltt_serialize_data(struct ust_buffer *buf, size_t buf_offset,
                        struct ltt_serialize_closure *closure,
                        void *serialize_private,
-                       int *largest_align, const char *fmt, va_list *args);
-
-struct ltt_available_probe {
-       const char *name;               /* probe name */
-       const char *format;
-       marker_probe_func *probe_func;
-       ltt_serialize_cb callbacks[LTT_NR_CALLBACKS];
-       struct list_head node;          /* registered probes list */
-};
+                       unsigned int stack_pos_ctx, int *largest_align,
+                       const char *fmt, va_list *args);
 
 struct ltt_probe_private_data {
-       struct ltt_trace_struct *trace; /*
+       struct ust_trace *trace;        /*
                                         * Target trace, for metadata
                                         * or statedump.
                                         */
@@ -100,38 +89,44 @@ enum ltt_channels {
        LTT_CHANNEL_UST,
 };
 
-struct ltt_active_marker {
-       struct list_head node;          /* active markers list */
+struct chan_info_struct {
+       const char *name;
+       unsigned int def_subbufsize;
+       unsigned int def_subbufcount;
+};
+
+struct ltt_active_ust_marker {
+       struct cds_list_head node;              /* active markers list */
        const char *channel;
        const char *name;
        const char *format;
        struct ltt_available_probe *probe;
 };
 
-struct marker; //ust//
-extern void ltt_vtrace(const struct marker *mdata, void *probe_data,
-       struct registers *regs, void *call_data, const char *fmt, va_list *args);
-extern void ltt_trace(const struct marker *mdata, void *probe_data,
-       struct registers *regs, void *call_data, const char *fmt, ...);
+struct ust_marker; //ust//
+extern void ltt_vtrace(const struct ust_marker *mdata, void *probe_data,
+       void *call_data, const char *fmt, va_list *args);
+extern void ltt_trace(const struct ust_marker *mdata, void *probe_data,
+       void *call_data, const char *fmt, ...);
 
 /*
  * Unique ID assigned to each registered probe.
  */
-enum marker_id {
-       MARKER_ID_SET_MARKER_ID = 0,    /* Static IDs available (range 0-7) */
-       MARKER_ID_SET_MARKER_FORMAT,
-       MARKER_ID_COMPACT,              /* Compact IDs (range: 8-127)       */
-       MARKER_ID_DYNAMIC,              /* Dynamic IDs (range: 128-65535)   */
+enum ust_marker_id {
+       UST_MARKER_ID_SET_MARKER_ID = 0,        /* Static IDs available (range 0-7) */
+       UST_MARKER_ID_SET_MARKER_FORMAT,
+       UST_MARKER_ID_COMPACT,          /* Compact IDs (range: 8-127)       */
+       UST_MARKER_ID_DYNAMIC,          /* Dynamic IDs (range: 128-65535)   */
 };
 
 /* static ids 0-1 reserved for internal use. */
-#define MARKER_CORE_IDS                2
-static inline enum marker_id marker_id_type(uint16_t id)
+#define UST_MARKER_CORE_IDS            2
+static __inline__ enum ust_marker_id ust_marker_id_type(uint16_t id)
 {
-       if (id < MARKER_CORE_IDS)
-               return (enum marker_id)id;
+       if (id < UST_MARKER_CORE_IDS)
+               return (enum ust_marker_id)id;
        else
-               return MARKER_ID_DYNAMIC;
+               return UST_MARKER_ID_DYNAMIC;
 }
 
 struct user_dbg_data {
@@ -142,39 +137,30 @@ struct user_dbg_data {
 
 struct ltt_trace_ops {
        /* First 32 bytes cache-hot cacheline */
-       int (*reserve_slot) (struct ltt_trace_struct *trace,
-                               struct ltt_channel_struct *channel,
-                               void **transport_data, size_t data_size,
-                               size_t *slot_size, long *buf_offset, u64 *tsc,
-                               unsigned int *rflags,
-                               int largest_align);
-//ust//        void (*commit_slot) (struct ltt_channel_struct *channel,
-//ust//                                void **transport_data, long buf_offset,
-//ust//                                size_t slot_size);
-       void (*wakeup_channel) (struct ltt_channel_struct *ltt_channel);
-       int (*user_blocking) (struct ltt_trace_struct *trace,
+       void (*wakeup_channel) (struct ust_channel *channel);
+       int (*user_blocking) (struct ust_trace *trace,
                                unsigned int index, size_t data_size,
                                struct user_dbg_data *dbg);
-       /* End of first 32 bytes cacheline */
-       int (*create_dirs) (struct ltt_trace_struct *new_trace);
-       void (*remove_dirs) (struct ltt_trace_struct *new_trace);
-       int (*create_channel) (const char *trace_name,
-                               struct ltt_trace_struct *trace,
-                               struct dentry *dir, const char *channel_name,
-                               struct ltt_channel_struct *ltt_chan,
-                               unsigned int subbuf_size,
-                               unsigned int n_subbufs, int overwrite);
-       void (*finish_channel) (struct ltt_channel_struct *channel);
-       void (*remove_channel) (struct ltt_channel_struct *channel);
-       void (*user_errors) (struct ltt_trace_struct *trace,
-                               unsigned int index, size_t data_size,
-                               struct user_dbg_data *dbg);
-} ____cacheline_aligned;
+       /* End of first 32 bytes cacheline */
+       int (*create_dirs) (struct ust_trace *new_trace);
+       void (*remove_dirs) (struct ust_trace *new_trace);
+       int (*create_channel) (const char *trace_name,
+                               struct ust_trace *trace,
+                               const char *channel_name,
+                               struct ust_channel *channel,
+                               unsigned int subbuf_size,
+                               unsigned int n_subbufs, int overwrite);
+       void (*finish_channel) (struct ust_channel *channel);
+       void (*remove_channel) (struct ust_channel *channel);
+       void (*user_errors) (struct ust_trace *trace,
+                               unsigned int index, size_t data_size,
+                               struct user_dbg_data *dbg, unsigned int cpu);
+};
 
 struct ltt_transport {
        char *name;
        struct module *owner;
-       struct list_head node;
+       struct cds_list_head node;
        struct ltt_trace_ops ops;
 };
 
@@ -184,13 +170,13 @@ enum trace_mode { LTT_TRACE_NORMAL, LTT_TRACE_FLIGHT, LTT_TRACE_HYBRID };
 #define CHANNEL_FLAG_OVERWRITE (1U<<1)
 
 /* Per-trace information - each trace/flight recorder represented by one */
-struct ltt_trace_struct {
+struct ust_trace {
        /* First 32 bytes cache-hot cacheline */
-       struct list_head list;
+       struct cds_list_head list;
        struct ltt_trace_ops *ops;
        int active;
        /* Second 32 bytes cache-hot cacheline */
-       struct ltt_channel_struct *channels;
+       struct ust_channel *channels;
        unsigned int nr_channels;
        u32 freq_scale;
        u64 start_freq;
@@ -201,46 +187,12 @@ struct ltt_trace_struct {
        struct {
                struct dentry                   *trace_root;
        } dentry;
-       struct kref kref; /* Each channel has a kref of the trace struct */
+       struct urcu_ref urcu_ref; /* Each channel has a urcu_ref of the trace struct */
        struct ltt_transport *transport;
-       struct kref ltt_transport_kref;
+       struct urcu_ref ltt_transport_urcu_ref;
        char trace_name[NAME_MAX];
 } ____cacheline_aligned;
 
-/* Hardcoded event headers
- *
- * event header for a trace with active heartbeat : 27 bits timestamps
- *
- * headers are 32-bits aligned. In order to insure such alignment, a dynamic per
- * trace alignment value must be done.
- *
- * Remember that the C compiler does align each member on the boundary
- * equivalent to their own size.
- *
- * As relay subbuffers are aligned on pages, we are sure that they are 4 and 8
- * bytes aligned, so the buffer header and trace header are aligned.
- *
- * Event headers are aligned depending on the trace alignment option.
- *
- * Note using C structure bitfields for cross-endianness and portability
- * concerns.
- */
-
-#define LTT_RESERVED_EVENTS    3
-#define LTT_EVENT_BITS         5
-#define LTT_FREE_EVENTS                ((1 << LTT_EVENT_BITS) - LTT_RESERVED_EVENTS)
-#define LTT_TSC_BITS           27
-#define LTT_TSC_MASK           ((1 << LTT_TSC_BITS) - 1)
-
-struct ltt_event_header {
-       u32 id_time;            /* 5 bits event id (MSB); 27 bits time (LSB) */
-};
-
-/* Reservation flags */
-#define        LTT_RFLAG_ID                    (1 << 0)
-#define        LTT_RFLAG_ID_SIZE               (1 << 1)
-#define        LTT_RFLAG_ID_SIZE_TSC           (1 << 2)
-
 /*
  * We use asm/timex.h : cpu_khz/HZ variable in here : we might have to deal
  * specifically with CPU frequency scaling someday, so using an interpolation
@@ -271,8 +223,8 @@ struct ltt_subbuffer_header {
                                         * used all along the trace.
                                         */
        uint32_t freq_scale;            /* Frequency scaling (divisor) */
-       uint32_t lost_size;             /* Size unused at end of subbuffer */
-       uint32_t buf_size;              /* Size of this subbuffer */
+       uint32_t data_size;             /* Size of data in subbuffer */
+       uint32_t sb_size;               /* Subbuffer size (including padding) */
        uint32_t events_lost;           /*
                                         * Events lost in this subbuffer since
                                         * the beginning of the trace.
@@ -293,65 +245,16 @@ struct ltt_subbuffer_header {
  * structure because gcc generates inefficient code on some architectures
  * (powerpc, mips..)
  */
-static inline size_t ltt_subbuffer_header_size(void)
+static __inline__ size_t ltt_subbuffer_header_size(void)
 {
        return offsetof(struct ltt_subbuffer_header, header_end);
 }
 
-/*
- * ltt_get_header_size
- *
- * Calculate alignment offset to 32-bits. This is the alignment offset of the
- * event header.
- *
- * Important note :
- * The event header must be 32-bits. The total offset calculated here :
- *
- * Alignment of header struct on 32 bits (min arch size, header size)
- * + sizeof(header struct)  (32-bits)
- * + (opt) u16 (ext. event id)
- * + (opt) u16 (event_size) (if event_size == 0xFFFFUL, has ext. event size)
- * + (opt) u32 (ext. event size)
- * + (opt) u64 full TSC (aligned on min(64-bits, arch size))
- *
- * The payload must itself determine its own alignment from the biggest type it
- * contains.
- * */
-static inline unsigned char ltt_get_header_size(
-               struct ltt_channel_struct *channel,
-               size_t offset,
-               size_t data_size,
-               size_t *before_hdr_pad,
-               unsigned int rflags)
-{
-       size_t orig_offset = offset;
-       size_t padding;
-
-       padding = ltt_align(offset, sizeof(struct ltt_event_header));
-       offset += padding;
-       offset += sizeof(struct ltt_event_header);
-
-       switch (rflags) {
-       case LTT_RFLAG_ID_SIZE_TSC:
-               offset += sizeof(u16) + sizeof(u16);
-               if (data_size >= 0xFFFFU)
-                       offset += sizeof(u32);
-               offset += ltt_align(offset, sizeof(u64));
-               offset += sizeof(u64);
-               break;
-       case LTT_RFLAG_ID_SIZE:
-               offset += sizeof(u16) + sizeof(u16);
-               if (data_size >= 0xFFFFU)
-                       offset += sizeof(u32);
-               break;
-       case LTT_RFLAG_ID:
-               offset += sizeof(u16);
-               break;
-       }
-
-       *before_hdr_pad = padding;
-       return offset - orig_offset;
-}
+extern size_t ltt_write_event_header_slow(struct ust_channel *channel,
+               struct ust_buffer *buf, long buf_offset,
+               u16 eID, u32 event_size,
+               u64 tsc, unsigned int rflags);
+
 
 /*
  * ltt_write_event_header
@@ -369,141 +272,28 @@ static inline unsigned char ltt_get_header_size(
  *
  * returns : offset where the event data must be written.
  */
-static inline size_t ltt_write_event_header(struct ltt_trace_struct *trace,
-               struct ltt_channel_struct *channel,
-               struct rchan_buf *buf, long buf_offset,
-               u16 eID, size_t event_size,
+static __inline__ size_t ltt_write_event_header(struct ust_channel *chan,
+               struct ust_buffer *buf, long buf_offset,
+               u16 eID, u32 event_size,
                u64 tsc, unsigned int rflags)
 {
        struct ltt_event_header header;
-       size_t small_size;
-
-       switch (rflags) {
-       case LTT_RFLAG_ID_SIZE_TSC:
-               header.id_time = 29 << LTT_TSC_BITS;
-               break;
-       case LTT_RFLAG_ID_SIZE:
-               header.id_time = 30 << LTT_TSC_BITS;
-               break;
-       case LTT_RFLAG_ID:
-               header.id_time = 31 << LTT_TSC_BITS;
-               break;
-       default:
-               header.id_time = eID << LTT_TSC_BITS;
-               break;
-       }
+
+       if (unlikely(rflags))
+               goto slow_path;
+
+       header.id_time = eID << LTT_TSC_BITS;
        header.id_time |= (u32)tsc & LTT_TSC_MASK;
-       ltt_relay_write(buf, buf_offset, &header, sizeof(header));
+       ust_buffers_write(buf, buf_offset, &header, sizeof(header));
        buf_offset += sizeof(header);
 
-       switch (rflags) {
-       case LTT_RFLAG_ID_SIZE_TSC:
-               small_size = min_t(size_t, event_size, 0xFFFFU);
-               ltt_relay_write(buf, buf_offset,
-                       (u16[]){ (u16)eID }, sizeof(u16));
-               buf_offset += sizeof(u16);
-               ltt_relay_write(buf, buf_offset,
-                       (u16[]){ (u16)small_size }, sizeof(u16));
-               buf_offset += sizeof(u16);
-               if (small_size == 0xFFFFU) {
-                       ltt_relay_write(buf, buf_offset,
-                               (u32[]){ (u32)event_size }, sizeof(u32));
-                       buf_offset += sizeof(u32);
-               }
-               buf_offset += ltt_align(buf_offset, sizeof(u64));
-               ltt_relay_write(buf, buf_offset,
-                       (u64[]){ (u64)tsc }, sizeof(u64));
-               buf_offset += sizeof(u64);
-               break;
-       case LTT_RFLAG_ID_SIZE:
-               small_size = min_t(size_t, event_size, 0xFFFFU);
-               ltt_relay_write(buf, buf_offset,
-                       (u16[]){ (u16)eID }, sizeof(u16));
-               buf_offset += sizeof(u16);
-               ltt_relay_write(buf, buf_offset,
-                       (u16[]){ (u16)small_size }, sizeof(u16));
-               buf_offset += sizeof(u16);
-               if (small_size == 0xFFFFU) {
-                       ltt_relay_write(buf, buf_offset,
-                               (u32[]){ (u32)event_size }, sizeof(u32));
-                       buf_offset += sizeof(u32);
-               }
-               break;
-       case LTT_RFLAG_ID:
-               ltt_relay_write(buf, buf_offset,
-                       (u16[]){ (u16)eID }, sizeof(u16));
-               buf_offset += sizeof(u16);
-               break;
-       default:
-               break;
-       }
-
        return buf_offset;
-}
 
-/* Lockless LTTng */
-
-/*
- * ltt_reserve_slot
- *
- * Atomic slot reservation in a LTTng buffer. It will take care of
- * sub-buffer switching.
- *
- * Parameters:
- *
- * @trace : the trace structure to log to.
- * @channel : the chanel to reserve space into.
- * @transport_data : specific transport data.
- * @data_size : size of the variable length data to log.
- * @slot_size : pointer to total size of the slot (out)
- * @buf_offset : pointer to reserve offset (out)
- * @tsc : pointer to the tsc at the slot reservation (out)
- * @rflags : reservation flags (header specificity)
- * @cpu : cpu id
- *
- * Return : -ENOSPC if not enough space, else 0.
- */
-static inline int ltt_reserve_slot(
-               struct ltt_trace_struct *trace,
-               struct ltt_channel_struct *channel,
-               void **transport_data,
-               size_t data_size,
-               size_t *slot_size,
-               long *buf_offset,
-               u64 *tsc,
-               unsigned int *rflags,
-               int largest_align)
-{
-       return trace->ops->reserve_slot(trace, channel, transport_data,
-                       data_size, slot_size, buf_offset, tsc, rflags,
-                       largest_align);
+slow_path:
+       return ltt_write_event_header_slow(chan, buf, buf_offset,
+                               eID, event_size, tsc, rflags);
 }
 
-
-///*
-// * ltt_commit_slot
-// *
-// * Atomic unordered slot commit. Increments the commit count in the
-// * specified sub-buffer, and delivers it if necessary.
-// *
-// * Parameters:
-// *
-// * @channel : the chanel to reserve space into.
-// * @transport_data : specific transport data.
-// * @buf_offset : offset of beginning of reserved slot
-// * @slot_size : size of the reserved slot.
-// */
-//static inline void ltt_commit_slot(
-//             struct ltt_channel_struct *channel,
-//             void **transport_data,
-//             long buf_offset,
-//             size_t slot_size)
-//{
-//     struct ltt_trace_struct *trace = channel->trace;
-//
-//     trace->ops->commit_slot(channel, transport_data, buf_offset, slot_size);
-//}
-
 /*
  * Control channels :
  * control/metadata
@@ -534,7 +324,57 @@ static inline int ltt_reserve_slot(
 #define LTT_DEFAULT_N_SUBBUFS_HIGH     2
 #define LTT_TRACER_MAGIC_NUMBER                0x00D6B7ED
 #define LTT_TRACER_VERSION_MAJOR       2
-#define LTT_TRACER_VERSION_MINOR       3
+#define LTT_TRACER_VERSION_MINOR       6
+
+/**
+ * ust_write_trace_header - Write trace header
+ * @trace: Trace information
+ * @header: Memory address where the information must be written to
+ */
+static __inline__ void ltt_write_trace_header(struct ust_trace *trace,
+               struct ltt_subbuffer_header *header)
+{
+       header->magic_number = LTT_TRACER_MAGIC_NUMBER;
+       header->major_version = LTT_TRACER_VERSION_MAJOR;
+       header->minor_version = LTT_TRACER_VERSION_MINOR;
+       header->arch_size = sizeof(void *);
+       header->alignment = ltt_get_alignment();
+       header->start_time_sec = trace->start_time.tv_sec;
+       header->start_time_usec = trace->start_time.tv_usec;
+       header->start_freq = trace->start_freq;
+       header->freq_scale = trace->freq_scale;
+}
+
+#ifndef UST_VALGRIND
+
+static __inline__ int ust_get_cpu(void)
+{
+       int cpu;
+
+       cpu = sched_getcpu();
+       if (likely(cpu >= 0))
+               return cpu;
+       /*
+        * If getcpu(2) is not implemented in the Kernel use CPU 0 as fallback.
+        */
+       return 0;
+}
+
+#else  /* #else #ifndef UST_VALGRIND */
+
+static __inline__ int ust_get_cpu(void)
+{
+       /*
+        * Valgrind does not support the sched_getcpu() vsyscall.
+        * It causes it to detect a segfault in the program and stop it.
+        * So if we want to check libust with valgrind, we have to refrain
+        * from using this call. TODO: it would probably be better to return
+        * other values too, to better test it.
+        */
+       return 0;
+}
+
+#endif /* #else #ifndef UST_VALGRIND */
 
 /*
  * Size reserved for high priority events (interrupts, NMI, BH) at the end of a
@@ -571,7 +411,7 @@ union ltt_control_args {
 
 extern int _ltt_trace_setup(const char *trace_name);
 extern int ltt_trace_setup(const char *trace_name);
-extern struct ltt_trace_struct *_ltt_trace_find_setup(const char *trace_name);
+extern struct ust_trace *_ltt_trace_find_setup(const char *trace_name);
 extern int ltt_trace_set_type(const char *trace_name, const char *trace_type);
 extern int ltt_trace_set_channel_subbufsize(const char *trace_name,
                const char *channel_name, unsigned int size);
@@ -582,7 +422,7 @@ extern int ltt_trace_set_channel_enable(const char *trace_name,
 extern int ltt_trace_set_channel_overwrite(const char *trace_name,
                const char *channel_name, unsigned int overwrite);
 extern int ltt_trace_alloc(const char *trace_name);
-extern int ltt_trace_destroy(const char *trace_name);
+extern int ltt_trace_destroy(const char *trace_name, int drop);
 extern int ltt_trace_start(const char *trace_name);
 extern int ltt_trace_stop(const char *trace_name);
 
@@ -596,28 +436,22 @@ extern int ltt_filter_control(enum ltt_filter_control_msg msg,
 
 extern struct dentry *get_filter_root(void);
 
-extern void ltt_write_trace_header(struct ltt_trace_struct *trace,
+extern void ltt_write_trace_header(struct ust_trace *trace,
                struct ltt_subbuffer_header *header);
-extern void ltt_buffer_destroy(struct ltt_channel_struct *ltt_chan);
+extern void ltt_buffer_destroy(struct ust_channel *ltt_chan);
 
 extern void ltt_core_register(int (*function)(u8, void *));
 
 extern void ltt_core_unregister(void);
 
-extern void ltt_release_trace(struct kref *kref);
-extern void ltt_release_transport(struct kref *kref);
+extern void ltt_release_trace(struct urcu_ref *urcu_ref);
+extern void ltt_release_transport(struct urcu_ref *urcu_ref);
 
-extern int ltt_probe_register(struct ltt_available_probe *pdata);
-extern int ltt_probe_unregister(struct ltt_available_probe *pdata);
-extern int ltt_marker_connect(const char *channel, const char *mname,
-               const char *pname);
-extern int ltt_marker_disconnect(const char *channel, const char *mname,
-               const char *pname);
-extern void ltt_dump_marker_state(struct ltt_trace_struct *trace);
+extern void ltt_dump_ust_marker_state(struct ust_trace *trace);
 
 extern void ltt_lock_traces(void);
 extern void ltt_unlock_traces(void);
 
-extern struct ltt_trace_struct *_ltt_trace_find(const char *trace_name);
+extern struct ust_trace *_ltt_trace_find(const char *trace_name);
 
 #endif /* _LTT_TRACER_H */
This page took 0.030908 seconds and 4 git commands to generate.