Commit da184a80 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'tracing-fixes-for-linus' of...

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
parents 525995d7 e36c5458
...@@ -131,7 +131,7 @@ struct ftrace_event_call { ...@@ -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 { ...@@ -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 ...@@ -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))); ...@@ -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; ...@@ -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; ...@@ -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; ...@@ -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) \ ...@@ -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)\ ...@@ -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)\ ...@@ -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)\ ...@@ -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) \ ...@@ -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)\ ...@@ -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 = { \ ...@@ -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 = { \ ...@@ -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: \ ...@@ -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) ...@@ -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) ...@@ -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, &not); type = filter_parse_regex(buff, len, &search, &not);
...@@ -1750,6 +1751,7 @@ static void ftrace_match_records(char *buff, int len, int enable) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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 @@ ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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[] = { ...@@ -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, ...@@ -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,67 +2331,49 @@ static const struct file_operations tracing_cpumask_fops = { ...@@ -2316,67 +2331,49 @@ 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); static int __set_tracer_option(struct tracer *trace,
struct tracer_flags *tracer_flags,
struct tracer_opt *opts, int neg)
{
int ret;
kfree(buf); ret = trace->set_flag(tracer_flags->val, opts->bit, !neg);
return r; if (ret)
return ret;
if (neg)
tracer_flags->val &= ~opts->bit;
else
tracer_flags->val |= opts->bit;
return 0;
} }
/* Try to assign a tracer specific option */ /* Try to assign a tracer specific option */
...@@ -2384,33 +2381,17 @@ static int set_tracer_option(struct tracer *trace, char *cmp, int neg) ...@@ -2384,33 +2381,17 @@ static int set_tracer_option(struct tracer *trace, char *cmp, int neg)
{ {
struct tracer_flags *tracer_flags = trace->flags; struct tracer_flags *tracer_flags = trace->flags;
struct tracer_opt *opts = NULL; struct tracer_opt *opts = NULL;
int ret = 0, i = 0; int i;
int len;
for (i = 0; tracer_flags->opts[i].name; i++) { for (i = 0; tracer_flags->opts[i].name; i++) {
opts = &tracer_flags->opts[i]; opts = &tracer_flags->opts[i];
len = strlen(opts->name);
if (strncmp(cmp, opts->name, len) == 0) { if (strcmp(cmp, opts->name) == 0)
ret = trace->set_flag(tracer_flags->val, return __set_tracer_option(trace, trace->flags,
opts->bit, !neg); opts, neg);
break;
}
} }
/* Not found */
if (!tracer_flags->opts[i].name)
return -EINVAL;
/* Refused to handle */
if (ret)
return ret;
if (neg)
tracer_flags->val &= ~opts->bit;
else
tracer_flags->val |= opts->bit;
return 0; return -EINVAL;
} }
static void set_tracer_flags(unsigned int mask, int enabled) static void set_tracer_flags(unsigned int mask, int enabled)
...@@ -2430,7 +2411,7 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 = { ...@@ -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, ...@@ -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) { return -EINVAL;
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;
if (!!(topt->flags->val & topt->opt->bit) != val) {
mutex_lock(&trace_types_lock); mutex_lock(&trace_types_lock);
if (current_trace->set_flag) ret = __set_tracer_option(current_trace, topt->flags,
ret = current_trace->set_flag(topt->flags->val, topt->opt, val);
topt->opt->bit, 1);
mutex_unlock(&trace_types_lock); mutex_unlock(&trace_types_lock);
if (ret) if (ret)
return ret; return ret;
topt->flags->val |= topt->opt->bit;
break;
default:
return -EINVAL;
} }
*ppos += cnt; *ppos += cnt;
......
...@@ -597,18 +597,17 @@ enum trace_iterator_flags { ...@@ -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) ...@@ -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: ...@@ -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) ...@@ -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); ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) \ ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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++;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment