You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'tracing-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'tracing-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (105 commits) ring-buffer: only enable ring_buffer_swap_cpu when needed ring-buffer: check for swapped buffers in start of committing tracing: report error in trace if we fail to swap latency buffer tracing: add trace_array_printk for internal tracers to use tracing: pass around ring buffer instead of tracer tracing: make tracing_reset safe for external use tracing: use timestamp to determine start of latency traces tracing: Remove mentioning of legacy latency_trace file from documentation tracing/filters: Defer pred allocation, fix memory leak tracing: remove users of tracing_reset tracing: disable buffers and synchronize_sched before resetting tracing: disable update max tracer while reading trace tracing: print out start and stop in latency traces ring-buffer: disable all cpu buffers when one finds a problem ring-buffer: do not count discarded events ring-buffer: remove ring_buffer_event_discard ring-buffer: fix ring_buffer_read crossing pages ring-buffer: remove unnecessary cpu_relax ring-buffer: do not swap buffers during a commit ring-buffer: do not reset while in a commit ...
This commit is contained in:
@@ -93,16 +93,22 @@ void tracing_generic_entry_update(struct trace_entry *entry,
|
||||
unsigned long flags,
|
||||
int pc);
|
||||
struct ring_buffer_event *
|
||||
trace_current_buffer_lock_reserve(int type, unsigned long len,
|
||||
trace_current_buffer_lock_reserve(struct ring_buffer **current_buffer,
|
||||
int type, unsigned long len,
|
||||
unsigned long flags, int pc);
|
||||
void trace_current_buffer_unlock_commit(struct ring_buffer_event *event,
|
||||
void trace_current_buffer_unlock_commit(struct ring_buffer *buffer,
|
||||
struct ring_buffer_event *event,
|
||||
unsigned long flags, int pc);
|
||||
void trace_nowake_buffer_unlock_commit(struct ring_buffer_event *event,
|
||||
void trace_nowake_buffer_unlock_commit(struct ring_buffer *buffer,
|
||||
struct ring_buffer_event *event,
|
||||
unsigned long flags, int pc);
|
||||
void trace_current_buffer_discard_commit(struct ring_buffer_event *event);
|
||||
void trace_current_buffer_discard_commit(struct ring_buffer *buffer,
|
||||
struct ring_buffer_event *event);
|
||||
|
||||
void tracing_record_cmdline(struct task_struct *tsk);
|
||||
|
||||
struct event_filter;
|
||||
|
||||
struct ftrace_event_call {
|
||||
struct list_head list;
|
||||
char *name;
|
||||
@@ -110,16 +116,18 @@ struct ftrace_event_call {
|
||||
struct dentry *dir;
|
||||
struct trace_event *event;
|
||||
int enabled;
|
||||
int (*regfunc)(void);
|
||||
void (*unregfunc)(void);
|
||||
int (*regfunc)(void *);
|
||||
void (*unregfunc)(void *);
|
||||
int id;
|
||||
int (*raw_init)(void);
|
||||
int (*show_format)(struct trace_seq *s);
|
||||
int (*define_fields)(void);
|
||||
int (*show_format)(struct ftrace_event_call *call,
|
||||
struct trace_seq *s);
|
||||
int (*define_fields)(struct ftrace_event_call *);
|
||||
struct list_head fields;
|
||||
int filter_active;
|
||||
void *filter;
|
||||
struct event_filter *filter;
|
||||
void *mod;
|
||||
void *data;
|
||||
|
||||
atomic_t profile_count;
|
||||
int (*profile_enable)(struct ftrace_event_call *);
|
||||
@@ -129,15 +137,25 @@ struct ftrace_event_call {
|
||||
#define MAX_FILTER_PRED 32
|
||||
#define MAX_FILTER_STR_VAL 128
|
||||
|
||||
extern int init_preds(struct ftrace_event_call *call);
|
||||
extern void destroy_preds(struct ftrace_event_call *call);
|
||||
extern int filter_match_preds(struct ftrace_event_call *call, void *rec);
|
||||
extern int filter_current_check_discard(struct ftrace_event_call *call,
|
||||
extern int filter_current_check_discard(struct ring_buffer *buffer,
|
||||
struct ftrace_event_call *call,
|
||||
void *rec,
|
||||
struct ring_buffer_event *event);
|
||||
|
||||
extern int trace_define_field(struct ftrace_event_call *call, char *type,
|
||||
char *name, int offset, int size, int is_signed);
|
||||
enum {
|
||||
FILTER_OTHER = 0,
|
||||
FILTER_STATIC_STRING,
|
||||
FILTER_DYN_STRING,
|
||||
FILTER_PTR_STRING,
|
||||
};
|
||||
|
||||
extern int trace_define_field(struct ftrace_event_call *call,
|
||||
const char *type, const char *name,
|
||||
int offset, int size, int is_signed,
|
||||
int filter_type);
|
||||
extern int trace_define_common_fields(struct ftrace_event_call *call);
|
||||
|
||||
#define is_signed_type(type) (((type)(-1)) < 0)
|
||||
|
||||
@@ -162,11 +180,4 @@ do { \
|
||||
__trace_printk(ip, fmt, ##args); \
|
||||
} while (0)
|
||||
|
||||
#define __common_field(type, item, is_signed) \
|
||||
ret = trace_define_field(event_call, #type, "common_" #item, \
|
||||
offsetof(typeof(field.ent), item), \
|
||||
sizeof(field.ent.item), is_signed); \
|
||||
if (ret) \
|
||||
return ret;
|
||||
|
||||
#endif /* _LINUX_FTRACE_EVENT_H */
|
||||
|
||||
+11
-3
@@ -17,10 +17,12 @@
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/marker.h>
|
||||
#include <linux/tracepoint.h>
|
||||
#include <asm/local.h>
|
||||
|
||||
#include <asm/local.h>
|
||||
#include <asm/module.h>
|
||||
|
||||
#include <trace/events/module.h>
|
||||
|
||||
/* Not Yet Implemented */
|
||||
#define MODULE_SUPPORTED_DEVICE(name)
|
||||
|
||||
@@ -462,7 +464,10 @@ static inline local_t *__module_ref_addr(struct module *mod, int cpu)
|
||||
static inline void __module_get(struct module *module)
|
||||
{
|
||||
if (module) {
|
||||
local_inc(__module_ref_addr(module, get_cpu()));
|
||||
unsigned int cpu = get_cpu();
|
||||
local_inc(__module_ref_addr(module, cpu));
|
||||
trace_module_get(module, _THIS_IP_,
|
||||
local_read(__module_ref_addr(module, cpu)));
|
||||
put_cpu();
|
||||
}
|
||||
}
|
||||
@@ -473,8 +478,11 @@ static inline int try_module_get(struct module *module)
|
||||
|
||||
if (module) {
|
||||
unsigned int cpu = get_cpu();
|
||||
if (likely(module_is_live(module)))
|
||||
if (likely(module_is_live(module))) {
|
||||
local_inc(__module_ref_addr(module, cpu));
|
||||
trace_module_get(module, _THIS_IP_,
|
||||
local_read(__module_ref_addr(module, cpu)));
|
||||
}
|
||||
else
|
||||
ret = 0;
|
||||
put_cpu();
|
||||
|
||||
@@ -766,6 +766,8 @@ extern int sysctl_perf_counter_mlock;
|
||||
extern int sysctl_perf_counter_sample_rate;
|
||||
|
||||
extern void perf_counter_init(void);
|
||||
extern void perf_tpcounter_event(int event_id, u64 addr, u64 count,
|
||||
void *record, int entry_size);
|
||||
|
||||
#ifndef perf_misc_flags
|
||||
#define perf_misc_flags(regs) (user_mode(regs) ? PERF_EVENT_MISC_USER : \
|
||||
|
||||
@@ -74,20 +74,6 @@ ring_buffer_event_time_delta(struct ring_buffer_event *event)
|
||||
return event->time_delta;
|
||||
}
|
||||
|
||||
/*
|
||||
* ring_buffer_event_discard can discard any event in the ring buffer.
|
||||
* it is up to the caller to protect against a reader from
|
||||
* consuming it or a writer from wrapping and replacing it.
|
||||
*
|
||||
* No external protection is needed if this is called before
|
||||
* the event is commited. But in that case it would be better to
|
||||
* use ring_buffer_discard_commit.
|
||||
*
|
||||
* Note, if an event that has not been committed is discarded
|
||||
* with ring_buffer_event_discard, it must still be committed.
|
||||
*/
|
||||
void ring_buffer_event_discard(struct ring_buffer_event *event);
|
||||
|
||||
/*
|
||||
* ring_buffer_discard_commit will remove an event that has not
|
||||
* ben committed yet. If this is used, then ring_buffer_unlock_commit
|
||||
@@ -154,8 +140,17 @@ unsigned long ring_buffer_size(struct ring_buffer *buffer);
|
||||
void ring_buffer_reset_cpu(struct ring_buffer *buffer, int cpu);
|
||||
void ring_buffer_reset(struct ring_buffer *buffer);
|
||||
|
||||
#ifdef CONFIG_RING_BUFFER_ALLOW_SWAP
|
||||
int ring_buffer_swap_cpu(struct ring_buffer *buffer_a,
|
||||
struct ring_buffer *buffer_b, int cpu);
|
||||
#else
|
||||
static inline int
|
||||
ring_buffer_swap_cpu(struct ring_buffer *buffer_a,
|
||||
struct ring_buffer *buffer_b, int cpu)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
|
||||
int ring_buffer_empty(struct ring_buffer *buffer);
|
||||
int ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu);
|
||||
@@ -170,7 +165,6 @@ unsigned long ring_buffer_overruns(struct ring_buffer *buffer);
|
||||
unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu);
|
||||
unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu);
|
||||
unsigned long ring_buffer_commit_overrun_cpu(struct ring_buffer *buffer, int cpu);
|
||||
unsigned long ring_buffer_nmi_dropped_cpu(struct ring_buffer *buffer, int cpu);
|
||||
|
||||
u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu);
|
||||
void ring_buffer_normalize_time_stamp(struct ring_buffer *buffer,
|
||||
|
||||
+129
-2
@@ -64,6 +64,7 @@ struct perf_counter_attr;
|
||||
#include <linux/sem.h>
|
||||
#include <asm/siginfo.h>
|
||||
#include <asm/signal.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/quota.h>
|
||||
#include <linux/key.h>
|
||||
#include <trace/syscall.h>
|
||||
@@ -97,6 +98,53 @@ struct perf_counter_attr;
|
||||
#define __SC_TEST5(t5, a5, ...) __SC_TEST(t5); __SC_TEST4(__VA_ARGS__)
|
||||
#define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__)
|
||||
|
||||
#ifdef CONFIG_EVENT_PROFILE
|
||||
#define TRACE_SYS_ENTER_PROFILE(sname) \
|
||||
static int prof_sysenter_enable_##sname(struct ftrace_event_call *event_call) \
|
||||
{ \
|
||||
int ret = 0; \
|
||||
if (!atomic_inc_return(&event_enter_##sname.profile_count)) \
|
||||
ret = reg_prof_syscall_enter("sys"#sname); \
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
static void prof_sysenter_disable_##sname(struct ftrace_event_call *event_call)\
|
||||
{ \
|
||||
if (atomic_add_negative(-1, &event_enter_##sname.profile_count)) \
|
||||
unreg_prof_syscall_enter("sys"#sname); \
|
||||
}
|
||||
|
||||
#define TRACE_SYS_EXIT_PROFILE(sname) \
|
||||
static int prof_sysexit_enable_##sname(struct ftrace_event_call *event_call) \
|
||||
{ \
|
||||
int ret = 0; \
|
||||
if (!atomic_inc_return(&event_exit_##sname.profile_count)) \
|
||||
ret = reg_prof_syscall_exit("sys"#sname); \
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
static void prof_sysexit_disable_##sname(struct ftrace_event_call *event_call) \
|
||||
{ \
|
||||
if (atomic_add_negative(-1, &event_exit_##sname.profile_count)) \
|
||||
unreg_prof_syscall_exit("sys"#sname); \
|
||||
}
|
||||
|
||||
#define TRACE_SYS_ENTER_PROFILE_INIT(sname) \
|
||||
.profile_count = ATOMIC_INIT(-1), \
|
||||
.profile_enable = prof_sysenter_enable_##sname, \
|
||||
.profile_disable = prof_sysenter_disable_##sname,
|
||||
|
||||
#define TRACE_SYS_EXIT_PROFILE_INIT(sname) \
|
||||
.profile_count = ATOMIC_INIT(-1), \
|
||||
.profile_enable = prof_sysexit_enable_##sname, \
|
||||
.profile_disable = prof_sysexit_disable_##sname,
|
||||
#else
|
||||
#define TRACE_SYS_ENTER_PROFILE(sname)
|
||||
#define TRACE_SYS_ENTER_PROFILE_INIT(sname)
|
||||
#define TRACE_SYS_EXIT_PROFILE(sname)
|
||||
#define TRACE_SYS_EXIT_PROFILE_INIT(sname)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FTRACE_SYSCALLS
|
||||
#define __SC_STR_ADECL1(t, a) #a
|
||||
#define __SC_STR_ADECL2(t, a, ...) #a, __SC_STR_ADECL1(__VA_ARGS__)
|
||||
@@ -112,7 +160,81 @@ struct perf_counter_attr;
|
||||
#define __SC_STR_TDECL5(t, a, ...) #t, __SC_STR_TDECL4(__VA_ARGS__)
|
||||
#define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__)
|
||||
|
||||
#define SYSCALL_TRACE_ENTER_EVENT(sname) \
|
||||
static struct ftrace_event_call event_enter_##sname; \
|
||||
struct trace_event enter_syscall_print_##sname = { \
|
||||
.trace = print_syscall_enter, \
|
||||
}; \
|
||||
static int init_enter_##sname(void) \
|
||||
{ \
|
||||
int num, id; \
|
||||
num = syscall_name_to_nr("sys"#sname); \
|
||||
if (num < 0) \
|
||||
return -ENOSYS; \
|
||||
id = register_ftrace_event(&enter_syscall_print_##sname);\
|
||||
if (!id) \
|
||||
return -ENODEV; \
|
||||
event_enter_##sname.id = id; \
|
||||
set_syscall_enter_id(num, id); \
|
||||
INIT_LIST_HEAD(&event_enter_##sname.fields); \
|
||||
return 0; \
|
||||
} \
|
||||
TRACE_SYS_ENTER_PROFILE(sname); \
|
||||
static struct ftrace_event_call __used \
|
||||
__attribute__((__aligned__(4))) \
|
||||
__attribute__((section("_ftrace_events"))) \
|
||||
event_enter_##sname = { \
|
||||
.name = "sys_enter"#sname, \
|
||||
.system = "syscalls", \
|
||||
.event = &event_syscall_enter, \
|
||||
.raw_init = init_enter_##sname, \
|
||||
.show_format = syscall_enter_format, \
|
||||
.define_fields = syscall_enter_define_fields, \
|
||||
.regfunc = reg_event_syscall_enter, \
|
||||
.unregfunc = unreg_event_syscall_enter, \
|
||||
.data = "sys"#sname, \
|
||||
TRACE_SYS_ENTER_PROFILE_INIT(sname) \
|
||||
}
|
||||
|
||||
#define SYSCALL_TRACE_EXIT_EVENT(sname) \
|
||||
static struct ftrace_event_call event_exit_##sname; \
|
||||
struct trace_event exit_syscall_print_##sname = { \
|
||||
.trace = print_syscall_exit, \
|
||||
}; \
|
||||
static int init_exit_##sname(void) \
|
||||
{ \
|
||||
int num, id; \
|
||||
num = syscall_name_to_nr("sys"#sname); \
|
||||
if (num < 0) \
|
||||
return -ENOSYS; \
|
||||
id = register_ftrace_event(&exit_syscall_print_##sname);\
|
||||
if (!id) \
|
||||
return -ENODEV; \
|
||||
event_exit_##sname.id = id; \
|
||||
set_syscall_exit_id(num, id); \
|
||||
INIT_LIST_HEAD(&event_exit_##sname.fields); \
|
||||
return 0; \
|
||||
} \
|
||||
TRACE_SYS_EXIT_PROFILE(sname); \
|
||||
static struct ftrace_event_call __used \
|
||||
__attribute__((__aligned__(4))) \
|
||||
__attribute__((section("_ftrace_events"))) \
|
||||
event_exit_##sname = { \
|
||||
.name = "sys_exit"#sname, \
|
||||
.system = "syscalls", \
|
||||
.event = &event_syscall_exit, \
|
||||
.raw_init = init_exit_##sname, \
|
||||
.show_format = syscall_exit_format, \
|
||||
.define_fields = syscall_exit_define_fields, \
|
||||
.regfunc = reg_event_syscall_exit, \
|
||||
.unregfunc = unreg_event_syscall_exit, \
|
||||
.data = "sys"#sname, \
|
||||
TRACE_SYS_EXIT_PROFILE_INIT(sname) \
|
||||
}
|
||||
|
||||
#define SYSCALL_METADATA(sname, nb) \
|
||||
SYSCALL_TRACE_ENTER_EVENT(sname); \
|
||||
SYSCALL_TRACE_EXIT_EVENT(sname); \
|
||||
static const struct syscall_metadata __used \
|
||||
__attribute__((__aligned__(4))) \
|
||||
__attribute__((section("__syscalls_metadata"))) \
|
||||
@@ -121,18 +243,23 @@ struct perf_counter_attr;
|
||||
.nb_args = nb, \
|
||||
.types = types_##sname, \
|
||||
.args = args_##sname, \
|
||||
}
|
||||
.enter_event = &event_enter_##sname, \
|
||||
.exit_event = &event_exit_##sname, \
|
||||
};
|
||||
|
||||
#define SYSCALL_DEFINE0(sname) \
|
||||
SYSCALL_TRACE_ENTER_EVENT(_##sname); \
|
||||
SYSCALL_TRACE_EXIT_EVENT(_##sname); \
|
||||
static const struct syscall_metadata __used \
|
||||
__attribute__((__aligned__(4))) \
|
||||
__attribute__((section("__syscalls_metadata"))) \
|
||||
__syscall_meta_##sname = { \
|
||||
.name = "sys_"#sname, \
|
||||
.nb_args = 0, \
|
||||
.enter_event = &event_enter__##sname, \
|
||||
.exit_event = &event_exit__##sname, \
|
||||
}; \
|
||||
asmlinkage long sys_##sname(void)
|
||||
|
||||
#else
|
||||
#define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void)
|
||||
#endif
|
||||
|
||||
@@ -23,6 +23,8 @@ struct tracepoint;
|
||||
struct tracepoint {
|
||||
const char *name; /* Tracepoint name */
|
||||
int state; /* State. */
|
||||
void (*regfunc)(void);
|
||||
void (*unregfunc)(void);
|
||||
void **funcs;
|
||||
} __attribute__((aligned(32))); /*
|
||||
* Aligned on 32 bytes because it is
|
||||
@@ -78,12 +80,16 @@ struct tracepoint {
|
||||
return tracepoint_probe_unregister(#name, (void *)probe);\
|
||||
}
|
||||
|
||||
#define DEFINE_TRACE(name) \
|
||||
|
||||
#define DEFINE_TRACE_FN(name, reg, unreg) \
|
||||
static const char __tpstrtab_##name[] \
|
||||
__attribute__((section("__tracepoints_strings"))) = #name; \
|
||||
struct tracepoint __tracepoint_##name \
|
||||
__attribute__((section("__tracepoints"), aligned(32))) = \
|
||||
{ __tpstrtab_##name, 0, NULL }
|
||||
{ __tpstrtab_##name, 0, reg, unreg, NULL }
|
||||
|
||||
#define DEFINE_TRACE(name) \
|
||||
DEFINE_TRACE_FN(name, NULL, NULL);
|
||||
|
||||
#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \
|
||||
EXPORT_SYMBOL_GPL(__tracepoint_##name)
|
||||
@@ -108,6 +114,7 @@ extern void tracepoint_update_probe_range(struct tracepoint *begin,
|
||||
return -ENOSYS; \
|
||||
}
|
||||
|
||||
#define DEFINE_TRACE_FN(name, reg, unreg)
|
||||
#define DEFINE_TRACE(name)
|
||||
#define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
|
||||
#define EXPORT_TRACEPOINT_SYMBOL(name)
|
||||
@@ -158,6 +165,15 @@ static inline void tracepoint_synchronize_unregister(void)
|
||||
|
||||
#define PARAMS(args...) args
|
||||
|
||||
#endif /* _LINUX_TRACEPOINT_H */
|
||||
|
||||
/*
|
||||
* Note: we keep the TRACE_EVENT outside the include file ifdef protection.
|
||||
* This is due to the way trace events work. If a file includes two
|
||||
* trace event headers under one "CREATE_TRACE_POINTS" the first include
|
||||
* will override the TRACE_EVENT and break the second include.
|
||||
*/
|
||||
|
||||
#ifndef TRACE_EVENT
|
||||
/*
|
||||
* For use with the TRACE_EVENT macro:
|
||||
@@ -259,10 +275,15 @@ static inline void tracepoint_synchronize_unregister(void)
|
||||
* can also by used by generic instrumentation like SystemTap), and
|
||||
* it is also used to expose a structured trace record in
|
||||
* /sys/kernel/debug/tracing/events/.
|
||||
*
|
||||
* A set of (un)registration functions can be passed to the variant
|
||||
* TRACE_EVENT_FN to perform any (un)registration work.
|
||||
*/
|
||||
|
||||
#define TRACE_EVENT(name, proto, args, struct, assign, print) \
|
||||
DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
|
||||
#endif
|
||||
#define TRACE_EVENT_FN(name, proto, args, struct, \
|
||||
assign, print, reg, unreg) \
|
||||
DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
|
||||
|
||||
#endif
|
||||
#endif /* ifdef TRACE_EVENT (see note above) */
|
||||
|
||||
Reference in New Issue
Block a user