)
#endif
-#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(4,14,0) || \
+#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(6,10,0))
+LTTNG_TRACEPOINT_EVENT_CLASS(btrfs_delayed_tree_ref,
+
+ TP_PROTO(const struct btrfs_fs_info *fs_info,
+ const struct btrfs_delayed_ref_node *ref),
+
+ TP_ARGS(fs_info, ref),
+
+ TP_FIELDS(
+ ctf_array(u8, fsid, lttng_fs_info_fsid, BTRFS_UUID_SIZE)
+ ctf_integer(u64, bytenr, ref->bytenr)
+ ctf_integer(u64, num_bytes, ref->num_bytes)
+ ctf_integer(int, action, ref->action)
+ ctf_integer(u64, parent, ref->parent)
+ ctf_integer(u64, ref_root, ref->ref_root)
+ ctf_integer(int, level, ref->tree_ref.level)
+ ctf_integer(int, type, ref->type)
+ ctf_integer(u64, seq, ref->seq)
+ )
+)
+
+LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(btrfs_delayed_tree_ref,
+
+ add_delayed_tree_ref,
+
+ btrfs_add_delayed_tree_ref,
+
+ TP_PROTO(const struct btrfs_fs_info *fs_info,
+ const struct btrfs_delayed_ref_node *ref),
+
+ TP_ARGS(fs_info, ref)
+)
+
+LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(btrfs_delayed_tree_ref,
+
+ run_delayed_tree_ref,
+
+ btrfs_run_delayed_tree_ref,
+
+ TP_PROTO(const struct btrfs_fs_info *fs_info,
+ const struct btrfs_delayed_ref_node *ref),
+
+ TP_ARGS(fs_info, ref)
+)
+#elif (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(4,14,0) || \
LTTNG_SLE_KERNEL_RANGE(4,4,73,5,0,0, 4,4,73,6,0,0) || \
LTTNG_SLE_KERNEL_RANGE(4,4,82,6,0,0, 4,4,82,7,0,0) || \
LTTNG_SLE_KERNEL_RANGE(4,4,92,6,0,0, 4,4,92,7,0,0) || \
)
#endif
-#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(4,14,0) || \
+#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(6,10,0))
+LTTNG_TRACEPOINT_EVENT_CLASS(btrfs_delayed_data_ref,
+
+ TP_PROTO(const struct btrfs_fs_info *fs_info,
+ const struct btrfs_delayed_ref_node *ref),
+
+ TP_ARGS(fs_info, ref),
+
+ TP_FIELDS(
+ ctf_array(u8, fsid, lttng_fs_info_fsid, BTRFS_UUID_SIZE)
+ ctf_integer(u64, bytenr, ref->bytenr)
+ ctf_integer(u64, num_bytes, ref->num_bytes)
+ ctf_integer(int, action, ref->action)
+ ctf_integer(u64, parent, ref->parent)
+ ctf_integer(u64, ref_root, ref->ref_root)
+ ctf_integer(u64, owner, ref->data_ref.objectid)
+ ctf_integer(u64, offset, ref->data_ref.offset)
+ ctf_integer(int, type, ref->type)
+ ctf_integer(u64, seq, ref->seq)
+ )
+)
+
+LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(btrfs_delayed_data_ref,
+
+ add_delayed_data_ref,
+
+ btrfs_add_delayed_data_ref,
+
+ TP_PROTO(const struct btrfs_fs_info *fs_info,
+ const struct btrfs_delayed_ref_node *ref),
+
+ TP_ARGS(fs_info, ref)
+)
+
+LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(btrfs_delayed_data_ref,
+
+ run_delayed_data_ref,
+
+ btrfs_run_delayed_data_ref,
+
+ TP_PROTO(const struct btrfs_fs_info *fs_info,
+ const struct btrfs_delayed_ref_node *ref),
+
+ TP_ARGS(fs_info, ref)
+)
+
+#elif (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(4,14,0) || \
LTTNG_SLE_KERNEL_RANGE(4,4,73,5,0,0, 4,4,73,6,0,0) || \
LTTNG_SLE_KERNEL_RANGE(4,4,82,6,0,0, 4,4,82,7,0,0) || \
LTTNG_SLE_KERNEL_RANGE(4,4,92,6,0,0, 4,4,92,7,0,0) || \
)
)
-#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(6,7,0))
+#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(6,7,0) || \
+ LTTNG_RHEL_KERNEL_RANGE(5,14,0,427,16,1, 5,15,0,0,0,0))
LTTNG_TRACEPOINT_EVENT(mm_vmscan_lru_isolate,
TP_PROTO(int classzone_idx,
#endif
#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,2,0) || \
+ LTTNG_KERNEL_RANGE(4,19,312, 4,20,0) || \
LTTNG_RHEL_KERNEL_RANGE(4,18,0,193,0,0, 4,19,0,0,0,0))
/**
* timer_expire_entry - called immediately before the timer callback
#include <lttng/tracepoint-event.h>
#include <linux/udp.h>
+#include <lttng/kernel-version.h>
+#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(6,10,0))
+LTTNG_TRACEPOINT_ENUM(lttng_sk_family,
+ TP_ENUM_VALUES(
+ ctf_enum_value("AF_INET", AF_INET)
+ ctf_enum_value("AF_INET6", AF_INET6)
+ )
+)
+
+LTTNG_TRACEPOINT_EVENT(udp_fail_queue_rcv_skb,
+
+ TP_PROTO(int rc, struct sock *sk, struct sk_buff *skb),
+
+ TP_ARGS(rc, sk, skb),
+
+ TP_FIELDS(
+ ctf_integer(int, rc, rc)
+ ctf_integer(__u16, sport, ntohs(udp_hdr(skb)->source))
+ ctf_integer(__u16, dport, ntohs(udp_hdr(skb)->dest))
+ ctf_enum(lttng_sk_family, __u16, family, sk->sk_family)
+ /*
+ * The 'saddr' and 'daddr' fields from the upstream tracepoint
+ * are currently not extracted. It is recommended to use a
+ * tracepoint from the 'net' probe instead which includes all
+ * fields from the IP header.
+ */
+ )
+)
+#else
LTTNG_TRACEPOINT_EVENT(udp_fail_queue_rcv_skb,
TP_PROTO(int rc, struct sock *sk),
ctf_integer(__u16, lport, inet_sk(sk)->inet_num)
)
)
+#endif
#endif /* LTTNG_TRACE_UDP_H */
#endif /* CONFIG_COMPAT_OLD_SIGACTION */
#endif
+/*
+ * Override 'pipe' to set the output field 'fildes' to an array of 2 integers
+ * instead of the default integer pointer.
+ */
#define OVERRIDE_32_pipe
SC_LTTNG_TRACEPOINT_EVENT(pipe,
TP_PROTO(sc_exit(long ret,) int * fildes),
#ifndef CREATE_SYSCALL_TABLE
+/*
+ * Override 'pipe' to set the output field 'fildes' to an array of 2 integers
+ * instead of the default integer pointer.
+ */
#define OVERRIDE_32_pipe
SC_LTTNG_TRACEPOINT_EVENT(pipe,
TP_PROTO(sc_exit(long ret,) int * fildes),
)
)
+/*
+ * Override 'pipe2' to set the output field 'fildes' to an array of 2 integers
+ * instead of the default integer pointer.
+ */
#define OVERRIDE_32_pipe2
#define OVERRIDE_64_pipe2
SC_LTTNG_TRACEPOINT_EVENT(pipe2,
lttng_tp_mempool_free(tp_locvar->fds_ex);
#if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM)
+/*
+ * Instead of extracting the user-space pointers of the 3 fd_set,
+ * extract the bitmask of the FDs in the sets (in, out, ex) in the form
+ * of an array of uint8_t (1024 FDs is the limit in the kernel).
+ */
#define OVERRIDE_32_select
#define OVERRIDE_64_select
SC_LTTNG_TRACEPOINT_EVENT_CODE(select,
#endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM) */
#if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM)
+/*
+ * Instead of extracting the user-space pointers of the 3 fd_set,
+ * extract the bitmask of the FDs in the sets (in, out, ex) in the form
+ * of an array of uint8_t (1024 FDs is the limit in the kernel).
+ */
#define OVERRIDE_32_pselect6
#define OVERRIDE_64_pselect6
SC_LTTNG_TRACEPOINT_EVENT_CODE(pselect6,
)
#endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM) */
+#if defined(CONFIG_X86_32) || defined(CONFIG_ARM)
+/*
+ * Instead of extracting the user-space pointers of the 3 fd_set,
+ * extract the bitmask of the FDs in the sets (in, out, ex) in the form
+ * of an array of uint8_t (1024 FDs is the limit in the kernel).
+ */
+#define OVERRIDE_32_pselect6_time32
+SC_LTTNG_TRACEPOINT_EVENT_CODE(pselect6_time32,
+ TP_PROTO(sc_exit(long ret,) int n, fd_set __user * inp, fd_set __user * outp,
+ fd_set __user * exp, struct old_timespec32 __user * tvp, void __user * sig),
+ TP_ARGS(sc_exit(ret,) n, inp, outp, exp, tvp, sig),
+ TP_locvar(
+ LTTNG_SYSCALL_SELECT_locvar
+ ),
+ TP_code_pre(
+ LTTNG_SYSCALL_SELECT_code_pre
+ ),
+ TP_FIELDS(
+ sc_exit(ctf_integer(long, ret, ret))
+ sc_in(ctf_integer(int, n, n))
+ sc_inout(ctf_integer(uint8_t, overflow, tp_locvar->overflow))
+ sc_inout(ctf_integer(struct old_timespec32 *, tvp, tvp))
+ sc_in(ctf_integer_hex(void *, sig, sig))
+
+ sc_inout(
+#if (__BYTE_ORDER == __LITTLE_ENDIAN)
+ LTTNG_SYSCALL_SELECT_fds_field_LE(readfds, inp)
+ LTTNG_SYSCALL_SELECT_fds_field_LE(writefds, outp)
+ LTTNG_SYSCALL_SELECT_fds_field_LE(exceptfds, exp)
+#else
+ LTTNG_SYSCALL_SELECT_fds_field_BE(readfds, inp)
+ LTTNG_SYSCALL_SELECT_fds_field_BE(writefds, outp)
+ LTTNG_SYSCALL_SELECT_fds_field_BE(exceptfds, exp)
+#endif
+ )
+ ),
+ TP_code_post(
+ LTTNG_SYSCALL_SELECT_code_post
+ )
+)
+#endif /* defined(CONFIG_X86_32) || defined(CONFIG_ARM) */
+
#ifdef LTTNG_CREATE_FIELD_METADATA
#ifndef ONCE_LTTNG_TRACE_POLL_H
#define ONCE_LTTNG_TRACE_POLL_H
lttng_tp_mempool_free(tp_locvar->fds);
#if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM)
+/*
+ * Instead of printing the pointer address of the poll set, extract all the FDs
+ * and flags from the poll set. For now, only output the standardized
+ * set of events to limit the verbosity of the output, and also extract
+ * the raw value. In the future, moving to CTF2 will allow hiding unset
+ * fields and then allow extracting all the fields.
+ */
#define OVERRIDE_32_poll
#define OVERRIDE_64_poll
SC_LTTNG_TRACEPOINT_EVENT_CODE(poll,
#endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM) */
#if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM)
+/*
+ * Instead of printing the pointer address of the poll set, extract all the FDs
+ * and flags from the poll set. For now, only output the standardized
+ * set of events to limit the verbosity of the output, and also extract
+ * the raw value. In the future, moving to CTF2 will allow hiding unset
+ * fields and then allow extracting all the fields.
+ */
#define OVERRIDE_32_ppoll
#define OVERRIDE_64_ppoll
SC_LTTNG_TRACEPOINT_EVENT_CODE(ppoll,
)
#endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM) */
+#if defined(CONFIG_X86_32) || defined(CONFIG_ARM)
+/*
+ * Instead of printing the pointer address of the poll set, extract all the FDs
+ * and flags from the poll set. For now, only output the standardized
+ * set of events to limit the verbosity of the output, and also extract
+ * the raw value. In the future, moving to CTF2 will allow hiding unset
+ * fields and then allow extracting all the fields.
+ */
+#define OVERRIDE_32_ppoll_time32
+SC_LTTNG_TRACEPOINT_EVENT_CODE(ppoll_time32,
+ TP_PROTO(sc_exit(long ret,) struct pollfd __user * ufds,
+ unsigned int nfds, struct old_timespec32 * tsp, const sigset_t * sigmask, size_t sigsetsize),
+ TP_ARGS(sc_exit(ret,) ufds, nfds, tsp, sigmask, sigsetsize),
+ TP_locvar(
+ LTTNG_SYSCALL_POLL_locvar
+ ),
+ TP_code_pre(
+ LTTNG_SYSCALL_POLL_code_pre
+ ),
+ TP_FIELDS(
+ sc_exit(ctf_integer(long, ret, ret))
+ sc_in(ctf_integer(struct old_timespec32 *, tsp, tsp))
+ sc_in(ctf_integer(const sigset_t *, sigmask, sigmask))
+ sc_in(ctf_integer(size_t, sigsetsize, sigsetsize))
+ sc_inout(ctf_integer(unsigned int, nfds, nfds))
+ sc_inout(ctf_integer(unsigned int, fds_length, tp_locvar->fds_length))
+ sc_inout(ctf_integer(uint8_t, overflow, tp_locvar->overflow))
+ LTTNG_SYSCALL_POLL_fds_field
+ ),
+ TP_code_post(
+ LTTNG_SYSCALL_POLL_code_post
+ )
+)
+#endif /* defined(CONFIG_X86_32) || defined(CONFIG_ARM) */
+
#include <linux/eventpoll.h>
SC_LTTNG_TRACEPOINT_ENUM(lttng_epoll_op,
#endif /* CONFIG_COMPAT_OLD_SIGACTION */
#endif
+/*
+ * Override 'pipe' to set the output field 'fildes' to an array of 2 integers
+ * instead of the default integer pointer.
+ */
#define OVERRIDE_32_pipe
#define OVERRIDE_64_pipe
SC_LTTNG_TRACEPOINT_EVENT(pipe,
TP_code_post()
)
+/*
+ * Override 'pipe' to set the output field 'fildes' to an array of 2 integers
+ * instead of the default integer pointer.
+ */
#define OVERRIDE_64_pipe
SC_LTTNG_TRACEPOINT_EVENT(pipe,
TP_PROTO(sc_exit(long ret,) int * fildes),
struct lttng_kernel_ring_buffer *buf; /* Channel per-cpu buffers */
unsigned long num_subbuf; /* Number of sub-buffers for writer */
- u64 start_tsc; /* Channel creation TSC value */
+ u64 start_timestamp; /* Channel creation timestamp value */
void *priv; /* Client-specific information */
void *priv_ops; /* Client-specific ops pointer */
void (*release_priv_ops)(void *priv_ops);
/* Slow path only, at subbuffer switch */
size_t (*subbuffer_header_size) (void);
- void (*buffer_begin) (struct lttng_kernel_ring_buffer *buf, u64 tsc,
+ void (*buffer_begin) (struct lttng_kernel_ring_buffer *buf, u64 timestamp,
unsigned int subbuf_idx);
- void (*buffer_end) (struct lttng_kernel_ring_buffer *buf, u64 tsc,
+ void (*buffer_end) (struct lttng_kernel_ring_buffer *buf, u64 timestamp,
unsigned int subbuf_idx, unsigned long data_size,
const struct lttng_kernel_ring_buffer_ctx *ctx);
*/
} wakeup;
/*
- * tsc_bits: timestamp bits saved at each record.
+ * timestamp_bits: timestamp bits saved at each record.
* 0 and 64 disable the timestamp compression scheme.
*/
- unsigned int tsc_bits;
+ unsigned int timestamp_bits;
struct lttng_kernel_ring_buffer_client_cb cb;
};
* prior to record header alignment
* padding.
*/
- u64 tsc; /* time-stamp counter value */
+ u64 timestamp; /* time-stamp counter value */
unsigned int rflags; /* reservation flags */
struct lttng_kernel_ring_buffer *buf; /*
/*
* Reservation flags.
*
- * RING_BUFFER_RFLAG_FULL_TSC
+ * RING_BUFFER_RFLAG_FULL_TIMESTAMP
*
* This flag is passed to record_header_size() and to the primitive used to
* write the record header. It indicates that the full 64-bit time value is
* needed in the record header. If this flag is not set, the record header needs
- * only to contain "tsc_bits" bit of time value.
+ * only to contain "timestamp_bits" bit of time value.
*
* Reservation flags can be added by the client, starting from
* "(RING_BUFFER_FLAGS_END << 0)". It can be used to pass information from
* record_header_size() to lib_ring_buffer_write_record_header().
*/
-#define RING_BUFFER_RFLAG_FULL_TSC (1U << 0)
+#define RING_BUFFER_RFLAG_FULL_TIMESTAMP (1U << 0)
#define RING_BUFFER_RFLAG_END (1U << 1)
#ifndef LTTNG_TRACER_CORE_H
*o_begin = v_read(config, &buf->offset);
*o_old = *o_begin;
- ctx->priv.tsc = lib_ring_buffer_clock_read(chan);
- if ((int64_t) ctx->priv.tsc == -EIO)
+ ctx->priv.timestamp = lib_ring_buffer_clock_read(chan);
+ if ((int64_t) ctx->priv.timestamp == -EIO)
return 1;
/*
*/
prefetch(&buf->commit_hot[subbuf_index(*o_begin, chan)]);
- if (last_tsc_overflow(config, buf, ctx->priv.tsc))
- ctx->priv.rflags |= RING_BUFFER_RFLAG_FULL_TSC;
+ if (last_timestamp_overflow(config, buf, ctx->priv.timestamp))
+ ctx->priv.rflags |= RING_BUFFER_RFLAG_FULL_TIMESTAMP;
if (unlikely(subbuf_offset(*o_begin, chan) == 0))
return 1;
* @ctx: ring buffer context. (input and output) Must be already initialized.
*
* Atomic wait-free slot reservation. The reserved space starts at the context
- * "pre_offset". Its length is "slot_size". The associated time-stamp is "tsc".
+ * "pre_offset". Its length is "slot_size". The associated time-stamp is
+ * "timestamp".
*
* Return :
* 0 on success.
goto slow_path;
/*
- * Atomically update last_tsc. This update races against concurrent
- * atomic updates, but the race will always cause supplementary full TSC
- * record headers, never the opposite (missing a full TSC record header
- * when it would be needed).
+ * Atomically update last_timestamp. This update races against concurrent
+ * atomic updates, but the race will always cause supplementary
+ * full timestamp record headers, never the opposite (missing a
+ * full timestamp record header when it would be needed).
*/
- save_last_tsc(config, ctx->priv.buf, ctx->priv.tsc);
+ save_last_timestamp(config, ctx->priv.buf, ctx->priv.timestamp);
/*
* Push the reader if necessary
/*
* We need to ensure that if the cmpxchg succeeds and discards the
- * record, the next record will record a full TSC, because it cannot
- * rely on the last_tsc associated with the discarded record to detect
- * overflows. The only way to ensure this is to set the last_tsc to 0
- * (assuming no 64-bit TSC overflow), which forces to write a 64-bit
- * timestamp in the next record.
+ * record, the next record will record a full timestamp, because
+ * it cannot rely on the last_timestamp associated with the
+ * discarded record to detect overflows. The only way to ensure
+ * this is to set the last_timestamp to 0 (assuming no 64-bit
+ * timestamp overflow), which forces to write a 64-bit timestamp in
+ * the next record.
*
- * Note: if discard fails, we must leave the TSC in the record header.
- * It is needed to keep track of TSC overflows for the following
- * records.
+ * Note: if discard fails, we must leave the timestamp in the
+ * record header. It is needed to keep track of timestamp
+ * overflows for the following records.
*/
- save_last_tsc(config, buf, 0ULL);
+ save_last_timestamp(config, buf, 0ULL);
if (likely(v_cmpxchg(config, &buf->offset, end_offset, ctx->priv.pre_offset)
!= end_offset))
}
/*
- * Last TSC comparison functions. Check if the current TSC overflows tsc_bits
- * bits from the last TSC read. When overflows are detected, the full 64-bit
- * timestamp counter should be written in the record header. Reads and writes
- * last_tsc atomically.
+ * Last timestamp comparison functions. Check if the current timestamp
+ * overflows timestamp_bits bits from the last timestamp read. When
+ * overflows are detected, the full 64-bit timestamp counter should be
+ * written in the record header. Reads and writes last_timestamp
+ * atomically.
*/
#if (BITS_PER_LONG == 32)
static inline
-void save_last_tsc(const struct lttng_kernel_ring_buffer_config *config,
- struct lttng_kernel_ring_buffer *buf, u64 tsc)
+void save_last_timestamp(const struct lttng_kernel_ring_buffer_config *config,
+ struct lttng_kernel_ring_buffer *buf, u64 timestamp)
{
- if (config->tsc_bits == 0 || config->tsc_bits == 64)
+ if (config->timestamp_bits == 0 || config->timestamp_bits == 64)
return;
/*
* Ensure the compiler performs this update in a single instruction.
*/
- v_set(config, &buf->last_tsc, (unsigned long)(tsc >> config->tsc_bits));
+ v_set(config, &buf->last_timestamp, (unsigned long)(timestamp >> config->timestamp_bits));
}
static inline
-int last_tsc_overflow(const struct lttng_kernel_ring_buffer_config *config,
- struct lttng_kernel_ring_buffer *buf, u64 tsc)
+int last_timestamp_overflow(const struct lttng_kernel_ring_buffer_config *config,
+ struct lttng_kernel_ring_buffer *buf, u64 timestamp)
{
- unsigned long tsc_shifted;
+ unsigned long timestamp_shifted;
- if (config->tsc_bits == 0 || config->tsc_bits == 64)
+ if (config->timestamp_bits == 0 || config->timestamp_bits == 64)
return 0;
- tsc_shifted = (unsigned long)(tsc >> config->tsc_bits);
- if (unlikely(tsc_shifted
- - (unsigned long)v_read(config, &buf->last_tsc)))
+ timestamp_shifted = (unsigned long)(timestamp >> config->timestamp_bits);
+ if (unlikely(timestamp_shifted
+ - (unsigned long)v_read(config, &buf->last_timestamp)))
return 1;
else
return 0;
}
#else
static inline
-void save_last_tsc(const struct lttng_kernel_ring_buffer_config *config,
- struct lttng_kernel_ring_buffer *buf, u64 tsc)
+void save_last_timestamp(const struct lttng_kernel_ring_buffer_config *config,
+ struct lttng_kernel_ring_buffer *buf, u64 timestamp)
{
- if (config->tsc_bits == 0 || config->tsc_bits == 64)
+ if (config->timestamp_bits == 0 || config->timestamp_bits == 64)
return;
- v_set(config, &buf->last_tsc, (unsigned long)tsc);
+ v_set(config, &buf->last_timestamp, (unsigned long)timestamp);
}
static inline
-int last_tsc_overflow(const struct lttng_kernel_ring_buffer_config *config,
- struct lttng_kernel_ring_buffer *buf, u64 tsc)
+int last_timestamp_overflow(const struct lttng_kernel_ring_buffer_config *config,
+ struct lttng_kernel_ring_buffer *buf, u64 timestamp)
{
- if (config->tsc_bits == 0 || config->tsc_bits == 64)
+ if (config->timestamp_bits == 0 || config->timestamp_bits == 64)
return 0;
- if (unlikely((tsc - v_read(config, &buf->last_tsc))
- >> config->tsc_bits))
+ if (unlikely((timestamp - v_read(config, &buf->last_timestamp))
+ >> config->timestamp_bits))
return 1;
else
return 0;
}
/*
- * Receive end of subbuffer TSC as parameter. It has been read in the
+ * Receive end of subbuffer timestamp as parameter. It has been read in the
* space reservation loop of either reserve or switch, which ensures it
* progresses monotonically with event records in the buffer. Therefore,
* it ensures that the end timestamp of a subbuffer is <= begin
*/
atomic_t record_disabled;
/* End of first 32 bytes cacheline */
- union v_atomic last_tsc; /*
+ union v_atomic last_timestamp; /*
* Last timestamp written in the buffer.
*/
* extern struct class block_class;
*/
static inline
-struct class *__canary__get_block_class(void)
+const struct class *__canary__get_block_class(void)
{
return &block_class;
}
}
#endif
+#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(6,10,0))
+static inline
+bool lttng_close_on_exec(unsigned int fd, const struct files_struct *files)
+{
+ return close_on_exec(fd, files);
+}
+#else
+static inline
+bool lttng_close_on_exec(unsigned int fd, const struct files_struct *files)
+{
+ return close_on_exec(fd, files_fdtable(files));
+}
+#endif
+
#endif /* _LTTNG_WRAPPER_FDTABLE_H */
#ifdef LTTNG_USE_NMI_SAFE_CLOCK
-DECLARE_PER_CPU(u64, lttng_last_tsc);
+DECLARE_PER_CPU(u64, lttng_last_timestamp);
/*
* Sometimes called with preemption enabled. Can be interrupted.
static inline u64 trace_clock_monotonic_wrapper(void)
{
u64 now, last, result;
- u64 *last_tsc_ptr;
+ u64 *last_timestamp_ptr;
/* Use fast nmi-safe monotonic clock provided by the Linux kernel. */
preempt_disable();
- last_tsc_ptr = this_cpu_ptr(<tng_last_tsc);
- last = *last_tsc_ptr;
+ last_timestamp_ptr = this_cpu_ptr(<tng_last_timestamp);
+ last = *last_timestamp_ptr;
/*
* Read "last" before "now". It is not strictly required, but it ensures
* that an interrupt coming in won't artificially trigger a case where
now = ktime_get_mono_fast_ns();
if (U64_MAX / 2 < now - last)
now = last;
- result = cmpxchg64_local(last_tsc_ptr, last, now);
+ result = cmpxchg64_local(last_timestamp_ptr, last, now);
preempt_enable();
if (result == last) {
/* Update done. */
* num_subbuf_order, buf_size_order, extra_reader_sb, num_subbuf,
* priv, notifiers, config, cpumask and name.
*/
- chanb->start_tsc = config->cb.ring_buffer_clock_read(chan);
+ chanb->start_timestamp = config->cb.ring_buffer_clock_read(chan);
}
#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(4,10,0))
if (ret)
goto free_bufs;
}
- chanb->start_tsc = config->cb.ring_buffer_clock_read(chan);
+ chanb->start_timestamp = config->cb.ring_buffer_clock_read(chan);
return 0;
}
atomic_long_set(&buf->consumed, 0);
atomic_set(&buf->record_disabled, 0);
- v_set(config, &buf->last_tsc, 0);
+ v_set(config, &buf->last_timestamp, 0);
lib_ring_buffer_backend_reset(&buf->backend);
/* Don't reset number of active readers */
v_set(config, &buf->records_lost_full, 0);
struct lttng_kernel_ring_buffer_channel *chan = container_of(chanb, struct lttng_kernel_ring_buffer_channel, backend);
void *priv = chanb->priv;
size_t subbuf_header_size;
- u64 tsc;
+ u64 timestamp;
int ret;
/* Test for cpu hotplug */
subbuf_header_size = config->cb.subbuffer_header_size();
v_set(config, &buf->offset, subbuf_header_size);
subbuffer_id_clear_noref(config, &buf->backend.buf_wsb[0].id);
- tsc = config->cb.ring_buffer_clock_read(buf->backend.chan);
- config->cb.buffer_begin(buf, tsc, 0);
+ timestamp = config->cb.ring_buffer_clock_read(buf->backend.chan);
+ config->cb.buffer_begin(buf, timestamp, 0);
v_add(config, subbuf_header_size, &buf->commit_hot[0].cc);
if (config->cb.buffer_create) {
unsigned long commit_count;
struct commit_counters_hot *cc_hot;
- config->cb.buffer_begin(buf, ctx->priv.tsc, oldidx);
+ config->cb.buffer_begin(buf, ctx->priv.timestamp, oldidx);
/*
* Order all writes to buffer before the commit count update that will
* postponed until the commit counter is incremented for the
* current space reservation.
*/
- *ts_end = ctx->priv.tsc;
+ *ts_end = ctx->priv.timestamp;
/*
* Order all writes to buffer and store to ts_end before the commit
unsigned long commit_count;
struct commit_counters_hot *cc_hot;
- config->cb.buffer_begin(buf, ctx->priv.tsc, beginidx);
+ config->cb.buffer_begin(buf, ctx->priv.timestamp, beginidx);
/*
* Order all writes to buffer before the commit count update that will
* postponed until the commit counter is incremented for the
* current space reservation.
*/
- *ts_end = ctx->priv.tsc;
+ *ts_end = ctx->priv.timestamp;
}
/*
offsets->switch_old_start = 0;
off = subbuf_offset(offsets->begin, chan);
- ctx->priv.tsc = config->cb.ring_buffer_clock_read(chan);
+ ctx->priv.timestamp = config->cb.ring_buffer_clock_read(chan);
/*
* Ensure we flush the header of an empty subbuffer when doing the
!= offsets.old);
/*
- * Atomically update last_tsc. This update races against concurrent
- * atomic updates, but the race will always cause supplementary full TSC
- * records, never the opposite (missing a full TSC record when it would
- * be needed).
+ * Atomically update last_timestamp. This update races against concurrent
+ * atomic updates, but the race will always cause supplementary
+ * full timestamp records, never the opposite (missing a full
+ * timestamp record when it would be needed).
*/
- save_last_tsc(config, buf, ctx.priv.tsc);
+ save_last_timestamp(config, buf, ctx.priv.timestamp);
/*
* Push the reader if necessary
offsets->switch_old_end = 0;
offsets->pre_header_padding = 0;
- ctx->priv.tsc = config->cb.ring_buffer_clock_read(chan);
- if ((int64_t) ctx->priv.tsc == -EIO)
+ ctx->priv.timestamp = config->cb.ring_buffer_clock_read(chan);
+ if ((int64_t) ctx->priv.timestamp == -EIO)
return -EIO;
- if (last_tsc_overflow(config, buf, ctx->priv.tsc))
- ctx->priv.rflags |= RING_BUFFER_RFLAG_FULL_TSC;
+ if (last_timestamp_overflow(config, buf, ctx->priv.timestamp))
+ ctx->priv.rflags |= RING_BUFFER_RFLAG_FULL_TIMESTAMP;
if (unlikely(subbuf_offset(offsets->begin, ctx->priv.chan) == 0)) {
offsets->switch_new_start = 1; /* For offsets->begin */
!= offsets.old));
/*
- * Atomically update last_tsc. This update races against concurrent
- * atomic updates, but the race will always cause supplementary full TSC
- * records, never the opposite (missing a full TSC record when it would
- * be needed).
+ * Atomically update last_timestamp. This update races against concurrent
+ * atomic updates, but the race will always cause supplementary
+ * full timestamp records, never the opposite (missing a full
+ * timestamp record when it would be needed).
*/
- save_last_tsc(config, buf, ctx->priv.tsc);
+ save_last_timestamp(config, buf, ctx->priv.timestamp);
/*
* Push the reader if necessary
}
EXPORT_SYMBOL_GPL(lib_ring_buffer_check_deliver_slow);
+static
int __init init_lib_ring_buffer_frontend(void)
{
int cpu;
module_init(init_lib_ring_buffer_frontend);
+static
void __exit exit_lib_ring_buffer_frontend(void)
{
}
return ret;
}
+static
void event_notifier_send_notification_work_wakeup(struct irq_work *entry)
{
struct lttng_event_notifier_group *event_notifier_group =
* @file: the file
* @wait: poll table
*/
+static
unsigned int lttng_channel_poll(struct file *file, poll_table *wait)
{
struct lttng_kernel_channel_buffer *channel = file->private_data;
}
}
-/*
- * We own the filter_bytecode if we return success.
- */
-int lttng_filter_enabler_attach_bytecode(struct lttng_event_enabler_common *enabler,
- struct lttng_kernel_bytecode_node *filter_bytecode)
-{
- list_add(&filter_bytecode->node, &enabler->filter_bytecode_head);
- return 0;
-}
-
-void lttng_free_enabler_filter_bytecode(struct lttng_event_enabler_common *enabler)
-{
- struct lttng_kernel_bytecode_node *filter_bytecode, *tmp;
-
- list_for_each_entry_safe(filter_bytecode, tmp,
- &enabler->filter_bytecode_head, node) {
- kfree(filter_bytecode);
- }
-}
-
void lttng_free_event_filter_runtime(struct lttng_kernel_event_common *event)
{
struct bytecode_runtime *runtime, *tmp;
#include <lttng/abi.h>
#include <lttng/events.h>
+#include <lttng/events-internal.h>
-noinline
+static noinline
void lttng_calibrate_kretprobe(void)
{
asm volatile ("");
#include <wrapper/trace-clock.h>
#include <lttng/events.h>
#include <lttng/tracer.h>
+#include <lttng/events-internal.h>
struct lttng_trace_clock *lttng_trace_clock;
EXPORT_SYMBOL_GPL(lttng_trace_clock);
false, false),
};
+static
const struct lttng_kernel_event_field **lttng_cs_event_fields(enum lttng_cs_ctx_modes mode)
{
switch (mode) {
return 0;
}
+static
int capture_sequence(struct lttng_msgpack_writer *writer,
struct lttng_interpreter_output *output)
{
}
}
+static
struct lttng_kernel_id_tracker *get_tracker(struct lttng_kernel_session *session,
enum tracker_type tracker_type)
{
mutex_unlock(&sessions_mutex);
}
-int lttng_event_notifier_enabler_enable(
- struct lttng_event_notifier_enabler *event_notifier_enabler)
-{
- mutex_lock(&sessions_mutex);
- lttng_event_notifier_enabler_as_enabler(event_notifier_enabler)->enabled = 1;
- lttng_event_notifier_group_sync_enablers(event_notifier_enabler->group);
- mutex_unlock(&sessions_mutex);
- return 0;
-}
-
-int lttng_event_notifier_enabler_disable(
- struct lttng_event_notifier_enabler *event_notifier_enabler)
-{
- mutex_lock(&sessions_mutex);
- lttng_event_notifier_enabler_as_enabler(event_notifier_enabler)->enabled = 0;
- lttng_event_notifier_group_sync_enablers(event_notifier_enabler->group);
- mutex_unlock(&sessions_mutex);
- return 0;
-}
-
int lttng_event_notifier_enabler_attach_capture_bytecode(
struct lttng_event_notifier_enabler *event_notifier_enabler,
struct lttng_kernel_abi_capture_bytecode __user *bytecode)
* The content of the printf is printed as a single atomic metadata
* transaction.
*/
+static
int lttng_metadata_printf(struct lttng_kernel_session *session,
const char *fmt, ...)
{
#include <ringbuffer/frontend_types.h>
#define LTTNG_COMPACT_EVENT_BITS 5
-#define LTTNG_COMPACT_TSC_BITS 27
+#define LTTNG_COMPACT_TIMESTAMP_BITS 27
static struct lttng_transport lttng_relay_transport;
case 1: /* compact */
padding = lib_ring_buffer_align(offset, lttng_alignof(uint32_t));
offset += padding;
- if (!(ctx->priv.rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTTNG_RFLAG_EXTENDED))) {
+ if (!(ctx->priv.rflags & (RING_BUFFER_RFLAG_FULL_TIMESTAMP | LTTNG_RFLAG_EXTENDED))) {
offset += sizeof(uint32_t); /* id and timestamp */
} else {
/* Minimum space taken by LTTNG_COMPACT_EVENT_BITS id */
padding = lib_ring_buffer_align(offset, lttng_alignof(uint16_t));
offset += padding;
offset += sizeof(uint16_t);
- if (!(ctx->priv.rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTTNG_RFLAG_EXTENDED))) {
+ if (!(ctx->priv.rflags & (RING_BUFFER_RFLAG_FULL_TIMESTAMP | LTTNG_RFLAG_EXTENDED))) {
offset += lib_ring_buffer_align(offset, lttng_alignof(uint32_t));
offset += sizeof(uint32_t); /* timestamp */
} else {
event_id);
bt_bitfield_write(&id_time, uint32_t,
LTTNG_COMPACT_EVENT_BITS,
- LTTNG_COMPACT_TSC_BITS,
- ctx->priv.tsc);
+ LTTNG_COMPACT_TIMESTAMP_BITS,
+ ctx->priv.timestamp);
lib_ring_buffer_write(config, ctx, &id_time, sizeof(id_time));
break;
}
case 2: /* large */
{
- uint32_t timestamp = (uint32_t) ctx->priv.tsc;
+ uint32_t timestamp = (uint32_t) ctx->priv.timestamp;
uint16_t id = event_id;
lib_ring_buffer_write(config, ctx, &id, sizeof(id));
switch (lttng_chan->priv->header_type) {
case 1: /* compact */
- if (!(ctx->priv.rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTTNG_RFLAG_EXTENDED))) {
+ if (!(ctx->priv.rflags & (RING_BUFFER_RFLAG_FULL_TIMESTAMP | LTTNG_RFLAG_EXTENDED))) {
uint32_t id_time = 0;
bt_bitfield_write(&id_time, uint32_t,
event_id);
bt_bitfield_write(&id_time, uint32_t,
LTTNG_COMPACT_EVENT_BITS,
- LTTNG_COMPACT_TSC_BITS, ctx->priv.tsc);
+ LTTNG_COMPACT_TIMESTAMP_BITS, ctx->priv.timestamp);
lib_ring_buffer_write(config, ctx, &id_time, sizeof(id_time));
} else {
uint8_t id = 0;
- uint64_t timestamp = ctx->priv.tsc;
+ uint64_t timestamp = ctx->priv.timestamp;
bt_bitfield_write(&id, uint8_t,
0,
break;
case 2: /* large */
{
- if (!(ctx->priv.rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTTNG_RFLAG_EXTENDED))) {
- uint32_t timestamp = (uint32_t) ctx->priv.tsc;
+ if (!(ctx->priv.rflags & (RING_BUFFER_RFLAG_FULL_TIMESTAMP | LTTNG_RFLAG_EXTENDED))) {
+ uint32_t timestamp = (uint32_t) ctx->priv.timestamp;
uint16_t id = event_id;
lib_ring_buffer_write(config, ctx, &id, sizeof(id));
lib_ring_buffer_write(config, ctx, ×tamp, sizeof(timestamp));
} else {
uint16_t id = 65535;
- uint64_t timestamp = ctx->priv.tsc;
+ uint64_t timestamp = ctx->priv.timestamp;
lib_ring_buffer_write(config, ctx, &id, sizeof(id));
/* Align extended struct on largest member */
return offsetof(struct packet_header, ctx.header_end);
}
-static void client_buffer_begin(struct lttng_kernel_ring_buffer *buf, u64 tsc,
+static void client_buffer_begin(struct lttng_kernel_ring_buffer *buf, u64 timestamp,
unsigned int subbuf_idx)
{
struct lttng_kernel_ring_buffer_channel *chan = buf->backend.chan;
memcpy(header->uuid, session->priv->uuid.b, sizeof(session->priv->uuid));
header->stream_id = lttng_chan->priv->id;
header->stream_instance_id = buf->backend.cpu;
- header->ctx.timestamp_begin = tsc;
+ header->ctx.timestamp_begin = timestamp;
header->ctx.timestamp_end = 0;
header->ctx.content_size = ~0ULL; /* for debugging */
header->ctx.packet_size = ~0ULL;
* offset is assumed to never be 0 here : never deliver a completely empty
* subbuffer. data_size is between 1 and subbuf_size.
*/
-static void client_buffer_end(struct lttng_kernel_ring_buffer *buf, u64 tsc,
+static void client_buffer_end(struct lttng_kernel_ring_buffer *buf, u64 timestamp,
unsigned int subbuf_idx, unsigned long data_size,
const struct lttng_kernel_ring_buffer_ctx *ctx)
{
subbuf_idx * chan->backend.subbuf_size);
unsigned long records_lost = 0;
- header->ctx.timestamp_end = tsc;
+ header->ctx.timestamp_end = timestamp;
header->ctx.content_size =
(uint64_t) data_size * CHAR_BIT; /* in bits */
header->ctx.packet_size =
.cb.buffer_create = client_buffer_create,
.cb.buffer_finalize = client_buffer_finalize,
- .tsc_bits = LTTNG_COMPACT_TSC_BITS,
+ .timestamp_bits = LTTNG_COMPACT_TIMESTAMP_BITS,
.alloc = RING_BUFFER_ALLOC_PER_CPU,
.sync = RING_BUFFER_SYNC_PER_CPU,
.mode = RING_BUFFER_MODE_TEMPLATE,
return offsetof(struct event_notifier_packet_header, header_end);
}
-static void client_buffer_begin(struct lttng_kernel_ring_buffer *buf, u64 tsc,
+static void client_buffer_begin(struct lttng_kernel_ring_buffer *buf, u64 timestamp,
unsigned int subbuf_idx)
{
}
* offset is assumed to never be 0 here : never deliver a completely empty
* subbuffer. data_size is between 1 and subbuf_size.
*/
-static void client_buffer_end(struct lttng_kernel_ring_buffer *buf, u64 tsc,
+static void client_buffer_end(struct lttng_kernel_ring_buffer *buf, u64 timestamp,
unsigned int subbuf_idx, unsigned long data_size,
const struct lttng_kernel_ring_buffer_ctx *ctx)
{
.cb.buffer_finalize = client_buffer_finalize,
.cb.record_get = client_record_get,
- .tsc_bits = 0,
+ .timestamp_bits = 0,
.alloc = RING_BUFFER_ALLOC_GLOBAL,
.sync = RING_BUFFER_SYNC_GLOBAL,
.mode = RING_BUFFER_MODE_TEMPLATE,
return offsetof(struct metadata_packet_header, header_end);
}
-static void client_buffer_begin(struct lttng_kernel_ring_buffer *buf, u64 tsc,
+static void client_buffer_begin(struct lttng_kernel_ring_buffer *buf, u64 timestamp,
unsigned int subbuf_idx)
{
struct lttng_kernel_ring_buffer_channel *chan = buf->backend.chan;
* offset is assumed to never be 0 here : never deliver a completely empty
* subbuffer. data_size is between 1 and subbuf_size.
*/
-static void client_buffer_end(struct lttng_kernel_ring_buffer *buf, u64 tsc,
+static void client_buffer_end(struct lttng_kernel_ring_buffer *buf, u64 timestamp,
unsigned int subbuf_idx, unsigned long data_size,
const struct lttng_kernel_ring_buffer_ctx *ctx)
{
.cb.buffer_create = client_buffer_create,
.cb.buffer_finalize = client_buffer_finalize,
- .tsc_bits = 0,
+ .timestamp_bits = 0,
.alloc = RING_BUFFER_ALLOC_GLOBAL,
.sync = RING_BUFFER_SYNC_GLOBAL,
.mode = RING_BUFFER_MODE_TEMPLATE,
#include <lttng/events.h>
#include <lttng/tracer.h>
+#include <lttng/events-internal.h>
#include <wrapper/cpu.h>
#include <wrapper/irqdesc.h>
#include <wrapper/fdtable.h>
#include <wrapper/tracepoint.h>
#include <wrapper/blkdev.h>
-#include <wrapper/fdtable.h>
#include <wrapper/sched.h>
/* Define the tracepoints, but do not build the probes */
*/
flags &= ~FMODE_NONOTIFY;
fdt = files_fdtable(ctx->files);
+
/*
- * We need to check here again whether fd is within the fdt
- * max_fds range, because we might be seeing a different
- * files_fdtable() than iterate_fd(), assuming only RCU is
- * protecting the read. In reality, iterate_fd() holds
- * file_lock, which should ensure the fdt does not change while
- * the lock is taken, but we are not aware whether this is
- * guaranteed or not, so play safe.
+ * The fdt should only grow and iterate_fd() holds file_lock, which
+ * should ensure the fdt does not change while the lock is taken but be
+ * cautious and check anyway.
*/
- if (fd < fdt->max_fds && close_on_exec(fd, fdt))
+ if (WARN_ON_ONCE(fd >= fdt->max_fds))
+ return 0;
+
+ if (lttng_close_on_exec(fd, ctx->files))
flags |= O_CLOEXEC;
+
+ /*
+ * If d_path() failed to get a full path for the file, use the dentry
+ * name instead to at least get a filename.
+ */
if (IS_ERR(s)) {
struct dentry *dentry = file->f_path.dentry;
kfree(tmp_mask);
return ret;
}
-
-int lttng_abi_syscall_list(void)
-{
- struct file *syscall_list_file;
- int file_fd, ret;
-
- file_fd = get_unused_fd_flags(0);
- if (file_fd < 0) {
- ret = file_fd;
- goto fd_error;
- }
-
- syscall_list_file = anon_inode_getfile("[lttng_syscall_list]",
- <tng_syscall_list_fops,
- NULL, O_RDWR);
- if (IS_ERR(syscall_list_file)) {
- ret = PTR_ERR(syscall_list_file);
- goto file_error;
- }
- ret = lttng_syscall_list_fops.open(NULL, syscall_list_file);
- if (ret < 0)
- goto open_error;
- fd_install(file_fd, syscall_list_file);
- return file_fd;
-
-open_error:
- fput(syscall_list_file);
-file_error:
- put_unused_fd(file_fd);
-fd_error:
- return ret;
-}
}
EXPORT_SYMBOL_GPL(lttng_uprobes_destroy_event_private);
-void lttng_uprobes_destroy_event_notifier_private(struct lttng_kernel_event_notifier *event_notifier)
-{
- iput(event_notifier->priv->parent.u.uprobe.inode);
- kfree(event_notifier->priv->parent.desc->event_name);
- kfree(event_notifier->priv->parent.desc);
-}
-EXPORT_SYMBOL_GPL(lttng_uprobes_destroy_event_notifier_private);
-
MODULE_LICENSE("GPL and additional rights");
MODULE_AUTHOR("Yannick Brosseau");
MODULE_DESCRIPTION("Linux Trace Toolkit Uprobes Support");
#include <linux/miscdevice.h>
#include <wrapper/vmalloc.h>
#include <lttng/events.h>
+#include <lttng/events-internal.h>
#define TP_MODULE_NOAUTOLOAD
#define LTTNG_PACKAGE_BUILD
#ifdef CONFIG_KALLSYMS
+/* Include page_alloc wrapper before pageblock-flags.h. */
+#include <wrapper/page_alloc.h>
+
+#include <linux/pageblock-flags.h>
#include <linux/kallsyms.h>
#include <linux/mm_types.h>
#include <linux/module.h>
#include <wrapper/kallsyms.h>
-#include <wrapper/page_alloc.h>
+#include <lttng/kernel-version.h>
+
+#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,14,0))
+static
+unsigned long (*get_pfnblock_flags_mask_sym)(const struct page *page,
+ unsigned long pfn,
+ unsigned long mask);
+
+unsigned long wrapper_get_pfnblock_flags_mask(const struct page *page,
+ unsigned long pfn,
+ unsigned long mask)
+{
+ WARN_ON_ONCE(!get_pfnblock_flags_mask_sym);
+ if (get_pfnblock_flags_mask_sym) {
+ struct irq_ibt_state irq_ibt_state;
+ unsigned long ret;
+ irq_ibt_state = wrapper_irq_ibt_save();
+ ret = get_pfnblock_flags_mask_sym(page, pfn, mask);
+ wrapper_irq_ibt_restore(irq_ibt_state);
+ return ret;
+ } else {
+ return -ENOSYS;
+ }
+}
+#elif (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,9,0))
+static
+unsigned long (*get_pfnblock_flags_mask_sym)(struct page *page,
+ unsigned long pfn,
+ unsigned long mask);
+
+unsigned long wrapper_get_pfnblock_flags_mask(struct page *page,
+ unsigned long pfn,
+ unsigned long mask)
+{
+ WARN_ON_ONCE(!get_pfnblock_flags_mask_sym);
+ if (get_pfnblock_flags_mask_sym) {
+ struct irq_ibt_state irq_ibt_state;
+ unsigned long ret;
+
+ irq_ibt_state = wrapper_irq_ibt_save();
+ ret = get_pfnblock_flags_mask_sym(page, pfn, mask);
+ wrapper_irq_ibt_restore(irq_ibt_state);
+ return ret;
+ } else {
+ return -ENOSYS;
+ }
+}
+#else /* #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,9,0)) */
static
unsigned long (*get_pfnblock_flags_mask_sym)(struct page *page,
unsigned long pfn,
return -ENOSYS;
}
}
+#endif /* #else #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,9,0)) */
+
EXPORT_SYMBOL_GPL(wrapper_get_pfnblock_flags_mask);
int wrapper_get_pfnblock_flags_mask_init(void)
}
EXPORT_SYMBOL_GPL(wrapper_get_pfnblock_flags_mask_init);
-/*
- * Canary function to check for 'get_pfnblock_flags_mask()' at compile time.
- *
- * From 'include/linux/pageblock-flags.h':
- *
- * unsigned long get_pfnblock_flags_mask(struct page *page,
- * unsigned long pfn,
- * unsigned long end_bitidx,
- * unsigned long mask);
- */
-__attribute__((unused)) static
-unsigned long __canary__get_pfnblock_flags_mask(struct page *page,
- unsigned long pfn,
- unsigned long end_bitidx,
- unsigned long mask)
-{
- return get_pfnblock_flags_mask(page, pfn, end_bitidx, mask);
-}
-
#else
#include <linux/pageblock-flags.h>
#include <wrapper/trace-clock.h>
#ifdef LTTNG_USE_NMI_SAFE_CLOCK
-DEFINE_PER_CPU(u64, lttng_last_tsc);
-EXPORT_PER_CPU_SYMBOL(lttng_last_tsc);
+DEFINE_PER_CPU(u64, lttng_last_timestamp);
+EXPORT_PER_CPU_SYMBOL(lttng_last_timestamp);
#endif /* #ifdef LTTNG_USE_NMI_SAFE_CLOCK */
#ifdef LTTNG_CLOCK_NMI_SAFE_BROKEN
# SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
# example usage:
-# lttng-get-syscall-inout.sh table-syscall-inout.txt select 1
+# lttng-get-syscall-inout.sh arm-64 select 5 1
ARCH_NAME=$1
SYSCALL_NAME=$2
# Delete temp file on exit
trap 'rm -f "$TMPFILE"' EXIT
-if [ "${GENERIC_INOUT_DESCRIPTION_FILE}" = "" ]; then
- echo "Error: Please specify input file name as first argument" >&2
+if [ "${ARCH_NAME}" = "" ]; then
+ echo "Error: Please specify the arch name as first argument" >&2
exit 1
fi
if [ "${SYSCALL_NAME}" = "" ]; then
- echo "Error: Please specify system call name as second argument" >&2
+ echo "Error: Please specify the system call name as second argument" >&2
+ exit 1
+fi
+
+if [[ "${NB_ARGS}" = "" ]]; then
+ echo "Error: Please specify a number of arguments as third argument" >&2
exit 1
fi
if [[ "${ARG_NR}" = "" || ${ARG_NR} == 0 ]]; then
- echo "Error: Please specify argument number larger than 0 as third argument" >&2
+ echo "Error: Please specify an argument number larger than 0 as fourth argument" >&2
exit 1
fi