#include <linux/rculist.h>
#include <asm/byteorder.h>
#include <linux/swab.h>
+#include <linux/user_namespace.h>
-#include <lttng/types.h>
-#include <lttng/probe-user.h>
#include <wrapper/vmalloc.h> /* for wrapper_vmalloc_sync_mappings() */
#include <ringbuffer/frontend_types.h>
#include <ringbuffer/backend.h>
#include <wrapper/rcu.h>
-#include <wrapper/user_namespace.h>
-#include <lttng-events.h>
-#include <lttng-tracer-core.h>
-#include <lttng-tp-mempool.h>
+#include <lttng/types.h>
+#include <lttng/probe-user.h>
+#include <lttng/events.h>
+#include <lttng/tracer-core.h>
+#include <lttng/tp-mempool.h>
#define __LTTNG_NULL_STRING "(null)"
/* Enumeration entry (single value) */
#undef ctf_enum_value
#define ctf_enum_value(_string, _value) \
- { \
- .start = { \
- .signedness = lttng_is_signed_type(__typeof__(_value)), \
- .value = lttng_is_signed_type(__typeof__(_value)) ? \
- (long long) (_value) : (_value), \
- }, \
- .end = { \
- .signedness = lttng_is_signed_type(__typeof__(_value)), \
- .value = lttng_is_signed_type(__typeof__(_value)) ? \
- (long long) (_value) : (_value), \
- }, \
- .string = (_string), \
- },
+ lttng_kernel_static_enum_entry_value(_string, _value)
/* Enumeration entry (range) */
#undef ctf_enum_range
#define ctf_enum_range(_string, _range_start, _range_end) \
- { \
- .start = { \
- .signedness = lttng_is_signed_type(__typeof__(_range_start)), \
- .value = lttng_is_signed_type(__typeof__(_range_start)) ? \
- (long long) (_range_start) : (_range_start), \
- }, \
- .end = { \
- .signedness = lttng_is_signed_type(__typeof__(_range_end)), \
- .value = lttng_is_signed_type(__typeof__(_range_end)) ? \
- (long long) (_range_end) : (_range_end), \
- }, \
- .string = (_string), \
- },
+ lttng_kernel_static_enum_entry_range(_string, _range_start, _range_end)
/* Enumeration entry (automatic value; follows the rules of CTF) */
#undef ctf_enum_auto
-#define ctf_enum_auto(_string) \
- { \
- .start = { \
- .signedness = -1, \
- .value = -1, \
- }, \
- .end = { \
- .signedness = -1, \
- .value = -1, \
- }, \
- .string = (_string), \
- .options = { \
- .is_auto = 1, \
- } \
- },
+#define ctf_enum_auto(_string) \
+ lttng_kernel_static_enum_entry_auto(_string)
#undef TP_ENUM_VALUES
#define TP_ENUM_VALUES(...) \
__VA_ARGS__
-#undef LTTNG_TRACEPOINT_ENUM
-#define LTTNG_TRACEPOINT_ENUM(_name, _values) \
- const struct lttng_enum_entry __enum_values__##_name[] = { \
+#ifndef LTTNG_TRACEPOINT_TYPE_EXTERN
+# undef LTTNG_TRACEPOINT_ENUM
+# define LTTNG_TRACEPOINT_ENUM(_name, _values) \
+ static const struct lttng_kernel_enum_entry * const __enum_values__##_name[] = { \
_values \
};
+#endif
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
+/*
+ * Stage 1.3 of the trace events.
+ *
+ * Create probe callback prototypes.
+ */
+
+/* Reset all macros within TRACEPOINT_EVENT */
+#include <lttng/events-reset.h>
+
+#undef TP_PROTO
+#define TP_PROTO(...) __VA_ARGS__
+
+#undef LTTNG_TRACEPOINT_EVENT_CLASS_CODE
+#define LTTNG_TRACEPOINT_EVENT_CLASS_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
+static void __event_probe__##_name(void *__data, _proto);
+
+#undef LTTNG_TRACEPOINT_EVENT_CLASS_CODE_NOARGS
+#define LTTNG_TRACEPOINT_EVENT_CLASS_CODE_NOARGS(_name, _locvar, _code_pre, _fields, _code_post) \
+static void __event_probe__##_name(void *__data);
#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+/*
+ * Stage 1.4 of tracepoint event generation.
+ *
+ * Declare toplevel descriptor for the whole probe.
+ */
+
+#define TP_ID1(_token, _system) _token##_system
+#define TP_ID(_token, _system) TP_ID1(_token, _system)
+
+static __used struct lttng_kernel_probe_desc TP_ID(__probe_desc___, TRACE_SYSTEM);
+
+#undef TP_ID1
+#undef TP_ID
+
/*
* Stage 2 of the trace events.
*
#include <lttng/events-nowrite.h>
#undef _ctf_integer_ext
-#define _ctf_integer_ext(_type, _item, _src, _byte_order, _base, _user, _nowrite) \
- { \
- .name = #_item, \
- .type = __type_integer(_type, 0, 0, -1, _byte_order, _base, none), \
- .nowrite = _nowrite, \
- .user = _user, \
- .nofilter = 0, \
- },
+#define _ctf_integer_ext(_type, _item, _src, _byte_order, _base, _user, _nowrite) \
+ lttng_kernel_static_event_field(#_item, \
+ _lttng_kernel_static_type_integer_from_type(_type, _byte_order, _user, _base), \
+ _nowrite, 0),
#undef _ctf_array_encoded
#define _ctf_array_encoded(_type, _item, _src, _length, \
_encoding, _byte_order, _elem_type_base, _user, _nowrite) \
- { \
- .name = #_item, \
- .type = \
- { \
- .atype = atype_array_nestable, \
- .u = \
- { \
- .array_nestable = \
- { \
- .elem_type = __LTTNG_COMPOUND_LITERAL(struct lttng_type, \
- __type_integer(_type, 0, 0, -1, _byte_order, _elem_type_base, _encoding)), \
- .length = _length, \
- .alignment = 0, \
- } \
- } \
- }, \
- .nowrite = _nowrite, \
- .user = _user, \
- .nofilter = 0, \
- },
+ lttng_kernel_static_event_field(#_item, \
+ lttng_kernel_static_type_array(_length, \
+ _lttng_kernel_static_type_integer_from_type(_type, _byte_order, _user, _elem_type_base), \
+ 0, \
+ _encoding), \
+ _nowrite, 0),
#undef _ctf_array_bitfield
#define _ctf_array_bitfield(_type, _item, _src, _length, _user, _nowrite) \
- { \
- .name = #_item, \
- .type = \
- { \
- .atype = atype_array_nestable, \
- .u = \
- { \
- .array_nestable = \
- { \
- .elem_type = __LTTNG_COMPOUND_LITERAL(struct lttng_type, \
- __type_integer(_type, 1, 1, 0, __LITTLE_ENDIAN, 10, none)), \
- .length = (_length) * sizeof(_type) * CHAR_BIT, \
- .alignment = lttng_alignof(_type), \
- } \
- } \
- }, \
- .nowrite = _nowrite, \
- .user = _user, \
- .nofilter = 0, \
- },
-
+ lttng_kernel_static_event_field(#_item, \
+ lttng_kernel_static_type_array((_length) * sizeof(_type) * CHAR_BIT, \
+ _lttng_kernel_static_type_integer(1, 1, 0, __LITTLE_ENDIAN, _user, 10), \
+ lttng_alignof(_type), \
+ none), \
+ _nowrite, 0),
#undef _ctf_sequence_encoded
#define _ctf_sequence_encoded(_type, _item, _src, \
_length_type, _src_length, _encoding, \
_byte_order, _elem_type_base, _user, _nowrite) \
- { \
- .name = "_" #_item "_length", \
- .type = __type_integer(_length_type, 0, 0, -1, __BYTE_ORDER, 10, none), \
- .nowrite = _nowrite, \
- .nofilter = 1, \
- }, \
- { \
- .name = #_item, \
- .type = \
- { \
- .atype = atype_sequence_nestable, \
- .u = \
- { \
- .sequence_nestable = \
- { \
- .length_name = "_" #_item "_length", \
- .elem_type = __LTTNG_COMPOUND_LITERAL(struct lttng_type, \
- __type_integer(_type, 0, 0, -1, _byte_order, _elem_type_base, _encoding)), \
- .alignment = 0, \
- }, \
- }, \
- }, \
- .nowrite = _nowrite, \
- .user = _user, \
- .nofilter = 0, \
- },
+ lttng_kernel_static_event_field("_" #_item "_length", \
+ lttng_kernel_static_type_integer_from_type(_length_type, __BYTE_ORDER, 10), \
+ _nowrite, 1), \
+ lttng_kernel_static_event_field(#_item, \
+ lttng_kernel_static_type_sequence(NULL, /* Use previous field. */ \
+ _lttng_kernel_static_type_integer_from_type(_type, _byte_order, _user, _elem_type_base), \
+ 0, \
+ _encoding), \
+ _nowrite, 0),
#undef _ctf_sequence_bitfield
#define _ctf_sequence_bitfield(_type, _item, _src, \
_length_type, _src_length, \
_user, _nowrite) \
- { \
- .name = "_" #_item "_length", \
- .type = __type_integer(_length_type, 0, 0, -1, __BYTE_ORDER, 10, none), \
- .nowrite = _nowrite, \
- .nofilter = 1, \
- }, \
- { \
- .name = #_item, \
- .type = \
- { \
- .atype = atype_sequence_nestable, \
- .u = \
- { \
- .sequence_nestable = \
- { \
- .length_name = "_" #_item "_length", \
- .elem_type = __LTTNG_COMPOUND_LITERAL(struct lttng_type, \
- __type_integer(_type, 1, 1, 0, __LITTLE_ENDIAN, 10, none)), \
- .alignment = lttng_alignof(_type), \
- }, \
- }, \
- }, \
- .nowrite = _nowrite, \
- .user = _user, \
- .nofilter = 0, \
- },
+ lttng_kernel_static_event_field("_" #_item "_length", \
+ lttng_kernel_static_type_integer_from_type(_length_type, __BYTE_ORDER, 10), \
+ _nowrite, 1), \
+ lttng_kernel_static_event_field(#_item, \
+ lttng_kernel_static_type_sequence(NULL, /* Use previous field. */ \
+ _lttng_kernel_static_type_integer(1, 1, 0, __LITTLE_ENDIAN, _user, 10), \
+ lttng_alignof(_type), \
+ none), \
+ _nowrite, 0),
#undef _ctf_string
#define _ctf_string(_item, _src, _user, _nowrite) \
- { \
- .name = #_item, \
- .type = \
- { \
- .atype = atype_string, \
- .u = \
- { \
- .string = { .encoding = lttng_encode_UTF8 }, \
- }, \
- }, \
- .nowrite = _nowrite, \
- .user = _user, \
- .nofilter = 0, \
- },
+ lttng_kernel_static_event_field(#_item, \
+ lttng_kernel_static_type_string(UTF8, _user), \
+ _nowrite, 0),
+
+#undef _ctf_unused
+#define _ctf_unused(_src)
#undef _ctf_enum
#define _ctf_enum(_name, _type, _item, _src, _user, _nowrite) \
- { \
- .name = #_item, \
- .type = { \
- .atype = atype_enum_nestable, \
- .u = { \
- .enum_nestable = { \
- .desc = &__enum_##_name, \
- .container_type = __LTTNG_COMPOUND_LITERAL(struct lttng_type, \
- __type_integer(_type, 0, 0, -1, __BYTE_ORDER, 10, none)), \
- }, \
- }, \
- }, \
- .nowrite = _nowrite, \
- .user = _user, \
- .nofilter = 0, \
- },
+ lttng_kernel_static_event_field(#_item, \
+ lttng_kernel_static_type_enum(&__enum_##_name, \
+ _lttng_kernel_static_type_integer_from_type(_type, __BYTE_ORDER, _user, 10)), \
+ _nowrite, 0),
#undef ctf_custom_field
#define ctf_custom_field(_type, _item, _code) \
- { \
- .name = #_item, \
- .type = _type, \
- .nowrite = 0, \
- .user = 0, \
- .nofilter = 1, \
- },
+ lttng_kernel_static_event_field(#_item, PARAMS(_type), 0, 1),
#undef ctf_custom_type
#define ctf_custom_type(...) __VA_ARGS__
#undef TP_FIELDS
#define TP_FIELDS(...) __VA_ARGS__ /* Only one used in this phase */
+#ifndef TP_PROBE_CB
+#define TP_PROBE_CB(_template) &__event_probe__##_template
+#endif
+
#undef LTTNG_TRACEPOINT_EVENT_CLASS_CODE_NOARGS
#define LTTNG_TRACEPOINT_EVENT_CLASS_CODE_NOARGS(_name, _locvar, _code_pre, _fields, _code_post) \
- static const struct lttng_event_field __event_fields___##_name[] = { \
+ static const struct lttng_kernel_event_field * const __event_fields___##_name[] = { \
_fields \
+ }; \
+ static const struct lttng_kernel_tracepoint_class lttng_kernel__event_class___##_name = { \
+ .fields = __event_fields___##_name, \
+ .nr_fields = ARRAY_SIZE(__event_fields___##_name), \
+ .probe_callback = (void (*)(void)) TP_PROBE_CB(_name), \
+ .probe_desc = &TP_ID(__probe_desc___, TRACE_SYSTEM), \
};
#undef LTTNG_TRACEPOINT_EVENT_CLASS_CODE
#define LTTNG_TRACEPOINT_EVENT_CLASS_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
LTTNG_TRACEPOINT_EVENT_CLASS_CODE_NOARGS(_name, _locvar, _code_pre, PARAMS(_fields), _code_post)
-#undef LTTNG_TRACEPOINT_ENUM
-#define LTTNG_TRACEPOINT_ENUM(_name, _values) \
- static const struct lttng_enum_desc __enum_##_name = { \
- .name = #_name, \
- .entries = __enum_values__##_name, \
- .nr_entries = ARRAY_SIZE(__enum_values__##_name), \
- };
-
-#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+#ifdef LTTNG_TRACEPOINT_TYPE_EXTERN
+# undef LTTNG_TRACEPOINT_TYPE
+# define LTTNG_TRACEPOINT_TYPE(_prototype, _init) \
+ extern _prototype;
+#elif defined (LTTNG_TRACEPOINT_TYPE_DEFINE_EXPORT)
+# define LTTNG_TRACEPOINT_TYPE_VISIBILITY __attribute__((visibility("hidden")))
+#else
+# define LTTNG_TRACEPOINT_TYPE_VISIBILITY static
+#endif
-/*
- * Stage 3 of the trace events.
- *
- * Create probe callback prototypes.
- */
+#ifdef LTTNG_TRACEPOINT_TYPE_VISIBILITY
+# undef LTTNG_TRACEPOINT_TYPE
+# define LTTNG_TRACEPOINT_TYPE(_prototype, _init) \
+ LTTNG_TRACEPOINT_TYPE_VISIBILITY _prototype = _init;
+#endif
-/* Reset all macros within TRACEPOINT_EVENT */
-#include <lttng/events-reset.h>
+# undef LTTNG_TRACEPOINT_ENUM
+# define LTTNG_TRACEPOINT_ENUM(_name, _values) \
+ LTTNG_TRACEPOINT_TYPE(PARAMS(const struct lttng_kernel_enum_desc __enum_##_name), \
+ PARAMS({ \
+ .name = #_name, \
+ .entries = __enum_values__##_name, \
+ .nr_entries = ARRAY_SIZE(__enum_values__##_name), \
+ .probe_desc = &TP_ID(__probe_desc___, TRACE_SYSTEM), \
+ }))
-#undef TP_PROTO
-#define TP_PROTO(...) __VA_ARGS__
+#define TP_ID1(_token, _system) _token##_system
+#define TP_ID(_token, _system) TP_ID1(_token, _system)
-#undef LTTNG_TRACEPOINT_EVENT_CLASS_CODE
-#define LTTNG_TRACEPOINT_EVENT_CLASS_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
-static void __event_probe__##_name(void *__data, _proto);
+#define LTTNG_CREATE_FIELD_METADATA
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+#undef LTTNG_CREATE_FIELD_METADATA
-#undef LTTNG_TRACEPOINT_EVENT_CLASS_CODE_NOARGS
-#define LTTNG_TRACEPOINT_EVENT_CLASS_CODE_NOARGS(_name, _locvar, _code_pre, _fields, _code_post) \
-static void __event_probe__##_name(void *__data);
+#undef LTTNG_TRACEPOINT_TYPE_VISIBILITY
-#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+#undef TP_ID1
+#undef TP_ID
/*
* Stage 4 of the trace events.
#undef LTTNG_TRACEPOINT_EVENT_CLASS_CODE_NOARGS
#define LTTNG_TRACEPOINT_EVENT_CLASS_CODE_NOARGS(_name, _locvar, _code_pre, _fields, _code_post) \
static inline \
-void __event_prepare_filter_stack__##_name(char *__stack_data, \
+void __event_prepare_interpreter_stack__##_name(char *__stack_data, \
void *__tp_locvar) \
{ \
struct { _locvar } *tp_locvar __attribute__((unused)) = __tp_locvar; \
#undef LTTNG_TRACEPOINT_EVENT_CLASS_CODE
#define LTTNG_TRACEPOINT_EVENT_CLASS_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
static inline \
-void __event_prepare_filter_stack__##_name(char *__stack_data, \
+void __event_prepare_interpreter_stack__##_name(char *__stack_data, \
void *__tp_locvar, _proto) \
{ \
struct { _locvar } *tp_locvar __attribute__((unused)) = __tp_locvar; \
#define _ctf_integer_ext_fetched(_type, _item, _src, _byte_order, _base, _nowrite) \
{ \
_type __tmp = _src; \
- lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__tmp));\
- __chan->ops->event_write(&__ctx, &__tmp, sizeof(__tmp));\
+ __chan->ops->event_write(&__ctx, &__tmp, sizeof(__tmp), lttng_alignof(__tmp)); \
}
#undef _ctf_integer_ext_isuser0
#undef _ctf_array_encoded
#define _ctf_array_encoded(_type, _item, _src, _length, _encoding, _byte_order, _base, _user, _nowrite) \
- lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_type)); \
- if (_user) { \
- __chan->ops->event_write_from_user(&__ctx, _src, sizeof(_type) * (_length)); \
- } else { \
- __chan->ops->event_write(&__ctx, _src, sizeof(_type) * (_length)); \
+ if (lttng_kernel_string_encoding_##_encoding == lttng_kernel_string_encoding_none) { \
+ if (_user) { \
+ __chan->ops->event_write_from_user(&__ctx, _src, sizeof(_type) * (_length), lttng_alignof(_type)); \
+ } else { \
+ __chan->ops->event_write(&__ctx, _src, sizeof(_type) * (_length), lttng_alignof(_type)); \
+ } \
+ } else { \
+ if (_user) { \
+ __chan->ops->event_pstrcpy_pad_from_user(&__ctx, (const char __user *) (_src), _length); \
+ } else { \
+ __chan->ops->event_pstrcpy_pad(&__ctx, (const char *) (_src), _length); \
+ } \
}
#if (__BYTE_ORDER == __LITTLE_ENDIAN)
#undef _ctf_array_bitfield
#define _ctf_array_bitfield(_type, _item, _src, _length, _user, _nowrite) \
- lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_type)); \
if (_user) { \
- __chan->ops->event_write_from_user(&__ctx, _src, sizeof(_type) * (_length)); \
+ __chan->ops->event_write_from_user(&__ctx, _src, sizeof(_type) * (_length), lttng_alignof(_type)); \
} else { \
- __chan->ops->event_write(&__ctx, _src, sizeof(_type) * (_length)); \
+ __chan->ops->event_write(&__ctx, _src, sizeof(_type) * (_length), lttng_alignof(_type)); \
}
#else /* #if (__BYTE_ORDER == __LITTLE_ENDIAN) */
/*
default: \
BUG_ON(1); \
} \
- __chan->ops->event_write(&__ctx, &_tmp, sizeof(_type)); \
+ __chan->ops->event_write(&__ctx, &_tmp, sizeof(_type), 1); \
} \
}
#endif /* #else #if (__BYTE_ORDER == __LITTLE_ENDIAN) */
#undef _ctf_sequence_encoded
-#define _ctf_sequence_encoded(_type, _item, _src, _length_type, \
+#define _ctf_sequence_encoded(_type, _item, _src, _length_type, \
_src_length, _encoding, _byte_order, _base, _user, _nowrite) \
- { \
+ { \
_length_type __tmpl = this_cpu_ptr(<tng_dynamic_len_stack)->stack[__dynamic_len_idx]; \
- lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_length_type));\
- __chan->ops->event_write(&__ctx, &__tmpl, sizeof(_length_type));\
- } \
- lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_type)); \
- if (_user) { \
- __chan->ops->event_write_from_user(&__ctx, _src, \
- sizeof(_type) * __get_dynamic_len(dest)); \
- } else { \
- __chan->ops->event_write(&__ctx, _src, \
- sizeof(_type) * __get_dynamic_len(dest)); \
+ __chan->ops->event_write(&__ctx, &__tmpl, sizeof(_length_type), lttng_alignof(_length_type));\
+ } \
+ if (lttng_kernel_string_encoding_##_encoding == lttng_kernel_string_encoding_none) { \
+ if (_user) { \
+ __chan->ops->event_write_from_user(&__ctx, _src, \
+ sizeof(_type) * __get_dynamic_len(dest), lttng_alignof(_type)); \
+ } else { \
+ __chan->ops->event_write(&__ctx, _src, \
+ sizeof(_type) * __get_dynamic_len(dest), lttng_alignof(_type)); \
+ } \
+ } else { \
+ if (_user) { \
+ __chan->ops->event_pstrcpy_pad_from_user(&__ctx, (const char __user *) (_src), \
+ __get_dynamic_len(dest)); \
+ } else { \
+ __chan->ops->event_pstrcpy_pad(&__ctx, (const char *) (_src), \
+ __get_dynamic_len(dest)); \
+ } \
}
#if (__BYTE_ORDER == __LITTLE_ENDIAN)
_user, _nowrite) \
{ \
_length_type __tmpl = this_cpu_ptr(<tng_dynamic_len_stack)->stack[__dynamic_len_idx] * sizeof(_type) * CHAR_BIT; \
- lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_length_type));\
- __chan->ops->event_write(&__ctx, &__tmpl, sizeof(_length_type));\
+ __chan->ops->event_write(&__ctx, &__tmpl, sizeof(_length_type), lttng_alignof(_length_type)); \
} \
- lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_type)); \
if (_user) { \
__chan->ops->event_write_from_user(&__ctx, _src, \
- sizeof(_type) * __get_dynamic_len(dest)); \
+ sizeof(_type) * __get_dynamic_len(dest), lttng_alignof(_type)); \
} else { \
__chan->ops->event_write(&__ctx, _src, \
- sizeof(_type) * __get_dynamic_len(dest)); \
+ sizeof(_type) * __get_dynamic_len(dest), lttng_alignof(_type)); \
}
#else /* #if (__BYTE_ORDER == __LITTLE_ENDIAN) */
/*
_user, _nowrite) \
{ \
_length_type __tmpl = this_cpu_ptr(<tng_dynamic_len_stack)->stack[__dynamic_len_idx] * sizeof(_type) * CHAR_BIT; \
- lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_length_type));\
- __chan->ops->event_write(&__ctx, &__tmpl, sizeof(_length_type));\
+ __chan->ops->event_write(&__ctx, &__tmpl, sizeof(_length_type), lttng_alignof(_length_type)); \
} \
lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(_type)); \
{ \
default: \
BUG_ON(1); \
} \
- __chan->ops->event_write(&__ctx, &_tmp, sizeof(_type)); \
+ __chan->ops->event_write(&__ctx, &_tmp, sizeof(_type), 1); \
} \
}
#endif /* #else #if (__BYTE_ORDER == __LITTLE_ENDIAN) */
* 2*sizeof(unsigned long) for all supported architectures.
* Perform UNION (||) of filter runtime list.
*/
+#undef _LTTNG_TRACEPOINT_EVENT_CLASS_CODE
+#define _LTTNG_TRACEPOINT_EVENT_CLASS_CODE(_name, _data_proto, _locvar_args, _locvar, _code_pre, _fields, _code_post) \
+static void __event_probe__##_name(_data_proto) \
+{ \
+ struct probe_local_vars { _locvar }; \
+ struct lttng_kernel_event_common *__event = __data; \
+ struct lttng_kernel_probe_ctx __lttng_probe_ctx = { \
+ .event = __event, \
+ .interruptible = !irqs_disabled(), \
+ }; \
+ union { \
+ size_t __dynamic_len_removed[ARRAY_SIZE(__event_fields___##_name)]; \
+ char __interpreter_stack_data[2 * sizeof(unsigned long) * ARRAY_SIZE(__event_fields___##_name)]; \
+ } __stackvar; \
+ size_t __orig_dynamic_len_offset, __dynamic_len_idx __attribute__((unused)); \
+ struct probe_local_vars __tp_locvar; \
+ struct probe_local_vars *tp_locvar __attribute__((unused)) = \
+ &__tp_locvar; \
+ bool __interpreter_stack_prepared = false; \
+ \
+ switch (__event->type) { \
+ case LTTNG_KERNEL_EVENT_TYPE_RECORDER: \
+ { \
+ struct lttng_kernel_event_recorder *__event_recorder = \
+ container_of(__event, struct lttng_kernel_event_recorder, parent); \
+ struct lttng_kernel_channel_buffer *__chan = __event_recorder->chan; \
+ struct lttng_kernel_session *__session = __chan->parent.session; \
+ struct lttng_kernel_id_tracker_rcu *__lf; \
+ \
+ if (!_TP_SESSION_CHECK(session, __session)) \
+ return; \
+ if (unlikely(!LTTNG_READ_ONCE(__session->active))) \
+ return; \
+ if (unlikely(!LTTNG_READ_ONCE(__chan->parent.enabled))) \
+ return; \
+ __lf = lttng_rcu_dereference(__session->pid_tracker.p); \
+ if (__lf && likely(!lttng_id_tracker_lookup(__lf, current->tgid))) \
+ return; \
+ __lf = lttng_rcu_dereference(__session->vpid_tracker.p); \
+ if (__lf && likely(!lttng_id_tracker_lookup(__lf, task_tgid_vnr(current)))) \
+ return; \
+ __lf = lttng_rcu_dereference(__session->uid_tracker.p); \
+ if (__lf && likely(!lttng_id_tracker_lookup(__lf, \
+ from_kuid_munged(&init_user_ns, current_uid())))) \
+ return; \
+ __lf = lttng_rcu_dereference(__session->vuid_tracker.p); \
+ if (__lf && likely(!lttng_id_tracker_lookup(__lf, \
+ from_kuid_munged(current_user_ns(), current_uid())))) \
+ return; \
+ __lf = lttng_rcu_dereference(__session->gid_tracker.p); \
+ if (__lf && likely(!lttng_id_tracker_lookup(__lf, \
+ from_kgid_munged(&init_user_ns, current_gid())))) \
+ return; \
+ __lf = lttng_rcu_dereference(__session->vgid_tracker.p); \
+ if (__lf && likely(!lttng_id_tracker_lookup(__lf, \
+ from_kgid_munged(current_user_ns(), current_gid())))) \
+ return; \
+ break; \
+ } \
+ case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER: \
+ break; \
+ default: \
+ WARN_ON_ONCE(1); \
+ } \
+ if (unlikely(!READ_ONCE(__event->enabled))) \
+ return; \
+ __orig_dynamic_len_offset = this_cpu_ptr(<tng_dynamic_len_stack)->offset; \
+ __dynamic_len_idx = __orig_dynamic_len_offset; \
+ _code_pre \
+ if (unlikely(READ_ONCE(__event->eval_filter))) { \
+ __event_prepare_interpreter_stack__##_name(__stackvar.__interpreter_stack_data, \
+ _locvar_args); \
+ __interpreter_stack_prepared = true; \
+ if (likely(__event->run_filter(__event, \
+ __stackvar.__interpreter_stack_data, &__lttng_probe_ctx, NULL) != LTTNG_KERNEL_EVENT_FILTER_ACCEPT)) \
+ goto __post; \
+ } \
+ switch (__event->type) { \
+ case LTTNG_KERNEL_EVENT_TYPE_RECORDER: \
+ { \
+ struct lttng_kernel_event_recorder *__event_recorder = \
+ container_of(__event, struct lttng_kernel_event_recorder, parent); \
+ struct lttng_kernel_channel_buffer *__chan = __event_recorder->chan; \
+ struct lttng_kernel_ring_buffer_ctx __ctx; \
+ ssize_t __event_len; \
+ size_t __event_align; \
+ int __ret; \
+ \
+ __event_len = __event_get_size__##_name(_locvar_args); \
+ if (unlikely(__event_len < 0)) { \
+ __chan->ops->lost_event_too_big(__chan); \
+ goto __post; \
+ } \
+ __event_align = __event_get_align__##_name(_locvar_args); \
+ lib_ring_buffer_ctx_init(&__ctx, __event_recorder, __event_len, \
+ __event_align, &__lttng_probe_ctx); \
+ __ret = __chan->ops->event_reserve(&__ctx); \
+ if (__ret < 0) \
+ goto __post; \
+ _fields \
+ __chan->ops->event_commit(&__ctx); \
+ break; \
+ } \
+ case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER: \
+ { \
+ struct lttng_kernel_event_notifier *__event_notifier = \
+ container_of(__event, struct lttng_kernel_event_notifier, parent); \
+ struct lttng_kernel_notification_ctx __notif_ctx; \
+ \
+ __notif_ctx.eval_capture = LTTNG_READ_ONCE(__event_notifier->eval_capture); \
+ if (unlikely(!__interpreter_stack_prepared && __notif_ctx.eval_capture)) \
+ __event_prepare_interpreter_stack__##_name( \
+ __stackvar.__interpreter_stack_data, \
+ _locvar_args); \
+ \
+ __event_notifier->notification_send(__event_notifier, \
+ __stackvar.__interpreter_stack_data, \
+ &__lttng_probe_ctx, \
+ &__notif_ctx); \
+ break; \
+ } \
+ default: \
+ WARN_ON_ONCE(1); \
+ } \
+__post: \
+ _code_post \
+ barrier(); /* use before un-reserve. */ \
+ this_cpu_ptr(<tng_dynamic_len_stack)->offset = __orig_dynamic_len_offset; \
+ return; \
+}
+
#undef LTTNG_TRACEPOINT_EVENT_CLASS_CODE
#define LTTNG_TRACEPOINT_EVENT_CLASS_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
-static void __event_probe__##_name(void *__data, _proto) \
-{ \
- struct probe_local_vars { _locvar }; \
- struct lttng_event *__event = __data; \
- struct lttng_probe_ctx __lttng_probe_ctx = { \
- .event = __event, \
- .interruptible = !irqs_disabled(), \
- }; \
- struct lttng_channel *__chan = __event->chan; \
- struct lttng_session *__session = __chan->session; \
- struct lib_ring_buffer_ctx __ctx; \
- ssize_t __event_len; \
- size_t __event_align; \
- size_t __orig_dynamic_len_offset, __dynamic_len_idx __attribute__((unused)); \
- union { \
- size_t __dynamic_len_removed[ARRAY_SIZE(__event_fields___##_name)]; \
- char __filter_stack_data[2 * sizeof(unsigned long) * ARRAY_SIZE(__event_fields___##_name)]; \
- } __stackvar; \
- int __ret; \
- struct probe_local_vars __tp_locvar; \
- struct probe_local_vars *tp_locvar __attribute__((unused)) = \
- &__tp_locvar; \
- struct lttng_id_tracker_rcu *__lf; \
- \
- if (!_TP_SESSION_CHECK(session, __session)) \
- return; \
- if (unlikely(!READ_ONCE(__session->active))) \
- return; \
- if (unlikely(!READ_ONCE(__chan->enabled))) \
- return; \
- if (unlikely(!READ_ONCE(__event->enabled))) \
- return; \
- __lf = lttng_rcu_dereference(__session->pid_tracker.p); \
- if (__lf && likely(!lttng_id_tracker_lookup(__lf, current->tgid))) \
- return; \
- __lf = lttng_rcu_dereference(__session->vpid_tracker.p); \
- if (__lf && likely(!lttng_id_tracker_lookup(__lf, task_tgid_vnr(current)))) \
- return; \
- __lf = lttng_rcu_dereference(__session->uid_tracker.p); \
- if (__lf && likely(!lttng_id_tracker_lookup(__lf, \
- lttng_current_uid()))) \
- return; \
- __lf = lttng_rcu_dereference(__session->vuid_tracker.p); \
- if (__lf && likely(!lttng_id_tracker_lookup(__lf, \
- lttng_current_vuid()))) \
- return; \
- __lf = lttng_rcu_dereference(__session->gid_tracker.p); \
- if (__lf && likely(!lttng_id_tracker_lookup(__lf, \
- lttng_current_gid()))) \
- return; \
- __lf = lttng_rcu_dereference(__session->vgid_tracker.p); \
- if (__lf && likely(!lttng_id_tracker_lookup(__lf, \
- lttng_current_vgid()))) \
- return; \
- __orig_dynamic_len_offset = this_cpu_ptr(<tng_dynamic_len_stack)->offset; \
- __dynamic_len_idx = __orig_dynamic_len_offset; \
- _code_pre \
- if (unlikely(!list_empty(&__event->bytecode_runtime_head))) { \
- struct lttng_bytecode_runtime *bc_runtime; \
- int __filter_record = __event->has_enablers_without_bytecode; \
- \
- __event_prepare_filter_stack__##_name(__stackvar.__filter_stack_data, \
- tp_locvar, _args); \
- lttng_list_for_each_entry_rcu(bc_runtime, &__event->bytecode_runtime_head, node) { \
- if (unlikely(bc_runtime->filter(bc_runtime, &__lttng_probe_ctx, \
- __stackvar.__filter_stack_data) & LTTNG_FILTER_RECORD_FLAG)) { \
- __filter_record = 1; \
- break; \
- } \
- } \
- if (likely(!__filter_record)) \
- goto __post; \
- } \
- __event_len = __event_get_size__##_name(tp_locvar, _args); \
- if (unlikely(__event_len < 0)) { \
- lib_ring_buffer_lost_event_too_big(__chan->chan); \
- goto __post; \
- } \
- __event_align = __event_get_align__##_name(tp_locvar, _args); \
- lib_ring_buffer_ctx_init(&__ctx, __chan->chan, &__lttng_probe_ctx, __event_len, \
- __event_align, -1); \
- __ret = __chan->ops->event_reserve(&__ctx, __event->id); \
- if (__ret < 0) \
- goto __post; \
- _fields \
- __chan->ops->event_commit(&__ctx); \
-__post: \
- _code_post \
- barrier(); /* use before un-reserve. */ \
- this_cpu_ptr(<tng_dynamic_len_stack)->offset = __orig_dynamic_len_offset; \
- return; \
-}
+ _LTTNG_TRACEPOINT_EVENT_CLASS_CODE(_name, PARAMS(void *__data, _proto), PARAMS(tp_locvar, _args), \
+ PARAMS(_locvar), PARAMS(_code_pre), PARAMS(_fields), PARAMS(_code_post))
#undef LTTNG_TRACEPOINT_EVENT_CLASS_CODE_NOARGS
#define LTTNG_TRACEPOINT_EVENT_CLASS_CODE_NOARGS(_name, _locvar, _code_pre, _fields, _code_post) \
-static void __event_probe__##_name(void *__data) \
-{ \
- struct probe_local_vars { _locvar }; \
- struct lttng_event *__event = __data; \
- struct lttng_probe_ctx __lttng_probe_ctx = { \
- .event = __event, \
- .interruptible = !irqs_disabled(), \
- }; \
- struct lttng_channel *__chan = __event->chan; \
- struct lttng_session *__session = __chan->session; \
- struct lib_ring_buffer_ctx __ctx; \
- ssize_t __event_len; \
- size_t __event_align; \
- size_t __orig_dynamic_len_offset, __dynamic_len_idx __attribute__((unused)); \
- union { \
- size_t __dynamic_len_removed[ARRAY_SIZE(__event_fields___##_name)]; \
- char __filter_stack_data[2 * sizeof(unsigned long) * ARRAY_SIZE(__event_fields___##_name)]; \
- } __stackvar; \
- int __ret; \
- struct probe_local_vars __tp_locvar; \
- struct probe_local_vars *tp_locvar __attribute__((unused)) = \
- &__tp_locvar; \
- struct lttng_id_tracker_rcu *__lf; \
- \
- if (!_TP_SESSION_CHECK(session, __session)) \
- return; \
- if (unlikely(!READ_ONCE(__session->active))) \
- return; \
- if (unlikely(!READ_ONCE(__chan->enabled))) \
- return; \
- if (unlikely(!READ_ONCE(__event->enabled))) \
- return; \
- __lf = lttng_rcu_dereference(__session->pid_tracker.p); \
- if (__lf && likely(!lttng_id_tracker_lookup(__lf, current->tgid))) \
- return; \
- __lf = lttng_rcu_dereference(__session->vpid_tracker.p); \
- if (__lf && likely(!lttng_id_tracker_lookup(__lf, task_tgid_vnr(current)))) \
- return; \
- __lf = lttng_rcu_dereference(__session->uid_tracker.p); \
- if (__lf && likely(!lttng_id_tracker_lookup(__lf, \
- lttng_current_uid()))) \
- return; \
- __lf = lttng_rcu_dereference(__session->vuid_tracker.p); \
- if (__lf && likely(!lttng_id_tracker_lookup(__lf, \
- lttng_current_vuid()))) \
- return; \
- __lf = lttng_rcu_dereference(__session->gid_tracker.p); \
- if (__lf && likely(!lttng_id_tracker_lookup(__lf, \
- lttng_current_gid()))) \
- return; \
- __lf = lttng_rcu_dereference(__session->vgid_tracker.p); \
- if (__lf && likely(!lttng_id_tracker_lookup(__lf, \
- lttng_current_vgid()))) \
- return; \
- __orig_dynamic_len_offset = this_cpu_ptr(<tng_dynamic_len_stack)->offset; \
- __dynamic_len_idx = __orig_dynamic_len_offset; \
- _code_pre \
- if (unlikely(!list_empty(&__event->bytecode_runtime_head))) { \
- struct lttng_bytecode_runtime *bc_runtime; \
- int __filter_record = __event->has_enablers_without_bytecode; \
- \
- __event_prepare_filter_stack__##_name(__stackvar.__filter_stack_data, \
- tp_locvar); \
- lttng_list_for_each_entry_rcu(bc_runtime, &__event->bytecode_runtime_head, node) { \
- if (unlikely(bc_runtime->filter(bc_runtime, &__lttng_probe_ctx, \
- __stackvar.__filter_stack_data) & LTTNG_FILTER_RECORD_FLAG)) { \
- __filter_record = 1; \
- break; \
- } \
- } \
- if (likely(!__filter_record)) \
- goto __post; \
- } \
- __event_len = __event_get_size__##_name(tp_locvar); \
- if (unlikely(__event_len < 0)) { \
- lib_ring_buffer_lost_event_too_big(__chan->chan); \
- goto __post; \
- } \
- __event_align = __event_get_align__##_name(tp_locvar); \
- lib_ring_buffer_ctx_init(&__ctx, __chan->chan, &__lttng_probe_ctx, __event_len, \
- __event_align, -1); \
- __ret = __chan->ops->event_reserve(&__ctx, __event->id); \
- if (__ret < 0) \
- goto __post; \
- _fields \
- __chan->ops->event_commit(&__ctx); \
-__post: \
- _code_post \
- barrier(); /* use before un-reserve. */ \
- this_cpu_ptr(<tng_dynamic_len_stack)->offset = __orig_dynamic_len_offset; \
- return; \
-}
+ _LTTNG_TRACEPOINT_EVENT_CLASS_CODE(_name, PARAMS(void *__data), PARAMS(tp_locvar), PARAMS(_locvar), \
+ PARAMS(_code_pre), PARAMS(_fields), PARAMS(_code_post))
#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
#undef __get_dynamic_len
/*
- * Stage 7 of the trace events.
+ * Stage 7.1 of the trace events.
*
* Create event descriptions.
*/
#include <lttng/events-reset.h> /* Reset all macros within LTTNG_TRACEPOINT_EVENT */
-#ifndef TP_PROBE_CB
-#define TP_PROBE_CB(_template) &__event_probe__##_template
-#endif
-
#undef LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP_NOARGS
#define LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP_NOARGS(_template, _name, _map) \
-static const struct lttng_event_desc __event_desc___##_map = { \
- .fields = __event_fields___##_template, \
- .name = #_map, \
- .kname = #_name, \
- .probe_callback = (void *) TP_PROBE_CB(_template), \
- .nr_fields = ARRAY_SIZE(__event_fields___##_template), \
+static const struct lttng_kernel_event_desc __event_desc___##_map = { \
+ .event_name = #_map, \
+ .event_kname = #_name, \
+ .tp_class = <tng_kernel__event_class___##_template, \
+ .probe_desc = &TP_ID(__probe_desc___, TRACE_SYSTEM), \
.owner = THIS_MODULE, \
};
#define LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(_template, _name, _map, _proto, _args) \
LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP_NOARGS(_template, _name, _map)
+#define TP_ID1(_token, _system) _token##_system
+#define TP_ID(_token, _system) TP_ID1(_token, _system)
+
#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+#undef TP_ID1
+#undef TP_ID
+
/*
* Stage 8 of the trace events.
*
#define TP_ID1(_token, _system) _token##_system
#define TP_ID(_token, _system) TP_ID1(_token, _system)
-static const struct lttng_event_desc *TP_ID(__event_desc___, TRACE_SYSTEM)[] = {
+static const struct lttng_kernel_event_desc * const TP_ID(__provider_event_desc___, TRACE_SYSTEM)[] = {
#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
};
#define TP_ID(_token, _system) TP_ID1(_token, _system)
/* non-const because list head will be modified when registered. */
-static __used struct lttng_probe_desc TP_ID(__probe_desc___, TRACE_SYSTEM) = {
- .provider = __stringify(TRACE_SYSTEM),
- .event_desc = TP_ID(__event_desc___, TRACE_SYSTEM),
- .nr_events = ARRAY_SIZE(TP_ID(__event_desc___, TRACE_SYSTEM)),
+static __used struct lttng_kernel_probe_desc TP_ID(__probe_desc___, TRACE_SYSTEM) = {
+ .provider_name = __stringify(TRACE_SYSTEM),
+ .event_desc = TP_ID(__provider_event_desc___, TRACE_SYSTEM),
+ .nr_events = ARRAY_SIZE(TP_ID(__provider_event_desc___, TRACE_SYSTEM)),
.head = { NULL, NULL },
.lazy_init_head = { NULL, NULL },
.lazy = 0,
static int TP_ID(__lttng_events_init__, TRACE_SYSTEM)(void)
{
wrapper_vmalloc_sync_mappings();
- return lttng_probe_register(&TP_ID(__probe_desc___, TRACE_SYSTEM));
+ return lttng_kernel_probe_register(&TP_ID(__probe_desc___, TRACE_SYSTEM));
}
static void TP_ID(__lttng_events_exit__, TRACE_SYSTEM)(void)
{
- lttng_probe_unregister(&TP_ID(__probe_desc___, TRACE_SYSTEM));
+ lttng_kernel_probe_unregister(&TP_ID(__probe_desc___, TRACE_SYSTEM));
}
#ifndef TP_MODULE_NOAUTOLOAD