Merge branch 'tracing-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'tracing-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: tracing: Fix return of trace_dump_stack() ksym_tracer: Fix bad cast tracing/power: Remove two exports tracing: Change event->profile_count to be int type tracing: Simplify trace_option_write() tracing: Remove useless trace option tracing: Use seq file for trace_clock tracing: Use seq file for trace_options function-graph: Allow writing the same val to set_graph_function ftrace: Call trace_parser_clear() properly ftrace: Return EINVAL when writing invalid val to set_ftrace_filter tracing: Move a printk out of ftrace_raw_reg_event_foo() tracing: Pull up calls to trace_define_common_fields() tracing: Extract duplicate ftrace_raw_init_event_foo() ftrace.h: Use common pr_info fmt string tracing: Add stack trace to irqsoff tracer tracing: Add trace_dump_stack() ring-buffer: Move resize integrity check under reader lock ring-buffer: Use sync sched protection on ring buffer resizing tracing: Fix wrong usage of strstrip in trace_ksyms
This commit is contained in:
@@ -131,7 +131,7 @@ struct ftrace_event_call {
|
|||||||
void *mod;
|
void *mod;
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
atomic_t profile_count;
|
int profile_count;
|
||||||
int (*profile_enable)(struct ftrace_event_call *);
|
int (*profile_enable)(struct ftrace_event_call *);
|
||||||
void (*profile_disable)(struct ftrace_event_call *);
|
void (*profile_disable)(struct ftrace_event_call *);
|
||||||
};
|
};
|
||||||
@@ -158,7 +158,7 @@ enum {
|
|||||||
FILTER_PTR_STRING,
|
FILTER_PTR_STRING,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int trace_define_common_fields(struct ftrace_event_call *call);
|
extern int trace_event_raw_init(struct ftrace_event_call *call);
|
||||||
extern int trace_define_field(struct ftrace_event_call *call, const char *type,
|
extern int trace_define_field(struct ftrace_event_call *call, const char *type,
|
||||||
const char *name, int offset, int size,
|
const char *name, int offset, int size,
|
||||||
int is_signed, int filter_type);
|
int is_signed, int filter_type);
|
||||||
|
@@ -535,6 +535,8 @@ extern int
|
|||||||
__trace_printk(unsigned long ip, const char *fmt, ...)
|
__trace_printk(unsigned long ip, const char *fmt, ...)
|
||||||
__attribute__ ((format (printf, 2, 3)));
|
__attribute__ ((format (printf, 2, 3)));
|
||||||
|
|
||||||
|
extern void trace_dump_stack(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The double __builtin_constant_p is because gcc will give us an error
|
* The double __builtin_constant_p is because gcc will give us an error
|
||||||
* if we try to allocate the static variable to fmt if it is not a
|
* if we try to allocate the static variable to fmt if it is not a
|
||||||
@@ -568,6 +570,7 @@ trace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
|||||||
static inline void tracing_start(void) { }
|
static inline void tracing_start(void) { }
|
||||||
static inline void tracing_stop(void) { }
|
static inline void tracing_stop(void) { }
|
||||||
static inline void ftrace_off_permanent(void) { }
|
static inline void ftrace_off_permanent(void) { }
|
||||||
|
static inline void trace_dump_stack(void) { }
|
||||||
static inline int
|
static inline int
|
||||||
trace_printk(const char *fmt, ...)
|
trace_printk(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
@@ -102,12 +102,10 @@ struct perf_event_attr;
|
|||||||
#ifdef CONFIG_EVENT_PROFILE
|
#ifdef CONFIG_EVENT_PROFILE
|
||||||
|
|
||||||
#define TRACE_SYS_ENTER_PROFILE_INIT(sname) \
|
#define TRACE_SYS_ENTER_PROFILE_INIT(sname) \
|
||||||
.profile_count = ATOMIC_INIT(-1), \
|
|
||||||
.profile_enable = prof_sysenter_enable, \
|
.profile_enable = prof_sysenter_enable, \
|
||||||
.profile_disable = prof_sysenter_disable,
|
.profile_disable = prof_sysenter_disable,
|
||||||
|
|
||||||
#define TRACE_SYS_EXIT_PROFILE_INIT(sname) \
|
#define TRACE_SYS_EXIT_PROFILE_INIT(sname) \
|
||||||
.profile_count = ATOMIC_INIT(-1), \
|
|
||||||
.profile_enable = prof_sysexit_enable, \
|
.profile_enable = prof_sysexit_enable, \
|
||||||
.profile_disable = prof_sysexit_disable,
|
.profile_disable = prof_sysexit_disable,
|
||||||
#else
|
#else
|
||||||
@@ -145,7 +143,7 @@ struct perf_event_attr;
|
|||||||
.name = "sys_enter"#sname, \
|
.name = "sys_enter"#sname, \
|
||||||
.system = "syscalls", \
|
.system = "syscalls", \
|
||||||
.event = &enter_syscall_print_##sname, \
|
.event = &enter_syscall_print_##sname, \
|
||||||
.raw_init = init_syscall_trace, \
|
.raw_init = trace_event_raw_init, \
|
||||||
.show_format = syscall_enter_format, \
|
.show_format = syscall_enter_format, \
|
||||||
.define_fields = syscall_enter_define_fields, \
|
.define_fields = syscall_enter_define_fields, \
|
||||||
.regfunc = reg_event_syscall_enter, \
|
.regfunc = reg_event_syscall_enter, \
|
||||||
@@ -167,7 +165,7 @@ struct perf_event_attr;
|
|||||||
.name = "sys_exit"#sname, \
|
.name = "sys_exit"#sname, \
|
||||||
.system = "syscalls", \
|
.system = "syscalls", \
|
||||||
.event = &exit_syscall_print_##sname, \
|
.event = &exit_syscall_print_##sname, \
|
||||||
.raw_init = init_syscall_trace, \
|
.raw_init = trace_event_raw_init, \
|
||||||
.show_format = syscall_exit_format, \
|
.show_format = syscall_exit_format, \
|
||||||
.define_fields = syscall_exit_define_fields, \
|
.define_fields = syscall_exit_define_fields, \
|
||||||
.regfunc = reg_event_syscall_exit, \
|
.regfunc = reg_event_syscall_exit, \
|
||||||
|
@@ -436,10 +436,6 @@ ftrace_define_fields_##call(struct ftrace_event_call *event_call) \
|
|||||||
struct ftrace_raw_##call field; \
|
struct ftrace_raw_##call field; \
|
||||||
int ret; \
|
int ret; \
|
||||||
\
|
\
|
||||||
ret = trace_define_common_fields(event_call); \
|
|
||||||
if (ret) \
|
|
||||||
return ret; \
|
|
||||||
\
|
|
||||||
tstruct; \
|
tstruct; \
|
||||||
\
|
\
|
||||||
return ret; \
|
return ret; \
|
||||||
@@ -559,13 +555,7 @@ static void ftrace_profile_disable_##name(struct ftrace_event_call *unused)\
|
|||||||
*
|
*
|
||||||
* static int ftrace_reg_event_<call>(struct ftrace_event_call *unused)
|
* static int ftrace_reg_event_<call>(struct ftrace_event_call *unused)
|
||||||
* {
|
* {
|
||||||
* int ret;
|
* return register_trace_<call>(ftrace_event_<call>);
|
||||||
*
|
|
||||||
* ret = register_trace_<call>(ftrace_event_<call>);
|
|
||||||
* if (!ret)
|
|
||||||
* pr_info("event trace: Could not activate trace point "
|
|
||||||
* "probe to <call>");
|
|
||||||
* return ret;
|
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused)
|
* static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused)
|
||||||
@@ -623,23 +613,12 @@ static void ftrace_profile_disable_##name(struct ftrace_event_call *unused)\
|
|||||||
* .trace = ftrace_raw_output_<call>, <-- stage 2
|
* .trace = ftrace_raw_output_<call>, <-- stage 2
|
||||||
* };
|
* };
|
||||||
*
|
*
|
||||||
* static int ftrace_raw_init_event_<call>(struct ftrace_event_call *unused)
|
|
||||||
* {
|
|
||||||
* int id;
|
|
||||||
*
|
|
||||||
* id = register_ftrace_event(&ftrace_event_type_<call>);
|
|
||||||
* if (!id)
|
|
||||||
* return -ENODEV;
|
|
||||||
* event_<call>.id = id;
|
|
||||||
* return 0;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* static struct ftrace_event_call __used
|
* static struct ftrace_event_call __used
|
||||||
* __attribute__((__aligned__(4)))
|
* __attribute__((__aligned__(4)))
|
||||||
* __attribute__((section("_ftrace_events"))) event_<call> = {
|
* __attribute__((section("_ftrace_events"))) event_<call> = {
|
||||||
* .name = "<call>",
|
* .name = "<call>",
|
||||||
* .system = "<system>",
|
* .system = "<system>",
|
||||||
* .raw_init = ftrace_raw_init_event_<call>,
|
* .raw_init = trace_event_raw_init,
|
||||||
* .regfunc = ftrace_reg_event_<call>,
|
* .regfunc = ftrace_reg_event_<call>,
|
||||||
* .unregfunc = ftrace_unreg_event_<call>,
|
* .unregfunc = ftrace_unreg_event_<call>,
|
||||||
* .show_format = ftrace_format_<call>,
|
* .show_format = ftrace_format_<call>,
|
||||||
@@ -647,13 +626,9 @@ static void ftrace_profile_disable_##name(struct ftrace_event_call *unused)\
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#undef TP_FMT
|
|
||||||
#define TP_FMT(fmt, args...) fmt "\n", ##args
|
|
||||||
|
|
||||||
#ifdef CONFIG_EVENT_PROFILE
|
#ifdef CONFIG_EVENT_PROFILE
|
||||||
|
|
||||||
#define _TRACE_PROFILE_INIT(call) \
|
#define _TRACE_PROFILE_INIT(call) \
|
||||||
.profile_count = ATOMIC_INIT(-1), \
|
|
||||||
.profile_enable = ftrace_profile_enable_##call, \
|
.profile_enable = ftrace_profile_enable_##call, \
|
||||||
.profile_disable = ftrace_profile_disable_##call,
|
.profile_disable = ftrace_profile_disable_##call,
|
||||||
|
|
||||||
@@ -728,13 +703,7 @@ static void ftrace_raw_event_##call(proto) \
|
|||||||
\
|
\
|
||||||
static int ftrace_raw_reg_event_##call(struct ftrace_event_call *unused)\
|
static int ftrace_raw_reg_event_##call(struct ftrace_event_call *unused)\
|
||||||
{ \
|
{ \
|
||||||
int ret; \
|
return register_trace_##call(ftrace_raw_event_##call); \
|
||||||
\
|
|
||||||
ret = register_trace_##call(ftrace_raw_event_##call); \
|
|
||||||
if (ret) \
|
|
||||||
pr_info("event trace: Could not activate trace point " \
|
|
||||||
"probe to " #call "\n"); \
|
|
||||||
return ret; \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static void ftrace_raw_unreg_event_##call(struct ftrace_event_call *unused)\
|
static void ftrace_raw_unreg_event_##call(struct ftrace_event_call *unused)\
|
||||||
@@ -744,19 +713,7 @@ static void ftrace_raw_unreg_event_##call(struct ftrace_event_call *unused)\
|
|||||||
\
|
\
|
||||||
static struct trace_event ftrace_event_type_##call = { \
|
static struct trace_event ftrace_event_type_##call = { \
|
||||||
.trace = ftrace_raw_output_##call, \
|
.trace = ftrace_raw_output_##call, \
|
||||||
}; \
|
};
|
||||||
\
|
|
||||||
static int ftrace_raw_init_event_##call(struct ftrace_event_call *unused)\
|
|
||||||
{ \
|
|
||||||
int id; \
|
|
||||||
\
|
|
||||||
id = register_ftrace_event(&ftrace_event_type_##call); \
|
|
||||||
if (!id) \
|
|
||||||
return -ENODEV; \
|
|
||||||
event_##call.id = id; \
|
|
||||||
INIT_LIST_HEAD(&event_##call.fields); \
|
|
||||||
return 0; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef DEFINE_EVENT_PRINT
|
#undef DEFINE_EVENT_PRINT
|
||||||
#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
|
#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
|
||||||
@@ -776,7 +733,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
|
|||||||
.name = #call, \
|
.name = #call, \
|
||||||
.system = __stringify(TRACE_SYSTEM), \
|
.system = __stringify(TRACE_SYSTEM), \
|
||||||
.event = &ftrace_event_type_##call, \
|
.event = &ftrace_event_type_##call, \
|
||||||
.raw_init = ftrace_raw_init_event_##call, \
|
.raw_init = trace_event_raw_init, \
|
||||||
.regfunc = ftrace_raw_reg_event_##call, \
|
.regfunc = ftrace_raw_reg_event_##call, \
|
||||||
.unregfunc = ftrace_raw_unreg_event_##call, \
|
.unregfunc = ftrace_raw_unreg_event_##call, \
|
||||||
.show_format = ftrace_format_##template, \
|
.show_format = ftrace_format_##template, \
|
||||||
@@ -793,7 +750,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
|
|||||||
.name = #call, \
|
.name = #call, \
|
||||||
.system = __stringify(TRACE_SYSTEM), \
|
.system = __stringify(TRACE_SYSTEM), \
|
||||||
.event = &ftrace_event_type_##call, \
|
.event = &ftrace_event_type_##call, \
|
||||||
.raw_init = ftrace_raw_init_event_##call, \
|
.raw_init = trace_event_raw_init, \
|
||||||
.regfunc = ftrace_raw_reg_event_##call, \
|
.regfunc = ftrace_raw_reg_event_##call, \
|
||||||
.unregfunc = ftrace_raw_unreg_event_##call, \
|
.unregfunc = ftrace_raw_unreg_event_##call, \
|
||||||
.show_format = ftrace_format_##call, \
|
.show_format = ftrace_format_##call, \
|
||||||
@@ -953,7 +910,6 @@ end: \
|
|||||||
perf_swevent_put_recursion_context(rctx); \
|
perf_swevent_put_recursion_context(rctx); \
|
||||||
end_recursion: \
|
end_recursion: \
|
||||||
local_irq_restore(irq_flags); \
|
local_irq_restore(irq_flags); \
|
||||||
\
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef DEFINE_EVENT
|
#undef DEFINE_EVENT
|
||||||
|
@@ -1724,7 +1724,7 @@ ftrace_match_record(struct dyn_ftrace *rec, char *regex, int len, int type)
|
|||||||
return ftrace_match(str, regex, len, type);
|
return ftrace_match(str, regex, len, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ftrace_match_records(char *buff, int len, int enable)
|
static int ftrace_match_records(char *buff, int len, int enable)
|
||||||
{
|
{
|
||||||
unsigned int search_len;
|
unsigned int search_len;
|
||||||
struct ftrace_page *pg;
|
struct ftrace_page *pg;
|
||||||
@@ -1733,6 +1733,7 @@ static void ftrace_match_records(char *buff, int len, int enable)
|
|||||||
char *search;
|
char *search;
|
||||||
int type;
|
int type;
|
||||||
int not;
|
int not;
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
|
flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
|
||||||
type = filter_parse_regex(buff, len, &search, ¬);
|
type = filter_parse_regex(buff, len, &search, ¬);
|
||||||
@@ -1750,6 +1751,7 @@ static void ftrace_match_records(char *buff, int len, int enable)
|
|||||||
rec->flags &= ~flag;
|
rec->flags &= ~flag;
|
||||||
else
|
else
|
||||||
rec->flags |= flag;
|
rec->flags |= flag;
|
||||||
|
found = 1;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Only enable filtering if we have a function that
|
* Only enable filtering if we have a function that
|
||||||
@@ -1759,6 +1761,8 @@ static void ftrace_match_records(char *buff, int len, int enable)
|
|||||||
ftrace_filtered = 1;
|
ftrace_filtered = 1;
|
||||||
} while_for_each_ftrace_rec();
|
} while_for_each_ftrace_rec();
|
||||||
mutex_unlock(&ftrace_lock);
|
mutex_unlock(&ftrace_lock);
|
||||||
|
|
||||||
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -1780,7 +1784,7 @@ ftrace_match_module_record(struct dyn_ftrace *rec, char *mod,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ftrace_match_module_records(char *buff, char *mod, int enable)
|
static int ftrace_match_module_records(char *buff, char *mod, int enable)
|
||||||
{
|
{
|
||||||
unsigned search_len = 0;
|
unsigned search_len = 0;
|
||||||
struct ftrace_page *pg;
|
struct ftrace_page *pg;
|
||||||
@@ -1789,6 +1793,7 @@ static void ftrace_match_module_records(char *buff, char *mod, int enable)
|
|||||||
char *search = buff;
|
char *search = buff;
|
||||||
unsigned long flag;
|
unsigned long flag;
|
||||||
int not = 0;
|
int not = 0;
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
|
flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
|
||||||
|
|
||||||
@@ -1819,12 +1824,15 @@ static void ftrace_match_module_records(char *buff, char *mod, int enable)
|
|||||||
rec->flags &= ~flag;
|
rec->flags &= ~flag;
|
||||||
else
|
else
|
||||||
rec->flags |= flag;
|
rec->flags |= flag;
|
||||||
|
found = 1;
|
||||||
}
|
}
|
||||||
if (enable && (rec->flags & FTRACE_FL_FILTER))
|
if (enable && (rec->flags & FTRACE_FL_FILTER))
|
||||||
ftrace_filtered = 1;
|
ftrace_filtered = 1;
|
||||||
|
|
||||||
} while_for_each_ftrace_rec();
|
} while_for_each_ftrace_rec();
|
||||||
mutex_unlock(&ftrace_lock);
|
mutex_unlock(&ftrace_lock);
|
||||||
|
|
||||||
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1853,8 +1861,9 @@ ftrace_mod_callback(char *func, char *cmd, char *param, int enable)
|
|||||||
if (!strlen(mod))
|
if (!strlen(mod))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
ftrace_match_module_records(func, mod, enable);
|
if (ftrace_match_module_records(func, mod, enable))
|
||||||
return 0;
|
return 0;
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ftrace_func_command ftrace_mod_cmd = {
|
static struct ftrace_func_command ftrace_mod_cmd = {
|
||||||
@@ -2151,8 +2160,9 @@ static int ftrace_process_regex(char *buff, int len, int enable)
|
|||||||
func = strsep(&next, ":");
|
func = strsep(&next, ":");
|
||||||
|
|
||||||
if (!next) {
|
if (!next) {
|
||||||
ftrace_match_records(func, len, enable);
|
if (ftrace_match_records(func, len, enable))
|
||||||
return 0;
|
return 0;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* command found */
|
/* command found */
|
||||||
@@ -2198,10 +2208,9 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
|
|||||||
!trace_parser_cont(parser)) {
|
!trace_parser_cont(parser)) {
|
||||||
ret = ftrace_process_regex(parser->buffer,
|
ret = ftrace_process_regex(parser->buffer,
|
||||||
parser->idx, enable);
|
parser->idx, enable);
|
||||||
|
trace_parser_clear(parser);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
trace_parser_clear(parser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = read;
|
ret = read;
|
||||||
@@ -2543,10 +2552,9 @@ ftrace_set_func(unsigned long *array, int *idx, char *buffer)
|
|||||||
exists = true;
|
exists = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!exists) {
|
if (!exists)
|
||||||
array[(*idx)++] = rec->ip;
|
array[(*idx)++] = rec->ip;
|
||||||
found = 1;
|
found = 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} while_for_each_ftrace_rec();
|
} while_for_each_ftrace_rec();
|
||||||
|
|
||||||
|
@@ -14,7 +14,5 @@
|
|||||||
#define CREATE_TRACE_POINTS
|
#define CREATE_TRACE_POINTS
|
||||||
#include <trace/events/power.h>
|
#include <trace/events/power.h>
|
||||||
|
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(power_start);
|
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(power_end);
|
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(power_frequency);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(power_frequency);
|
||||||
|
|
||||||
|
@@ -1193,9 +1193,6 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned nr_pages)
|
|||||||
struct list_head *p;
|
struct list_head *p;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
atomic_inc(&cpu_buffer->record_disabled);
|
|
||||||
synchronize_sched();
|
|
||||||
|
|
||||||
spin_lock_irq(&cpu_buffer->reader_lock);
|
spin_lock_irq(&cpu_buffer->reader_lock);
|
||||||
rb_head_page_deactivate(cpu_buffer);
|
rb_head_page_deactivate(cpu_buffer);
|
||||||
|
|
||||||
@@ -1211,12 +1208,9 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned nr_pages)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
rb_reset_cpu(cpu_buffer);
|
rb_reset_cpu(cpu_buffer);
|
||||||
spin_unlock_irq(&cpu_buffer->reader_lock);
|
|
||||||
|
|
||||||
rb_check_pages(cpu_buffer);
|
rb_check_pages(cpu_buffer);
|
||||||
|
|
||||||
atomic_dec(&cpu_buffer->record_disabled);
|
spin_unlock_irq(&cpu_buffer->reader_lock);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1227,9 +1221,6 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer,
|
|||||||
struct list_head *p;
|
struct list_head *p;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
atomic_inc(&cpu_buffer->record_disabled);
|
|
||||||
synchronize_sched();
|
|
||||||
|
|
||||||
spin_lock_irq(&cpu_buffer->reader_lock);
|
spin_lock_irq(&cpu_buffer->reader_lock);
|
||||||
rb_head_page_deactivate(cpu_buffer);
|
rb_head_page_deactivate(cpu_buffer);
|
||||||
|
|
||||||
@@ -1242,11 +1233,9 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer,
|
|||||||
list_add_tail(&bpage->list, cpu_buffer->pages);
|
list_add_tail(&bpage->list, cpu_buffer->pages);
|
||||||
}
|
}
|
||||||
rb_reset_cpu(cpu_buffer);
|
rb_reset_cpu(cpu_buffer);
|
||||||
spin_unlock_irq(&cpu_buffer->reader_lock);
|
|
||||||
|
|
||||||
rb_check_pages(cpu_buffer);
|
rb_check_pages(cpu_buffer);
|
||||||
|
|
||||||
atomic_dec(&cpu_buffer->record_disabled);
|
spin_unlock_irq(&cpu_buffer->reader_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1254,11 +1243,6 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer,
|
|||||||
* @buffer: the buffer to resize.
|
* @buffer: the buffer to resize.
|
||||||
* @size: the new size.
|
* @size: the new size.
|
||||||
*
|
*
|
||||||
* The tracer is responsible for making sure that the buffer is
|
|
||||||
* not being used while changing the size.
|
|
||||||
* Note: We may be able to change the above requirement by using
|
|
||||||
* RCU synchronizations.
|
|
||||||
*
|
|
||||||
* Minimum size is 2 * BUF_PAGE_SIZE.
|
* Minimum size is 2 * BUF_PAGE_SIZE.
|
||||||
*
|
*
|
||||||
* Returns -1 on failure.
|
* Returns -1 on failure.
|
||||||
@@ -1290,6 +1274,11 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size)
|
|||||||
if (size == buffer_size)
|
if (size == buffer_size)
|
||||||
return size;
|
return size;
|
||||||
|
|
||||||
|
atomic_inc(&buffer->record_disabled);
|
||||||
|
|
||||||
|
/* Make sure all writers are done with this buffer. */
|
||||||
|
synchronize_sched();
|
||||||
|
|
||||||
mutex_lock(&buffer->mutex);
|
mutex_lock(&buffer->mutex);
|
||||||
get_online_cpus();
|
get_online_cpus();
|
||||||
|
|
||||||
@@ -1352,6 +1341,8 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size)
|
|||||||
put_online_cpus();
|
put_online_cpus();
|
||||||
mutex_unlock(&buffer->mutex);
|
mutex_unlock(&buffer->mutex);
|
||||||
|
|
||||||
|
atomic_dec(&buffer->record_disabled);
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
|
|
||||||
free_pages:
|
free_pages:
|
||||||
@@ -1361,6 +1352,7 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size)
|
|||||||
}
|
}
|
||||||
put_online_cpus();
|
put_online_cpus();
|
||||||
mutex_unlock(&buffer->mutex);
|
mutex_unlock(&buffer->mutex);
|
||||||
|
atomic_dec(&buffer->record_disabled);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1370,6 +1362,7 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size)
|
|||||||
out_fail:
|
out_fail:
|
||||||
put_online_cpus();
|
put_online_cpus();
|
||||||
mutex_unlock(&buffer->mutex);
|
mutex_unlock(&buffer->mutex);
|
||||||
|
atomic_dec(&buffer->record_disabled);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(ring_buffer_resize);
|
EXPORT_SYMBOL_GPL(ring_buffer_resize);
|
||||||
|
@@ -313,7 +313,6 @@ static const char *trace_options[] = {
|
|||||||
"bin",
|
"bin",
|
||||||
"block",
|
"block",
|
||||||
"stacktrace",
|
"stacktrace",
|
||||||
"sched-tree",
|
|
||||||
"trace_printk",
|
"trace_printk",
|
||||||
"ftrace_preempt",
|
"ftrace_preempt",
|
||||||
"branch",
|
"branch",
|
||||||
@@ -1151,6 +1150,22 @@ void __trace_stack(struct trace_array *tr, unsigned long flags, int skip,
|
|||||||
__ftrace_trace_stack(tr->buffer, flags, skip, pc);
|
__ftrace_trace_stack(tr->buffer, flags, skip, pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* trace_dump_stack - record a stack back trace in the trace buffer
|
||||||
|
*/
|
||||||
|
void trace_dump_stack(void)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (tracing_disabled || tracing_selftest_running)
|
||||||
|
return;
|
||||||
|
|
||||||
|
local_save_flags(flags);
|
||||||
|
|
||||||
|
/* skipping 3 traces, seems to get us at the caller of this function */
|
||||||
|
__ftrace_trace_stack(global_trace.buffer, flags, 3, preempt_count());
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc)
|
ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc)
|
||||||
{
|
{
|
||||||
@@ -2316,92 +2331,41 @@ static const struct file_operations tracing_cpumask_fops = {
|
|||||||
.write = tracing_cpumask_write,
|
.write = tracing_cpumask_write,
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t
|
static int tracing_trace_options_show(struct seq_file *m, void *v)
|
||||||
tracing_trace_options_read(struct file *filp, char __user *ubuf,
|
|
||||||
size_t cnt, loff_t *ppos)
|
|
||||||
{
|
{
|
||||||
struct tracer_opt *trace_opts;
|
struct tracer_opt *trace_opts;
|
||||||
u32 tracer_flags;
|
u32 tracer_flags;
|
||||||
int len = 0;
|
|
||||||
char *buf;
|
|
||||||
int r = 0;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
||||||
/* calculate max size */
|
|
||||||
for (i = 0; trace_options[i]; i++) {
|
|
||||||
len += strlen(trace_options[i]);
|
|
||||||
len += 3; /* "no" and newline */
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_lock(&trace_types_lock);
|
mutex_lock(&trace_types_lock);
|
||||||
tracer_flags = current_trace->flags->val;
|
tracer_flags = current_trace->flags->val;
|
||||||
trace_opts = current_trace->flags->opts;
|
trace_opts = current_trace->flags->opts;
|
||||||
|
|
||||||
/*
|
|
||||||
* Increase the size with names of options specific
|
|
||||||
* of the current tracer.
|
|
||||||
*/
|
|
||||||
for (i = 0; trace_opts[i].name; i++) {
|
|
||||||
len += strlen(trace_opts[i].name);
|
|
||||||
len += 3; /* "no" and newline */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* +1 for \0 */
|
|
||||||
buf = kmalloc(len + 1, GFP_KERNEL);
|
|
||||||
if (!buf) {
|
|
||||||
mutex_unlock(&trace_types_lock);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; trace_options[i]; i++) {
|
for (i = 0; trace_options[i]; i++) {
|
||||||
if (trace_flags & (1 << i))
|
if (trace_flags & (1 << i))
|
||||||
r += sprintf(buf + r, "%s\n", trace_options[i]);
|
seq_printf(m, "%s\n", trace_options[i]);
|
||||||
else
|
else
|
||||||
r += sprintf(buf + r, "no%s\n", trace_options[i]);
|
seq_printf(m, "no%s\n", trace_options[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; trace_opts[i].name; i++) {
|
for (i = 0; trace_opts[i].name; i++) {
|
||||||
if (tracer_flags & trace_opts[i].bit)
|
if (tracer_flags & trace_opts[i].bit)
|
||||||
r += sprintf(buf + r, "%s\n",
|
seq_printf(m, "%s\n", trace_opts[i].name);
|
||||||
trace_opts[i].name);
|
|
||||||
else
|
else
|
||||||
r += sprintf(buf + r, "no%s\n",
|
seq_printf(m, "no%s\n", trace_opts[i].name);
|
||||||
trace_opts[i].name);
|
|
||||||
}
|
}
|
||||||
mutex_unlock(&trace_types_lock);
|
mutex_unlock(&trace_types_lock);
|
||||||
|
|
||||||
WARN_ON(r >= len + 1);
|
return 0;
|
||||||
|
|
||||||
r = simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
|
|
||||||
|
|
||||||
kfree(buf);
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to assign a tracer specific option */
|
static int __set_tracer_option(struct tracer *trace,
|
||||||
static int set_tracer_option(struct tracer *trace, char *cmp, int neg)
|
struct tracer_flags *tracer_flags,
|
||||||
|
struct tracer_opt *opts, int neg)
|
||||||
{
|
{
|
||||||
struct tracer_flags *tracer_flags = trace->flags;
|
int ret;
|
||||||
struct tracer_opt *opts = NULL;
|
|
||||||
int ret = 0, i = 0;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
for (i = 0; tracer_flags->opts[i].name; i++) {
|
ret = trace->set_flag(tracer_flags->val, opts->bit, !neg);
|
||||||
opts = &tracer_flags->opts[i];
|
|
||||||
len = strlen(opts->name);
|
|
||||||
|
|
||||||
if (strncmp(cmp, opts->name, len) == 0) {
|
|
||||||
ret = trace->set_flag(tracer_flags->val,
|
|
||||||
opts->bit, !neg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Not found */
|
|
||||||
if (!tracer_flags->opts[i].name)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/* Refused to handle */
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -2409,10 +2373,27 @@ static int set_tracer_option(struct tracer *trace, char *cmp, int neg)
|
|||||||
tracer_flags->val &= ~opts->bit;
|
tracer_flags->val &= ~opts->bit;
|
||||||
else
|
else
|
||||||
tracer_flags->val |= opts->bit;
|
tracer_flags->val |= opts->bit;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Try to assign a tracer specific option */
|
||||||
|
static int set_tracer_option(struct tracer *trace, char *cmp, int neg)
|
||||||
|
{
|
||||||
|
struct tracer_flags *tracer_flags = trace->flags;
|
||||||
|
struct tracer_opt *opts = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; tracer_flags->opts[i].name; i++) {
|
||||||
|
opts = &tracer_flags->opts[i];
|
||||||
|
|
||||||
|
if (strcmp(cmp, opts->name) == 0)
|
||||||
|
return __set_tracer_option(trace, trace->flags,
|
||||||
|
opts, neg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
static void set_tracer_flags(unsigned int mask, int enabled)
|
static void set_tracer_flags(unsigned int mask, int enabled)
|
||||||
{
|
{
|
||||||
/* do nothing if flag is already set */
|
/* do nothing if flag is already set */
|
||||||
@@ -2430,7 +2411,7 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf,
|
|||||||
size_t cnt, loff_t *ppos)
|
size_t cnt, loff_t *ppos)
|
||||||
{
|
{
|
||||||
char buf[64];
|
char buf[64];
|
||||||
char *cmp = buf;
|
char *cmp;
|
||||||
int neg = 0;
|
int neg = 0;
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
@@ -2442,16 +2423,15 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf,
|
|||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
buf[cnt] = 0;
|
buf[cnt] = 0;
|
||||||
|
cmp = strstrip(buf);
|
||||||
|
|
||||||
if (strncmp(buf, "no", 2) == 0) {
|
if (strncmp(cmp, "no", 2) == 0) {
|
||||||
neg = 1;
|
neg = 1;
|
||||||
cmp += 2;
|
cmp += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; trace_options[i]; i++) {
|
for (i = 0; trace_options[i]; i++) {
|
||||||
int len = strlen(trace_options[i]);
|
if (strcmp(cmp, trace_options[i]) == 0) {
|
||||||
|
|
||||||
if (strncmp(cmp, trace_options[i], len) == 0) {
|
|
||||||
set_tracer_flags(1 << i, !neg);
|
set_tracer_flags(1 << i, !neg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2471,9 +2451,18 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf,
|
|||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tracing_trace_options_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
if (tracing_disabled)
|
||||||
|
return -ENODEV;
|
||||||
|
return single_open(file, tracing_trace_options_show, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct file_operations tracing_iter_fops = {
|
static const struct file_operations tracing_iter_fops = {
|
||||||
.open = tracing_open_generic,
|
.open = tracing_trace_options_open,
|
||||||
.read = tracing_trace_options_read,
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
.write = tracing_trace_options_write,
|
.write = tracing_trace_options_write,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3392,21 +3381,18 @@ tracing_mark_write(struct file *filp, const char __user *ubuf,
|
|||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t tracing_clock_read(struct file *filp, char __user *ubuf,
|
static int tracing_clock_show(struct seq_file *m, void *v)
|
||||||
size_t cnt, loff_t *ppos)
|
|
||||||
{
|
{
|
||||||
char buf[64];
|
|
||||||
int bufiter = 0;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(trace_clocks); i++)
|
for (i = 0; i < ARRAY_SIZE(trace_clocks); i++)
|
||||||
bufiter += snprintf(buf + bufiter, sizeof(buf) - bufiter,
|
seq_printf(m,
|
||||||
"%s%s%s%s", i ? " " : "",
|
"%s%s%s%s", i ? " " : "",
|
||||||
i == trace_clock_id ? "[" : "", trace_clocks[i].name,
|
i == trace_clock_id ? "[" : "", trace_clocks[i].name,
|
||||||
i == trace_clock_id ? "]" : "");
|
i == trace_clock_id ? "]" : "");
|
||||||
bufiter += snprintf(buf + bufiter, sizeof(buf) - bufiter, "\n");
|
seq_putc(m, '\n');
|
||||||
|
|
||||||
return simple_read_from_buffer(ubuf, cnt, ppos, buf, bufiter);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf,
|
static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf,
|
||||||
@@ -3448,6 +3434,13 @@ static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf,
|
|||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tracing_clock_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
if (tracing_disabled)
|
||||||
|
return -ENODEV;
|
||||||
|
return single_open(file, tracing_clock_show, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct file_operations tracing_max_lat_fops = {
|
static const struct file_operations tracing_max_lat_fops = {
|
||||||
.open = tracing_open_generic,
|
.open = tracing_open_generic,
|
||||||
.read = tracing_max_lat_read,
|
.read = tracing_max_lat_read,
|
||||||
@@ -3486,8 +3479,10 @@ static const struct file_operations tracing_mark_fops = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct file_operations trace_clock_fops = {
|
static const struct file_operations trace_clock_fops = {
|
||||||
.open = tracing_open_generic,
|
.open = tracing_clock_open,
|
||||||
.read = tracing_clock_read,
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
.write = tracing_clock_write,
|
.write = tracing_clock_write,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3948,39 +3943,16 @@ trace_options_write(struct file *filp, const char __user *ubuf, size_t cnt,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = 0;
|
if (val != 0 && val != 1)
|
||||||
switch (val) {
|
|
||||||
case 0:
|
|
||||||
/* do nothing if already cleared */
|
|
||||||
if (!(topt->flags->val & topt->opt->bit))
|
|
||||||
break;
|
|
||||||
|
|
||||||
mutex_lock(&trace_types_lock);
|
|
||||||
if (current_trace->set_flag)
|
|
||||||
ret = current_trace->set_flag(topt->flags->val,
|
|
||||||
topt->opt->bit, 0);
|
|
||||||
mutex_unlock(&trace_types_lock);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
topt->flags->val &= ~topt->opt->bit;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
/* do nothing if already set */
|
|
||||||
if (topt->flags->val & topt->opt->bit)
|
|
||||||
break;
|
|
||||||
|
|
||||||
mutex_lock(&trace_types_lock);
|
|
||||||
if (current_trace->set_flag)
|
|
||||||
ret = current_trace->set_flag(topt->flags->val,
|
|
||||||
topt->opt->bit, 1);
|
|
||||||
mutex_unlock(&trace_types_lock);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
topt->flags->val |= topt->opt->bit;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!!(topt->flags->val & topt->opt->bit) != val) {
|
||||||
|
mutex_lock(&trace_types_lock);
|
||||||
|
ret = __set_tracer_option(current_trace, topt->flags,
|
||||||
|
topt->opt, val);
|
||||||
|
mutex_unlock(&trace_types_lock);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
*ppos += cnt;
|
*ppos += cnt;
|
||||||
|
@@ -597,18 +597,17 @@ enum trace_iterator_flags {
|
|||||||
TRACE_ITER_BIN = 0x40,
|
TRACE_ITER_BIN = 0x40,
|
||||||
TRACE_ITER_BLOCK = 0x80,
|
TRACE_ITER_BLOCK = 0x80,
|
||||||
TRACE_ITER_STACKTRACE = 0x100,
|
TRACE_ITER_STACKTRACE = 0x100,
|
||||||
TRACE_ITER_SCHED_TREE = 0x200,
|
TRACE_ITER_PRINTK = 0x200,
|
||||||
TRACE_ITER_PRINTK = 0x400,
|
TRACE_ITER_PREEMPTONLY = 0x400,
|
||||||
TRACE_ITER_PREEMPTONLY = 0x800,
|
TRACE_ITER_BRANCH = 0x800,
|
||||||
TRACE_ITER_BRANCH = 0x1000,
|
TRACE_ITER_ANNOTATE = 0x1000,
|
||||||
TRACE_ITER_ANNOTATE = 0x2000,
|
TRACE_ITER_USERSTACKTRACE = 0x2000,
|
||||||
TRACE_ITER_USERSTACKTRACE = 0x4000,
|
TRACE_ITER_SYM_USEROBJ = 0x4000,
|
||||||
TRACE_ITER_SYM_USEROBJ = 0x8000,
|
TRACE_ITER_PRINTK_MSGONLY = 0x8000,
|
||||||
TRACE_ITER_PRINTK_MSGONLY = 0x10000,
|
TRACE_ITER_CONTEXT_INFO = 0x10000, /* Print pid/cpu/time */
|
||||||
TRACE_ITER_CONTEXT_INFO = 0x20000, /* Print pid/cpu/time */
|
TRACE_ITER_LATENCY_FMT = 0x20000,
|
||||||
TRACE_ITER_LATENCY_FMT = 0x40000,
|
TRACE_ITER_SLEEP_TIME = 0x40000,
|
||||||
TRACE_ITER_SLEEP_TIME = 0x80000,
|
TRACE_ITER_GRAPH_TIME = 0x80000,
|
||||||
TRACE_ITER_GRAPH_TIME = 0x100000,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -25,7 +25,7 @@ static int ftrace_profile_enable_event(struct ftrace_event_call *event)
|
|||||||
char *buf;
|
char *buf;
|
||||||
int ret = -ENOMEM;
|
int ret = -ENOMEM;
|
||||||
|
|
||||||
if (atomic_inc_return(&event->profile_count))
|
if (event->profile_count++ > 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!total_profile_count) {
|
if (!total_profile_count) {
|
||||||
@@ -56,7 +56,7 @@ fail_buf_nmi:
|
|||||||
perf_trace_buf = NULL;
|
perf_trace_buf = NULL;
|
||||||
}
|
}
|
||||||
fail_buf:
|
fail_buf:
|
||||||
atomic_dec(&event->profile_count);
|
event->profile_count--;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -83,7 +83,7 @@ static void ftrace_profile_disable_event(struct ftrace_event_call *event)
|
|||||||
{
|
{
|
||||||
char *buf, *nmi_buf;
|
char *buf, *nmi_buf;
|
||||||
|
|
||||||
if (!atomic_add_negative(-1, &event->profile_count))
|
if (--event->profile_count > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
event->profile_disable(event);
|
event->profile_disable(event);
|
||||||
|
@@ -78,7 +78,7 @@ EXPORT_SYMBOL_GPL(trace_define_field);
|
|||||||
if (ret) \
|
if (ret) \
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
int trace_define_common_fields(struct ftrace_event_call *call)
|
static int trace_define_common_fields(struct ftrace_event_call *call)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct trace_entry ent;
|
struct trace_entry ent;
|
||||||
@@ -91,7 +91,6 @@ int trace_define_common_fields(struct ftrace_event_call *call)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(trace_define_common_fields);
|
|
||||||
|
|
||||||
void trace_destroy_fields(struct ftrace_event_call *call)
|
void trace_destroy_fields(struct ftrace_event_call *call)
|
||||||
{
|
{
|
||||||
@@ -105,9 +104,25 @@ void trace_destroy_fields(struct ftrace_event_call *call)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ftrace_event_enable_disable(struct ftrace_event_call *call,
|
int trace_event_raw_init(struct ftrace_event_call *call)
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
|
||||||
|
id = register_ftrace_event(call->event);
|
||||||
|
if (!id)
|
||||||
|
return -ENODEV;
|
||||||
|
call->id = id;
|
||||||
|
INIT_LIST_HEAD(&call->fields);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(trace_event_raw_init);
|
||||||
|
|
||||||
|
static int ftrace_event_enable_disable(struct ftrace_event_call *call,
|
||||||
int enable)
|
int enable)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
switch (enable) {
|
switch (enable) {
|
||||||
case 0:
|
case 0:
|
||||||
if (call->enabled) {
|
if (call->enabled) {
|
||||||
@@ -118,12 +133,20 @@ static void ftrace_event_enable_disable(struct ftrace_event_call *call,
|
|||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if (!call->enabled) {
|
if (!call->enabled) {
|
||||||
call->enabled = 1;
|
|
||||||
tracing_start_cmdline_record();
|
tracing_start_cmdline_record();
|
||||||
call->regfunc(call);
|
ret = call->regfunc(call);
|
||||||
|
if (ret) {
|
||||||
|
tracing_stop_cmdline_record();
|
||||||
|
pr_info("event trace: Could not enable event "
|
||||||
|
"%s\n", call->name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
call->enabled = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ftrace_clear_events(void)
|
static void ftrace_clear_events(void)
|
||||||
@@ -402,7 +425,7 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
|
|||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
mutex_lock(&event_mutex);
|
mutex_lock(&event_mutex);
|
||||||
ftrace_event_enable_disable(call, val);
|
ret = ftrace_event_enable_disable(call, val);
|
||||||
mutex_unlock(&event_mutex);
|
mutex_unlock(&event_mutex);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -412,7 +435,7 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
|
|||||||
|
|
||||||
*ppos += cnt;
|
*ppos += cnt;
|
||||||
|
|
||||||
return cnt;
|
return ret ? ret : cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
@@ -913,7 +936,9 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
|
|||||||
id);
|
id);
|
||||||
|
|
||||||
if (call->define_fields) {
|
if (call->define_fields) {
|
||||||
ret = call->define_fields(call);
|
ret = trace_define_common_fields(call);
|
||||||
|
if (!ret)
|
||||||
|
ret = call->define_fields(call);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pr_warning("Could not initialize trace point"
|
pr_warning("Could not initialize trace point"
|
||||||
" events/%s\n", call->name);
|
" events/%s\n", call->name);
|
||||||
|
@@ -184,10 +184,6 @@ ftrace_define_fields_##name(struct ftrace_event_call *event_call) \
|
|||||||
struct struct_name field; \
|
struct struct_name field; \
|
||||||
int ret; \
|
int ret; \
|
||||||
\
|
\
|
||||||
ret = trace_define_common_fields(event_call); \
|
|
||||||
if (ret) \
|
|
||||||
return ret; \
|
|
||||||
\
|
|
||||||
tstruct; \
|
tstruct; \
|
||||||
\
|
\
|
||||||
return ret; \
|
return ret; \
|
||||||
|
@@ -151,6 +151,8 @@ check_critical_timing(struct trace_array *tr,
|
|||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc);
|
trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc);
|
||||||
|
/* Skip 5 functions to get to the irq/preempt enable function */
|
||||||
|
__trace_stack(tr, flags, 5, pc);
|
||||||
|
|
||||||
if (data->critical_sequence != max_sequence)
|
if (data->critical_sequence != max_sequence)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
@@ -1132,10 +1132,6 @@ static int kprobe_event_define_fields(struct ftrace_event_call *event_call)
|
|||||||
struct kprobe_trace_entry field;
|
struct kprobe_trace_entry field;
|
||||||
struct trace_probe *tp = (struct trace_probe *)event_call->data;
|
struct trace_probe *tp = (struct trace_probe *)event_call->data;
|
||||||
|
|
||||||
ret = trace_define_common_fields(event_call);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0);
|
DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0);
|
||||||
DEFINE_FIELD(int, nargs, FIELD_STRING_NARGS, 1);
|
DEFINE_FIELD(int, nargs, FIELD_STRING_NARGS, 1);
|
||||||
/* Set argument names as fields */
|
/* Set argument names as fields */
|
||||||
@@ -1150,10 +1146,6 @@ static int kretprobe_event_define_fields(struct ftrace_event_call *event_call)
|
|||||||
struct kretprobe_trace_entry field;
|
struct kretprobe_trace_entry field;
|
||||||
struct trace_probe *tp = (struct trace_probe *)event_call->data;
|
struct trace_probe *tp = (struct trace_probe *)event_call->data;
|
||||||
|
|
||||||
ret = trace_define_common_fields(event_call);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
DEFINE_FIELD(unsigned long, func, FIELD_STRING_FUNC, 0);
|
DEFINE_FIELD(unsigned long, func, FIELD_STRING_FUNC, 0);
|
||||||
DEFINE_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP, 0);
|
DEFINE_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP, 0);
|
||||||
DEFINE_FIELD(int, nargs, FIELD_STRING_NARGS, 1);
|
DEFINE_FIELD(int, nargs, FIELD_STRING_NARGS, 1);
|
||||||
@@ -1453,7 +1445,6 @@ static int register_probe_event(struct trace_probe *tp)
|
|||||||
call->unregfunc = probe_event_disable;
|
call->unregfunc = probe_event_disable;
|
||||||
|
|
||||||
#ifdef CONFIG_EVENT_PROFILE
|
#ifdef CONFIG_EVENT_PROFILE
|
||||||
atomic_set(&call->profile_count, -1);
|
|
||||||
call->profile_enable = probe_profile_enable;
|
call->profile_enable = probe_profile_enable;
|
||||||
call->profile_disable = probe_profile_disable;
|
call->profile_disable = probe_profile_disable;
|
||||||
#endif
|
#endif
|
||||||
|
@@ -236,7 +236,8 @@ static ssize_t ksym_trace_filter_read(struct file *filp, char __user *ubuf,
|
|||||||
mutex_lock(&ksym_tracer_mutex);
|
mutex_lock(&ksym_tracer_mutex);
|
||||||
|
|
||||||
hlist_for_each_entry(entry, node, &ksym_filter_head, ksym_hlist) {
|
hlist_for_each_entry(entry, node, &ksym_filter_head, ksym_hlist) {
|
||||||
ret = trace_seq_printf(s, "%pS:", (void *)entry->attr.bp_addr);
|
ret = trace_seq_printf(s, "%pS:",
|
||||||
|
(void *)(unsigned long)entry->attr.bp_addr);
|
||||||
if (entry->attr.bp_type == HW_BREAKPOINT_R)
|
if (entry->attr.bp_type == HW_BREAKPOINT_R)
|
||||||
ret = trace_seq_puts(s, "r--\n");
|
ret = trace_seq_puts(s, "r--\n");
|
||||||
else if (entry->attr.bp_type == HW_BREAKPOINT_W)
|
else if (entry->attr.bp_type == HW_BREAKPOINT_W)
|
||||||
@@ -278,21 +279,20 @@ static ssize_t ksym_trace_filter_write(struct file *file,
|
|||||||
{
|
{
|
||||||
struct trace_ksym *entry;
|
struct trace_ksym *entry;
|
||||||
struct hlist_node *node;
|
struct hlist_node *node;
|
||||||
char *input_string, *ksymname = NULL;
|
char *buf, *input_string, *ksymname = NULL;
|
||||||
unsigned long ksym_addr = 0;
|
unsigned long ksym_addr = 0;
|
||||||
int ret, op, changed = 0;
|
int ret, op, changed = 0;
|
||||||
|
|
||||||
input_string = kzalloc(count + 1, GFP_KERNEL);
|
buf = kzalloc(count + 1, GFP_KERNEL);
|
||||||
if (!input_string)
|
if (!buf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (copy_from_user(input_string, buffer, count)) {
|
ret = -EFAULT;
|
||||||
kfree(input_string);
|
if (copy_from_user(buf, buffer, count))
|
||||||
return -EFAULT;
|
goto out;
|
||||||
}
|
|
||||||
input_string[count] = '\0';
|
|
||||||
|
|
||||||
strstrip(input_string);
|
buf[count] = '\0';
|
||||||
|
input_string = strstrip(buf);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear all breakpoints if:
|
* Clear all breakpoints if:
|
||||||
@@ -300,18 +300,16 @@ static ssize_t ksym_trace_filter_write(struct file *file,
|
|||||||
* 2: echo 0 > ksym_trace_filter
|
* 2: echo 0 > ksym_trace_filter
|
||||||
* 3: echo "*:---" > ksym_trace_filter
|
* 3: echo "*:---" > ksym_trace_filter
|
||||||
*/
|
*/
|
||||||
if (!input_string[0] || !strcmp(input_string, "0") ||
|
if (!buf[0] || !strcmp(buf, "0") ||
|
||||||
!strcmp(input_string, "*:---")) {
|
!strcmp(buf, "*:---")) {
|
||||||
__ksym_trace_reset();
|
__ksym_trace_reset();
|
||||||
kfree(input_string);
|
ret = 0;
|
||||||
return count;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = op = parse_ksym_trace_str(input_string, &ksymname, &ksym_addr);
|
ret = op = parse_ksym_trace_str(input_string, &ksymname, &ksym_addr);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
kfree(input_string);
|
goto out;
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_lock(&ksym_tracer_mutex);
|
mutex_lock(&ksym_tracer_mutex);
|
||||||
|
|
||||||
@@ -322,7 +320,7 @@ static ssize_t ksym_trace_filter_write(struct file *file,
|
|||||||
if (entry->attr.bp_type != op)
|
if (entry->attr.bp_type != op)
|
||||||
changed = 1;
|
changed = 1;
|
||||||
else
|
else
|
||||||
goto out;
|
goto out_unlock;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -337,28 +335,24 @@ static ssize_t ksym_trace_filter_write(struct file *file,
|
|||||||
if (IS_ERR(entry->ksym_hbp))
|
if (IS_ERR(entry->ksym_hbp))
|
||||||
ret = PTR_ERR(entry->ksym_hbp);
|
ret = PTR_ERR(entry->ksym_hbp);
|
||||||
else
|
else
|
||||||
goto out;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
/* Error or "symbol:---" case: drop it */
|
/* Error or "symbol:---" case: drop it */
|
||||||
ksym_filter_entry_count--;
|
ksym_filter_entry_count--;
|
||||||
hlist_del_rcu(&(entry->ksym_hlist));
|
hlist_del_rcu(&(entry->ksym_hlist));
|
||||||
synchronize_rcu();
|
synchronize_rcu();
|
||||||
kfree(entry);
|
kfree(entry);
|
||||||
goto out;
|
goto out_unlock;
|
||||||
} else {
|
} else {
|
||||||
/* Check for malformed request: (4) */
|
/* Check for malformed request: (4) */
|
||||||
if (op == 0)
|
if (op)
|
||||||
goto out;
|
ret = process_new_ksym_entry(ksymname, op, ksym_addr);
|
||||||
ret = process_new_ksym_entry(ksymname, op, ksym_addr);
|
|
||||||
}
|
}
|
||||||
out:
|
out_unlock:
|
||||||
mutex_unlock(&ksym_tracer_mutex);
|
mutex_unlock(&ksym_tracer_mutex);
|
||||||
|
out:
|
||||||
kfree(input_string);
|
kfree(buf);
|
||||||
|
return !ret ? count : ret;
|
||||||
if (!ret)
|
|
||||||
ret = count;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations ksym_tracing_fops = {
|
static const struct file_operations ksym_tracing_fops = {
|
||||||
|
@@ -217,10 +217,6 @@ int syscall_enter_define_fields(struct ftrace_event_call *call)
|
|||||||
int i;
|
int i;
|
||||||
int offset = offsetof(typeof(trace), args);
|
int offset = offsetof(typeof(trace), args);
|
||||||
|
|
||||||
ret = trace_define_common_fields(call);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER);
|
ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@@ -241,10 +237,6 @@ int syscall_exit_define_fields(struct ftrace_event_call *call)
|
|||||||
struct syscall_trace_exit trace;
|
struct syscall_trace_exit trace;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = trace_define_common_fields(call);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER);
|
ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@@ -333,10 +325,7 @@ int reg_event_syscall_enter(struct ftrace_event_call *call)
|
|||||||
mutex_lock(&syscall_trace_lock);
|
mutex_lock(&syscall_trace_lock);
|
||||||
if (!sys_refcount_enter)
|
if (!sys_refcount_enter)
|
||||||
ret = register_trace_sys_enter(ftrace_syscall_enter);
|
ret = register_trace_sys_enter(ftrace_syscall_enter);
|
||||||
if (ret) {
|
if (!ret) {
|
||||||
pr_info("event trace: Could not activate"
|
|
||||||
"syscall entry trace point");
|
|
||||||
} else {
|
|
||||||
set_bit(num, enabled_enter_syscalls);
|
set_bit(num, enabled_enter_syscalls);
|
||||||
sys_refcount_enter++;
|
sys_refcount_enter++;
|
||||||
}
|
}
|
||||||
@@ -370,10 +359,7 @@ int reg_event_syscall_exit(struct ftrace_event_call *call)
|
|||||||
mutex_lock(&syscall_trace_lock);
|
mutex_lock(&syscall_trace_lock);
|
||||||
if (!sys_refcount_exit)
|
if (!sys_refcount_exit)
|
||||||
ret = register_trace_sys_exit(ftrace_syscall_exit);
|
ret = register_trace_sys_exit(ftrace_syscall_exit);
|
||||||
if (ret) {
|
if (!ret) {
|
||||||
pr_info("event trace: Could not activate"
|
|
||||||
"syscall exit trace point");
|
|
||||||
} else {
|
|
||||||
set_bit(num, enabled_exit_syscalls);
|
set_bit(num, enabled_exit_syscalls);
|
||||||
sys_refcount_exit++;
|
sys_refcount_exit++;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user