#include <linux/kref.h>
#include <linux/uuid.h>
#include <linux/irq_work.h>
-#include <wrapper/uprobes.h>
+#include <linux/uprobes.h>
+
#include <lttng/cpuhotplug.h>
#include <lttng/tracer.h>
#include <lttng/abi.h>
#define lttng_is_signed_type(type) (((type) -1) < (type) 1)
-struct lttng_channel;
-struct lttng_session;
-struct lttng_metadata_cache;
+struct lttng_kernel_channel_buffer;
+struct lttng_kernel_session;
struct lttng_kernel_ring_buffer_ctx;
-struct perf_event;
-struct perf_event_attr;
-struct lib_ring_buffer_config;
/* Type description */
NR_LTTNG_KERNEL_STRING_ENCODING,
};
-enum channel_type {
- PER_CPU_CHANNEL,
- METADATA_CHANNEL,
-};
-
struct lttng_kernel_enum_value {
unsigned long long value;
unsigned int signedness:1;
unsigned int size; /* in bits */
unsigned short alignment; /* in bits */
unsigned int signedness:1,
- reverse_byte_order:1;
+ reverse_byte_order:1,
+ user:1; /* fetch from user-space */
unsigned int base; /* 2, 8, 10, 16, for pretty print */
};
struct lttng_kernel_type_string {
struct lttng_kernel_type_common parent;
enum lttng_kernel_string_encoding encoding;
+ unsigned int user:1; /* fetch from user-space */
};
struct lttng_kernel_type_enum {
struct lttng_kernel_type_common parent;
const struct lttng_kernel_type_common *elem_type;
unsigned int length; /* Num. elems. */
- unsigned int alignment;
+ unsigned int alignment; /* Alignment in bytes before elements. */
enum lttng_kernel_string_encoding encoding;
};
struct lttng_kernel_type_common parent;
const char *length_name; /* Length field name. If NULL, use previous field. */
const struct lttng_kernel_type_common *elem_type;
- unsigned int alignment; /* Alignment before elements. */
+ unsigned int alignment; /* Alignment in bytes before elements. */
enum lttng_kernel_string_encoding encoding;
};
struct lttng_kernel_type_struct {
struct lttng_kernel_type_common parent;
unsigned int nr_fields;
- const struct lttng_kernel_event_field **fields; /* Array of pointers to fields. */
- unsigned int alignment;
+ const struct lttng_kernel_event_field * const *fields; /* Array of pointers to fields. */
+ unsigned int alignment; /* Alignment in bits */
};
struct lttng_kernel_type_variant {
struct lttng_kernel_type_common parent;
const char *tag_name; /* Tag field name. If NULL, use previous field. */
- const struct lttng_kernel_event_field **choices; /* Array of pointers to fields. */
+ const struct lttng_kernel_event_field * const *choices; /* Array of pointers to fields. */
unsigned int nr_choices;
- unsigned int alignment;
+ unsigned int alignment; /* Alignment in bytes */
};
struct lttng_kernel_enum_desc {
const char *name;
- const struct lttng_kernel_enum_entry **entries;
+ const struct lttng_kernel_enum_entry * const *entries;
unsigned int nr_entries;
+ const struct lttng_kernel_probe_desc *probe_desc;
};
/* Event field description */
const char *name;
const struct lttng_kernel_type_common *type;
unsigned int nowrite:1, /* do not write into trace */
- user:1, /* fetch from user-space */
nofilter:1; /* do not consider for filter */
};
-#define lttng_kernel_static_type_integer(_size, _alignment, _signedness, _byte_order, _base) \
+#ifndef PARAMS
+#define PARAMS(args...) args
+#endif
+
+#define _lttng_kernel_static_type_integer(_size, _alignment, _signedness, _byte_order, _user, _base) \
((const struct lttng_kernel_type_common *) __LTTNG_COMPOUND_LITERAL(const struct lttng_kernel_type_integer, { \
.parent = { \
.type = lttng_kernel_type_integer, \
.alignment = (_alignment), \
.signedness = (_signedness), \
.reverse_byte_order = (_byte_order) != __BYTE_ORDER, \
+ .user = (_user), \
.base = (_base), \
}))
-#define lttng_kernel_static_type_integer_from_type(_type, _byte_order, _base) \
- lttng_kernel_static_type_integer(sizeof(_type) * CHAR_BIT, \
+#define lttng_kernel_static_type_integer(_size, _alignment, _signedness, _byte_order, _base) \
+ _lttng_kernel_static_type_integer(_size, _alignment, _signedness, _byte_order, 0, _base)
+
+#define lttng_kernel_static_type_user_integer(_size, _alignment, _signedness, _byte_order, _base) \
+ _lttng_kernel_static_type_integer(_size, _alignment, _signedness, _byte_order, 1, _base)
+
+#define _lttng_kernel_static_type_integer_from_type(_type, _byte_order, _user, _base) \
+ _lttng_kernel_static_type_integer(sizeof(_type) * CHAR_BIT, \
lttng_alignof(_type) * CHAR_BIT, \
lttng_is_signed_type(_type), \
- _byte_order, \
- _base)
+ _byte_order, _user, _base)
+
+#define lttng_kernel_static_type_integer_from_type(_type, _byte_order, _base) \
+ _lttng_kernel_static_type_integer_from_type(_type, _byte_order, 0, _base)
+
+#define lttng_kernel_static_type_user_integer_from_type(_type, _byte_order, _base) \
+ _lttng_kernel_static_type_integer_from_type(_type, _byte_order, 1, _base)
#define lttng_kernel_static_type_enum(_desc, _container_type) \
((const struct lttng_kernel_type_common *) __LTTNG_COMPOUND_LITERAL(const struct lttng_kernel_type_enum, { \
.elem_type = (_elem_type), \
}))
-#define lttng_kernel_static_type_string(_encoding) \
+#define lttng_kernel_static_type_string(_encoding, _user) \
((const struct lttng_kernel_type_common *) __LTTNG_COMPOUND_LITERAL(const struct lttng_kernel_type_string, { \
.parent = { \
.type = lttng_kernel_type_string, \
}, \
.encoding = lttng_kernel_string_encoding_##_encoding, \
+ .user = (_user), \
}))
-#define lttng_kernel_static_type_struct(_nr_fields, _fields, _alignment) \
- ((const struct lttng_kernel_type_common *) __LTTNG_COMPOUND_LITERAL(const struct lttng_kernel_type_struct, { \
+#define lttng_kernel_static_type_struct_init(_nr_fields, _fields, _alignment) \
+ { \
.parent = { \
.type = lttng_kernel_type_struct, \
}, \
.nr_fields = (_nr_fields), \
.fields = _fields, \
.alignment = (_alignment), \
- }))
+ }
+
+#define lttng_kernel_static_type_struct(_nr_fields, _fields, _alignment) \
+ ((const struct lttng_kernel_type_common *) __LTTNG_COMPOUND_LITERAL(const struct lttng_kernel_type_struct, \
+ lttng_kernel_static_type_struct_init(_nr_fields, PARAMS(_fields), _alignment) \
+ ))
#define lttng_kernel_static_type_variant(_nr_choices, _choices, _tag_name, _alignment) \
((const struct lttng_kernel_type_common *) __LTTNG_COMPOUND_LITERAL(const struct lttng_kernel_type_variant, { \
.alignment = (_alignment), \
}))
-#define lttng_kernel_static_event_field(_name, _type, _nowrite, _user, _nofilter) \
+#define lttng_kernel_static_event_field(_name, _type, _nowrite, _nofilter) \
__LTTNG_COMPOUND_LITERAL(const struct lttng_kernel_event_field, { \
.name = (_name), \
.type = (_type), \
.nowrite = (_nowrite), \
- .user = (_user), \
.nofilter = (_nofilter), \
})
uint8_t interruptible;
};
+struct lttng_kernel_tracepoint_class {
+ void (*probe_callback)(void);
+ const struct lttng_kernel_event_field * const *fields; /* event payload */
+ unsigned int nr_fields;
+ const struct lttng_kernel_probe_desc *probe_desc;
+};
+
struct lttng_kernel_event_desc {
const char *event_name; /* lttng-modules name */
const char *event_kname; /* Linux kernel name (tracepoints) */
const struct lttng_kernel_probe_desc *probe_desc;
- void (*probe_callback)(void);
- const struct lttng_kernel_event_field **fields; /* event payload */
- unsigned int nr_fields;
+ const struct lttng_kernel_tracepoint_class *tp_class;
struct module *owner;
};
struct lttng_kernel_probe_desc {
const char *provider_name;
- const struct lttng_kernel_event_desc **event_desc;
+ const struct lttng_kernel_event_desc * const *event_desc;
unsigned int nr_events;
struct list_head head; /* chain registered probes */
struct list_head lazy_init_head;
struct lttng_kernel_event_common parent;
struct lttng_kernel_event_recorder_private *priv; /* Private event record interface */
- struct lttng_channel *chan;
+ struct lttng_kernel_channel_buffer *chan;
};
struct lttng_kernel_notification_ctx {
int (*event_reserve)(struct lttng_kernel_ring_buffer_ctx *ctx);
void (*event_commit)(struct lttng_kernel_ring_buffer_ctx *ctx);
void (*event_write)(struct lttng_kernel_ring_buffer_ctx *ctx, const void *src,
- size_t len);
+ size_t len, size_t alignment);
void (*event_write_from_user)(struct lttng_kernel_ring_buffer_ctx *ctx,
- const void *src, size_t len);
+ const void *src, size_t len, size_t alignment);
void (*event_memset)(struct lttng_kernel_ring_buffer_ctx *ctx,
int c, size_t len);
void (*event_strcpy)(struct lttng_kernel_ring_buffer_ctx *ctx, const char *src,
size_t len);
void (*event_strcpy_from_user)(struct lttng_kernel_ring_buffer_ctx *ctx,
const char __user *src, size_t len);
+ void (*event_pstrcpy_pad)(struct lttng_kernel_ring_buffer_ctx *ctx,
+ const char *src, size_t len);
+ void (*event_pstrcpy_pad_from_user)(struct lttng_kernel_ring_buffer_ctx *ctx,
+ const char __user *src, size_t len);
+ void (*lost_event_too_big)(struct lttng_kernel_channel_buffer *lttng_channel);
};
-struct lttng_syscall_filter;
+enum lttng_kernel_channel_type {
+ LTTNG_KERNEL_CHANNEL_TYPE_BUFFER = 0,
+};
-#define LTTNG_EVENT_HT_BITS 12
-#define LTTNG_EVENT_HT_SIZE (1U << LTTNG_EVENT_HT_BITS)
+struct lttng_kernel_channel_common_private;
-struct lttng_event_ht {
- struct hlist_head table[LTTNG_EVENT_HT_SIZE];
-};
+/* Use container_of() to get child. */
+struct lttng_kernel_channel_common {
+ struct lttng_kernel_channel_common_private *priv; /* Private channel interface. */
-#define LTTNG_EVENT_NOTIFIER_HT_BITS 12
-#define LTTNG_EVENT_NOTIFIER_HT_SIZE (1U << LTTNG_EVENT_NOTIFIER_HT_BITS)
+ enum lttng_kernel_channel_type type;
-struct lttng_event_notifier_ht {
- struct hlist_head table[LTTNG_EVENT_NOTIFIER_HT_SIZE];
+ int enabled;
+ struct lttng_kernel_session *session;
};
-struct lttng_channel {
- unsigned int id;
- struct channel *chan; /* Channel buffers */
- int enabled;
- struct lttng_kernel_ctx *ctx;
- /* Event ID management */
- struct lttng_session *session;
- struct file *file; /* File associated to channel */
- unsigned int free_event_id; /* Next event ID to allocate */
- struct list_head list; /* Channel list */
+struct lttng_kernel_channel_buffer_private;
+
+struct lttng_kernel_channel_buffer {
+ struct lttng_kernel_channel_common parent;
+ struct lttng_kernel_channel_buffer_private *priv;
+
struct lttng_kernel_channel_buffer_ops *ops;
- struct lttng_transport *transport;
- struct hlist_head *sc_table; /* for syscall tracing */
- struct hlist_head *compat_sc_table;
- struct hlist_head *sc_exit_table; /* for syscall exit tracing */
- struct hlist_head *compat_sc_exit_table;
- struct hlist_head sc_unknown; /* for unknown syscalls */
- struct hlist_head sc_compat_unknown;
- struct hlist_head sc_exit_unknown;
- struct hlist_head compat_sc_exit_unknown;
- struct lttng_syscall_filter *sc_filter;
- int header_type; /* 0: unset, 1: compact, 2: large */
- enum channel_type channel_type;
- int syscall_all_entry;
- int syscall_all_exit;
- unsigned int metadata_dumped:1,
- sys_enter_registered:1,
- sys_exit_registered:1,
- tstate:1; /* Transient enable state */
-};
-
-struct lttng_metadata_stream {
- void *priv; /* Ring buffer private data */
- struct lttng_metadata_cache *metadata_cache;
- unsigned int metadata_in; /* Bytes read from the cache */
- unsigned int metadata_out; /* Bytes consumed from stream */
- int finalized; /* Has channel been finalized */
- wait_queue_head_t read_wait; /* Reader buffer-level wait queue */
- struct list_head list; /* Stream list */
- struct lttng_transport *transport;
- uint64_t version; /* Current version of the metadata cache */
- bool coherent; /* Stream in a coherent state */
};
#define LTTNG_DYNAMIC_LEN_STACK_SIZE 128
DECLARE_PER_CPU(struct lttng_dynamic_len_stack, lttng_dynamic_len_stack);
/*
- * struct lttng_id_tracker declared in header due to deferencing of *v
+ * struct lttng_kernel_id_tracker declared in header due to deferencing of *v
* in RCU_INITIALIZER(v).
*/
#define LTTNG_ID_HASH_BITS 6
#define LTTNG_ID_TABLE_SIZE (1 << LTTNG_ID_HASH_BITS)
-enum tracker_type {
- TRACKER_PID,
- TRACKER_VPID,
- TRACKER_UID,
- TRACKER_VUID,
- TRACKER_GID,
- TRACKER_VGID,
-
- TRACKER_UNKNOWN,
-};
-
-struct lttng_id_tracker_rcu {
+struct lttng_kernel_id_tracker_rcu {
struct hlist_head id_hash[LTTNG_ID_TABLE_SIZE];
};
-struct lttng_id_tracker {
- struct lttng_session *session;
- enum tracker_type tracker_type;
- struct lttng_id_tracker_rcu *p; /* RCU dereferenced. */
-};
+struct lttng_kernel_id_tracker {
+ struct lttng_kernel_id_tracker_private *priv; /* Private API */
-struct lttng_id_hash_node {
- struct hlist_node hlist;
- int id;
+ struct lttng_kernel_id_tracker_rcu *p; /* RCU dereferenced. */
};
-struct lttng_session {
+struct lttng_kernel_session_private;
+
+struct lttng_kernel_session {
+ struct lttng_kernel_session_private *priv; /* Private session interface */
+
int active; /* Is trace session active ? */
- int been_active; /* Has trace session been active ? */
- struct file *file; /* File associated to session */
- struct list_head chan; /* Channel list head */
- struct list_head events; /* Event list head */
- struct list_head list; /* Session list */
- unsigned int free_chan_id; /* Next chan ID to allocate */
- uuid_le uuid; /* Trace session unique ID */
- struct lttng_metadata_cache *metadata_cache;
- struct lttng_id_tracker pid_tracker;
- struct lttng_id_tracker vpid_tracker;
- struct lttng_id_tracker uid_tracker;
- struct lttng_id_tracker vuid_tracker;
- struct lttng_id_tracker gid_tracker;
- struct lttng_id_tracker vgid_tracker;
- unsigned int metadata_dumped:1,
- tstate:1; /* Transient enable state */
- /* List of event enablers */
- struct list_head enablers_head;
- /* Hash table of events */
- struct lttng_event_ht events_ht;
- char name[LTTNG_KERNEL_ABI_SESSION_NAME_LEN];
- char creation_time[LTTNG_KERNEL_ABI_SESSION_CREATION_TIME_ISO8601_LEN];
+
+ struct lttng_kernel_id_tracker pid_tracker;
+ struct lttng_kernel_id_tracker vpid_tracker;
+ struct lttng_kernel_id_tracker uid_tracker;
+ struct lttng_kernel_id_tracker vuid_tracker;
+ struct lttng_kernel_id_tracker gid_tracker;
+ struct lttng_kernel_id_tracker vgid_tracker;
};
int lttng_kernel_probe_register(struct lttng_kernel_probe_desc *desc);
void lttng_kernel_probe_unregister(struct lttng_kernel_probe_desc *desc);
-bool lttng_id_tracker_lookup(struct lttng_id_tracker_rcu *p, int id);
+bool lttng_id_tracker_lookup(struct lttng_kernel_id_tracker_rcu *p, int id);
#endif /* _LTTNG_EVENTS_H */