Merge branches 'tracing/blktrace', 'tracing/ftrace' and 'tracing/urgent' into tracing/core
This commit is contained in:
@@ -108,7 +108,7 @@ struct ftrace_func_command {
|
|||||||
|
|
||||||
struct seq_file;
|
struct seq_file;
|
||||||
|
|
||||||
struct ftrace_hook_ops {
|
struct ftrace_probe_ops {
|
||||||
void (*func)(unsigned long ip,
|
void (*func)(unsigned long ip,
|
||||||
unsigned long parent_ip,
|
unsigned long parent_ip,
|
||||||
void **data);
|
void **data);
|
||||||
@@ -116,19 +116,19 @@ struct ftrace_hook_ops {
|
|||||||
void (*free)(void **data);
|
void (*free)(void **data);
|
||||||
int (*print)(struct seq_file *m,
|
int (*print)(struct seq_file *m,
|
||||||
unsigned long ip,
|
unsigned long ip,
|
||||||
struct ftrace_hook_ops *ops,
|
struct ftrace_probe_ops *ops,
|
||||||
void *data);
|
void *data);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
register_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
|
register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
|
||||||
void *data);
|
void *data);
|
||||||
extern void
|
extern void
|
||||||
unregister_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
|
unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
|
||||||
void *data);
|
void *data);
|
||||||
extern void
|
extern void
|
||||||
unregister_ftrace_function_hook_func(char *glob, struct ftrace_hook_ops *ops);
|
unregister_ftrace_function_probe_func(char *glob, struct ftrace_probe_ops *ops);
|
||||||
extern void unregister_ftrace_function_hook_all(char *glob);
|
extern void unregister_ftrace_function_probe_all(char *glob);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
FTRACE_FL_FREE = (1 << 0),
|
FTRACE_FL_FREE = (1 << 0),
|
||||||
|
@@ -60,6 +60,7 @@ config FUNCTION_TRACER
|
|||||||
depends on HAVE_FUNCTION_TRACER
|
depends on HAVE_FUNCTION_TRACER
|
||||||
depends on DEBUG_KERNEL
|
depends on DEBUG_KERNEL
|
||||||
select FRAME_POINTER
|
select FRAME_POINTER
|
||||||
|
select KALLSYMS
|
||||||
select TRACING
|
select TRACING
|
||||||
select CONTEXT_SWITCH_TRACER
|
select CONTEXT_SWITCH_TRACER
|
||||||
help
|
help
|
||||||
@@ -246,6 +247,7 @@ config STACK_TRACER
|
|||||||
depends on DEBUG_KERNEL
|
depends on DEBUG_KERNEL
|
||||||
select FUNCTION_TRACER
|
select FUNCTION_TRACER
|
||||||
select STACKTRACE
|
select STACKTRACE
|
||||||
|
select KALLSYMS
|
||||||
help
|
help
|
||||||
This special tracer records the maximum stack footprint of the
|
This special tracer records the maximum stack footprint of the
|
||||||
kernel and displays it in debugfs/tracing/stack_trace.
|
kernel and displays it in debugfs/tracing/stack_trace.
|
||||||
|
@@ -255,9 +255,9 @@ static struct pid * const ftrace_swapper_pid = &init_struct_pid;
|
|||||||
|
|
||||||
static struct hlist_head ftrace_func_hash[FTRACE_FUNC_HASHSIZE] __read_mostly;
|
static struct hlist_head ftrace_func_hash[FTRACE_FUNC_HASHSIZE] __read_mostly;
|
||||||
|
|
||||||
struct ftrace_func_hook {
|
struct ftrace_func_probe {
|
||||||
struct hlist_node node;
|
struct hlist_node node;
|
||||||
struct ftrace_hook_ops *ops;
|
struct ftrace_probe_ops *ops;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned long ip;
|
unsigned long ip;
|
||||||
void *data;
|
void *data;
|
||||||
@@ -460,8 +460,8 @@ static void ftrace_bug(int failed, unsigned long ip)
|
|||||||
static int
|
static int
|
||||||
__ftrace_replace_code(struct dyn_ftrace *rec, int enable)
|
__ftrace_replace_code(struct dyn_ftrace *rec, int enable)
|
||||||
{
|
{
|
||||||
unsigned long ip, fl;
|
|
||||||
unsigned long ftrace_addr;
|
unsigned long ftrace_addr;
|
||||||
|
unsigned long ip, fl;
|
||||||
|
|
||||||
ftrace_addr = (unsigned long)FTRACE_ADDR;
|
ftrace_addr = (unsigned long)FTRACE_ADDR;
|
||||||
|
|
||||||
@@ -530,9 +530,9 @@ __ftrace_replace_code(struct dyn_ftrace *rec, int enable)
|
|||||||
|
|
||||||
static void ftrace_replace_code(int enable)
|
static void ftrace_replace_code(int enable)
|
||||||
{
|
{
|
||||||
int failed;
|
|
||||||
struct dyn_ftrace *rec;
|
struct dyn_ftrace *rec;
|
||||||
struct ftrace_page *pg;
|
struct ftrace_page *pg;
|
||||||
|
int failed;
|
||||||
|
|
||||||
do_for_each_ftrace_rec(pg, rec) {
|
do_for_each_ftrace_rec(pg, rec) {
|
||||||
/*
|
/*
|
||||||
@@ -830,11 +830,11 @@ static void *t_hash_start(struct seq_file *m, loff_t *pos)
|
|||||||
|
|
||||||
static int t_hash_show(struct seq_file *m, void *v)
|
static int t_hash_show(struct seq_file *m, void *v)
|
||||||
{
|
{
|
||||||
struct ftrace_func_hook *rec;
|
struct ftrace_func_probe *rec;
|
||||||
struct hlist_node *hnd = v;
|
struct hlist_node *hnd = v;
|
||||||
char str[KSYM_SYMBOL_LEN];
|
char str[KSYM_SYMBOL_LEN];
|
||||||
|
|
||||||
rec = hlist_entry(hnd, struct ftrace_func_hook, node);
|
rec = hlist_entry(hnd, struct ftrace_func_probe, node);
|
||||||
|
|
||||||
if (rec->ops->print)
|
if (rec->ops->print)
|
||||||
return rec->ops->print(m, rec->ip, rec->ops, rec->data);
|
return rec->ops->print(m, rec->ip, rec->ops, rec->data);
|
||||||
@@ -1208,14 +1208,15 @@ ftrace_match_record(struct dyn_ftrace *rec, char *regex, int len, int type)
|
|||||||
|
|
||||||
static void ftrace_match_records(char *buff, int len, int enable)
|
static void ftrace_match_records(char *buff, int len, int enable)
|
||||||
{
|
{
|
||||||
char *search;
|
unsigned int search_len;
|
||||||
struct ftrace_page *pg;
|
struct ftrace_page *pg;
|
||||||
struct dyn_ftrace *rec;
|
struct dyn_ftrace *rec;
|
||||||
|
unsigned long flag;
|
||||||
|
char *search;
|
||||||
int type;
|
int type;
|
||||||
unsigned long flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
|
|
||||||
unsigned search_len;
|
|
||||||
int not;
|
int not;
|
||||||
|
|
||||||
|
flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
|
||||||
type = ftrace_setup_glob(buff, len, &search, ¬);
|
type = ftrace_setup_glob(buff, len, &search, ¬);
|
||||||
|
|
||||||
search_len = strlen(search);
|
search_len = strlen(search);
|
||||||
@@ -1263,14 +1264,16 @@ ftrace_match_module_record(struct dyn_ftrace *rec, char *mod,
|
|||||||
|
|
||||||
static void ftrace_match_module_records(char *buff, char *mod, int enable)
|
static void ftrace_match_module_records(char *buff, char *mod, int enable)
|
||||||
{
|
{
|
||||||
char *search = buff;
|
unsigned search_len = 0;
|
||||||
struct ftrace_page *pg;
|
struct ftrace_page *pg;
|
||||||
struct dyn_ftrace *rec;
|
struct dyn_ftrace *rec;
|
||||||
int type = MATCH_FULL;
|
int type = MATCH_FULL;
|
||||||
unsigned long flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
|
char *search = buff;
|
||||||
unsigned search_len = 0;
|
unsigned long flag;
|
||||||
int not = 0;
|
int not = 0;
|
||||||
|
|
||||||
|
flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
|
||||||
|
|
||||||
/* blank or '*' mean the same */
|
/* blank or '*' mean the same */
|
||||||
if (strcmp(buff, "*") == 0)
|
if (strcmp(buff, "*") == 0)
|
||||||
buff[0] = 0;
|
buff[0] = 0;
|
||||||
@@ -1348,9 +1351,9 @@ static int __init ftrace_mod_cmd_init(void)
|
|||||||
device_initcall(ftrace_mod_cmd_init);
|
device_initcall(ftrace_mod_cmd_init);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
function_trace_hook_call(unsigned long ip, unsigned long parent_ip)
|
function_trace_probe_call(unsigned long ip, unsigned long parent_ip)
|
||||||
{
|
{
|
||||||
struct ftrace_func_hook *entry;
|
struct ftrace_func_probe *entry;
|
||||||
struct hlist_head *hhd;
|
struct hlist_head *hhd;
|
||||||
struct hlist_node *n;
|
struct hlist_node *n;
|
||||||
unsigned long key;
|
unsigned long key;
|
||||||
@@ -1376,18 +1379,18 @@ function_trace_hook_call(unsigned long ip, unsigned long parent_ip)
|
|||||||
ftrace_preempt_enable(resched);
|
ftrace_preempt_enable(resched);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ftrace_ops trace_hook_ops __read_mostly =
|
static struct ftrace_ops trace_probe_ops __read_mostly =
|
||||||
{
|
{
|
||||||
.func = function_trace_hook_call,
|
.func = function_trace_probe_call,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int ftrace_hook_registered;
|
static int ftrace_probe_registered;
|
||||||
|
|
||||||
static void __enable_ftrace_function_hook(void)
|
static void __enable_ftrace_function_probe(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (ftrace_hook_registered)
|
if (ftrace_probe_registered)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
|
for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
|
||||||
@@ -1399,16 +1402,16 @@ static void __enable_ftrace_function_hook(void)
|
|||||||
if (i == FTRACE_FUNC_HASHSIZE)
|
if (i == FTRACE_FUNC_HASHSIZE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
__register_ftrace_function(&trace_hook_ops);
|
__register_ftrace_function(&trace_probe_ops);
|
||||||
ftrace_startup(0);
|
ftrace_startup(0);
|
||||||
ftrace_hook_registered = 1;
|
ftrace_probe_registered = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __disable_ftrace_function_hook(void)
|
static void __disable_ftrace_function_probe(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!ftrace_hook_registered)
|
if (!ftrace_probe_registered)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
|
for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
|
||||||
@@ -1418,16 +1421,16 @@ static void __disable_ftrace_function_hook(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* no more funcs left */
|
/* no more funcs left */
|
||||||
__unregister_ftrace_function(&trace_hook_ops);
|
__unregister_ftrace_function(&trace_probe_ops);
|
||||||
ftrace_shutdown(0);
|
ftrace_shutdown(0);
|
||||||
ftrace_hook_registered = 0;
|
ftrace_probe_registered = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void ftrace_free_entry_rcu(struct rcu_head *rhp)
|
static void ftrace_free_entry_rcu(struct rcu_head *rhp)
|
||||||
{
|
{
|
||||||
struct ftrace_func_hook *entry =
|
struct ftrace_func_probe *entry =
|
||||||
container_of(rhp, struct ftrace_func_hook, rcu);
|
container_of(rhp, struct ftrace_func_probe, rcu);
|
||||||
|
|
||||||
if (entry->ops->free)
|
if (entry->ops->free)
|
||||||
entry->ops->free(&entry->data);
|
entry->ops->free(&entry->data);
|
||||||
@@ -1436,21 +1439,21 @@ static void ftrace_free_entry_rcu(struct rcu_head *rhp)
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
register_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
|
register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct ftrace_func_hook *entry;
|
struct ftrace_func_probe *entry;
|
||||||
struct ftrace_page *pg;
|
struct ftrace_page *pg;
|
||||||
struct dyn_ftrace *rec;
|
struct dyn_ftrace *rec;
|
||||||
unsigned long key;
|
|
||||||
int type, len, not;
|
int type, len, not;
|
||||||
|
unsigned long key;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
char *search;
|
char *search;
|
||||||
|
|
||||||
type = ftrace_setup_glob(glob, strlen(glob), &search, ¬);
|
type = ftrace_setup_glob(glob, strlen(glob), &search, ¬);
|
||||||
len = strlen(search);
|
len = strlen(search);
|
||||||
|
|
||||||
/* we do not support '!' for function hooks */
|
/* we do not support '!' for function probes */
|
||||||
if (WARN_ON(not))
|
if (WARN_ON(not))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
@@ -1465,7 +1468,7 @@ register_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
|
|||||||
|
|
||||||
entry = kmalloc(sizeof(*entry), GFP_KERNEL);
|
entry = kmalloc(sizeof(*entry), GFP_KERNEL);
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
/* If we did not hook to any, then return error */
|
/* If we did not process any, then return error */
|
||||||
if (!count)
|
if (!count)
|
||||||
count = -ENOMEM;
|
count = -ENOMEM;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
@@ -1495,7 +1498,7 @@ register_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
|
|||||||
hlist_add_head_rcu(&entry->node, &ftrace_func_hash[key]);
|
hlist_add_head_rcu(&entry->node, &ftrace_func_hash[key]);
|
||||||
|
|
||||||
} while_for_each_ftrace_rec();
|
} while_for_each_ftrace_rec();
|
||||||
__enable_ftrace_function_hook();
|
__enable_ftrace_function_probe();
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
mutex_unlock(&ftrace_lock);
|
mutex_unlock(&ftrace_lock);
|
||||||
@@ -1504,15 +1507,15 @@ register_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
HOOK_TEST_FUNC = 1,
|
PROBE_TEST_FUNC = 1,
|
||||||
HOOK_TEST_DATA = 2
|
PROBE_TEST_DATA = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
__unregister_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
|
__unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
|
||||||
void *data, int flags)
|
void *data, int flags)
|
||||||
{
|
{
|
||||||
struct ftrace_func_hook *entry;
|
struct ftrace_func_probe *entry;
|
||||||
struct hlist_node *n, *tmp;
|
struct hlist_node *n, *tmp;
|
||||||
char str[KSYM_SYMBOL_LEN];
|
char str[KSYM_SYMBOL_LEN];
|
||||||
int type = MATCH_FULL;
|
int type = MATCH_FULL;
|
||||||
@@ -1527,7 +1530,7 @@ __unregister_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
|
|||||||
type = ftrace_setup_glob(glob, strlen(glob), &search, ¬);
|
type = ftrace_setup_glob(glob, strlen(glob), &search, ¬);
|
||||||
len = strlen(search);
|
len = strlen(search);
|
||||||
|
|
||||||
/* we do not support '!' for function hooks */
|
/* we do not support '!' for function probes */
|
||||||
if (WARN_ON(not))
|
if (WARN_ON(not))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1539,10 +1542,10 @@ __unregister_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
|
|||||||
hlist_for_each_entry_safe(entry, n, tmp, hhd, node) {
|
hlist_for_each_entry_safe(entry, n, tmp, hhd, node) {
|
||||||
|
|
||||||
/* break up if statements for readability */
|
/* break up if statements for readability */
|
||||||
if ((flags & HOOK_TEST_FUNC) && entry->ops != ops)
|
if ((flags & PROBE_TEST_FUNC) && entry->ops != ops)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((flags & HOOK_TEST_DATA) && entry->data != data)
|
if ((flags & PROBE_TEST_DATA) && entry->data != data)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* do this last, since it is the most expensive */
|
/* do this last, since it is the most expensive */
|
||||||
@@ -1557,27 +1560,27 @@ __unregister_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
|
|||||||
call_rcu(&entry->rcu, ftrace_free_entry_rcu);
|
call_rcu(&entry->rcu, ftrace_free_entry_rcu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
__disable_ftrace_function_hook();
|
__disable_ftrace_function_probe();
|
||||||
mutex_unlock(&ftrace_lock);
|
mutex_unlock(&ftrace_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
unregister_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
|
unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
__unregister_ftrace_function_hook(glob, ops, data,
|
__unregister_ftrace_function_probe(glob, ops, data,
|
||||||
HOOK_TEST_FUNC | HOOK_TEST_DATA);
|
PROBE_TEST_FUNC | PROBE_TEST_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
unregister_ftrace_function_hook_func(char *glob, struct ftrace_hook_ops *ops)
|
unregister_ftrace_function_probe_func(char *glob, struct ftrace_probe_ops *ops)
|
||||||
{
|
{
|
||||||
__unregister_ftrace_function_hook(glob, ops, NULL, HOOK_TEST_FUNC);
|
__unregister_ftrace_function_probe(glob, ops, NULL, PROBE_TEST_FUNC);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unregister_ftrace_function_hook_all(char *glob)
|
void unregister_ftrace_function_probe_all(char *glob)
|
||||||
{
|
{
|
||||||
__unregister_ftrace_function_hook(glob, NULL, NULL, 0);
|
__unregister_ftrace_function_probe(glob, NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static LIST_HEAD(ftrace_commands);
|
static LIST_HEAD(ftrace_commands);
|
||||||
@@ -1623,8 +1626,8 @@ int unregister_ftrace_command(struct ftrace_func_command *cmd)
|
|||||||
|
|
||||||
static int ftrace_process_regex(char *buff, int len, int enable)
|
static int ftrace_process_regex(char *buff, int len, int enable)
|
||||||
{
|
{
|
||||||
struct ftrace_func_command *p;
|
|
||||||
char *func, *command, *next = buff;
|
char *func, *command, *next = buff;
|
||||||
|
struct ftrace_func_command *p;
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
|
|
||||||
func = strsep(&next, ":");
|
func = strsep(&next, ":");
|
||||||
@@ -2392,7 +2395,6 @@ static __init int ftrace_init_debugfs(void)
|
|||||||
"'set_ftrace_pid' entry\n");
|
"'set_ftrace_pid' entry\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_initcall(ftrace_init_debugfs);
|
fs_initcall(ftrace_init_debugfs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -336,7 +336,7 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
|
|||||||
data->rt_priority = tsk->rt_priority;
|
data->rt_priority = tsk->rt_priority;
|
||||||
|
|
||||||
/* record this tasks comm */
|
/* record this tasks comm */
|
||||||
tracing_record_cmdline(current);
|
tracing_record_cmdline(tsk);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -499,6 +499,9 @@ __acquires(kernel_lock)
|
|||||||
else
|
else
|
||||||
if (!type->flags->opts)
|
if (!type->flags->opts)
|
||||||
type->flags->opts = dummy_tracer_opt;
|
type->flags->opts = dummy_tracer_opt;
|
||||||
|
if (!type->wait_pipe)
|
||||||
|
type->wait_pipe = default_wait_pipe;
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_FTRACE_STARTUP_TEST
|
#ifdef CONFIG_FTRACE_STARTUP_TEST
|
||||||
if (type->selftest && !tracing_selftest_disabled) {
|
if (type->selftest && !tracing_selftest_disabled) {
|
||||||
@@ -1064,7 +1067,10 @@ tracing_sched_wakeup_trace(struct trace_array *tr,
|
|||||||
entry->next_prio = wakee->prio;
|
entry->next_prio = wakee->prio;
|
||||||
entry->next_state = wakee->state;
|
entry->next_state = wakee->state;
|
||||||
entry->next_cpu = task_cpu(wakee);
|
entry->next_cpu = task_cpu(wakee);
|
||||||
trace_buffer_unlock_commit(tr, event, flags, pc);
|
|
||||||
|
ring_buffer_unlock_commit(tr->buffer, event);
|
||||||
|
ftrace_trace_stack(tr, flags, 6, pc);
|
||||||
|
ftrace_trace_userstack(tr, flags, pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -2392,6 +2398,38 @@ tracing_poll_pipe(struct file *filp, poll_table *poll_table)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void default_wait_pipe(struct trace_iterator *iter)
|
||||||
|
{
|
||||||
|
DEFINE_WAIT(wait);
|
||||||
|
|
||||||
|
prepare_to_wait(&trace_wait, &wait, TASK_INTERRUPTIBLE);
|
||||||
|
|
||||||
|
if (trace_empty(iter))
|
||||||
|
schedule();
|
||||||
|
|
||||||
|
finish_wait(&trace_wait, &wait);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a make-shift waitqueue.
|
||||||
|
* A tracer might use this callback on some rare cases:
|
||||||
|
*
|
||||||
|
* 1) the current tracer might hold the runqueue lock when it wakes up
|
||||||
|
* a reader, hence a deadlock (sched, function, and function graph tracers)
|
||||||
|
* 2) the function tracers, trace all functions, we don't want
|
||||||
|
* the overhead of calling wake_up and friends
|
||||||
|
* (and tracing them too)
|
||||||
|
*
|
||||||
|
* Anyway, this is really very primitive wakeup.
|
||||||
|
*/
|
||||||
|
void poll_wait_pipe(struct trace_iterator *iter)
|
||||||
|
{
|
||||||
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
|
/* sleep for 100 msecs, and try again. */
|
||||||
|
schedule_timeout(HZ / 10);
|
||||||
|
}
|
||||||
|
|
||||||
/* Must be called with trace_types_lock mutex held. */
|
/* Must be called with trace_types_lock mutex held. */
|
||||||
static int tracing_wait_pipe(struct file *filp)
|
static int tracing_wait_pipe(struct file *filp)
|
||||||
{
|
{
|
||||||
@@ -2403,30 +2441,14 @@ static int tracing_wait_pipe(struct file *filp)
|
|||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This is a make-shift waitqueue. The reason we don't use
|
|
||||||
* an actual wait queue is because:
|
|
||||||
* 1) we only ever have one waiter
|
|
||||||
* 2) the tracing, traces all functions, we don't want
|
|
||||||
* the overhead of calling wake_up and friends
|
|
||||||
* (and tracing them too)
|
|
||||||
* Anyway, this is really very primitive wakeup.
|
|
||||||
*/
|
|
||||||
set_current_state(TASK_INTERRUPTIBLE);
|
|
||||||
iter->tr->waiter = current;
|
|
||||||
|
|
||||||
mutex_unlock(&trace_types_lock);
|
mutex_unlock(&trace_types_lock);
|
||||||
|
|
||||||
/* sleep for 100 msecs, and try again. */
|
iter->trace->wait_pipe(iter);
|
||||||
schedule_timeout(HZ/10);
|
|
||||||
|
|
||||||
mutex_lock(&trace_types_lock);
|
mutex_lock(&trace_types_lock);
|
||||||
|
|
||||||
iter->tr->waiter = NULL;
|
if (signal_pending(current))
|
||||||
|
|
||||||
if (signal_pending(current)) {
|
|
||||||
return -EINTR;
|
return -EINTR;
|
||||||
}
|
|
||||||
|
|
||||||
if (iter->trace != current_trace)
|
if (iter->trace != current_trace)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2442,8 +2464,6 @@ static int tracing_wait_pipe(struct file *filp)
|
|||||||
*/
|
*/
|
||||||
if (!tracer_enabled && iter->pos)
|
if (!tracer_enabled && iter->pos)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -2551,8 +2571,7 @@ static struct pipe_buf_operations tracing_pipe_buf_ops = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
tracing_fill_pipe_page(struct page *pages, size_t rem,
|
tracing_fill_pipe_page(size_t rem, struct trace_iterator *iter)
|
||||||
struct trace_iterator *iter)
|
|
||||||
{
|
{
|
||||||
size_t count;
|
size_t count;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -2629,7 +2648,7 @@ static ssize_t tracing_splice_read_pipe(struct file *filp,
|
|||||||
if (!pages[i])
|
if (!pages[i])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
rem = tracing_fill_pipe_page(pages[i], rem, iter);
|
rem = tracing_fill_pipe_page(rem, iter);
|
||||||
|
|
||||||
/* Copy the data into the page, so we can start over. */
|
/* Copy the data into the page, so we can start over. */
|
||||||
ret = trace_seq_to_buffer(&iter->seq,
|
ret = trace_seq_to_buffer(&iter->seq,
|
||||||
|
@@ -337,18 +337,34 @@ struct tracer_flags {
|
|||||||
#define TRACER_OPT(s, b) .name = #s, .bit = b
|
#define TRACER_OPT(s, b) .name = #s, .bit = b
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* A specific tracer, represented by methods that operate on a trace array:
|
* struct tracer - a specific tracer and its callbacks to interact with debugfs
|
||||||
|
* @name: the name chosen to select it on the available_tracers file
|
||||||
|
* @init: called when one switches to this tracer (echo name > current_tracer)
|
||||||
|
* @reset: called when one switches to another tracer
|
||||||
|
* @start: called when tracing is unpaused (echo 1 > tracing_enabled)
|
||||||
|
* @stop: called when tracing is paused (echo 0 > tracing_enabled)
|
||||||
|
* @open: called when the trace file is opened
|
||||||
|
* @pipe_open: called when the trace_pipe file is opened
|
||||||
|
* @wait_pipe: override how the user waits for traces on trace_pipe
|
||||||
|
* @close: called when the trace file is released
|
||||||
|
* @read: override the default read callback on trace_pipe
|
||||||
|
* @splice_read: override the default splice_read callback on trace_pipe
|
||||||
|
* @selftest: selftest to run on boot (see trace_selftest.c)
|
||||||
|
* @print_headers: override the first lines that describe your columns
|
||||||
|
* @print_line: callback that prints a trace
|
||||||
|
* @set_flag: signals one of your private flags changed (trace_options file)
|
||||||
|
* @flags: your private flags
|
||||||
*/
|
*/
|
||||||
struct tracer {
|
struct tracer {
|
||||||
const char *name;
|
const char *name;
|
||||||
/* Your tracer should raise a warning if init fails */
|
|
||||||
int (*init)(struct trace_array *tr);
|
int (*init)(struct trace_array *tr);
|
||||||
void (*reset)(struct trace_array *tr);
|
void (*reset)(struct trace_array *tr);
|
||||||
void (*start)(struct trace_array *tr);
|
void (*start)(struct trace_array *tr);
|
||||||
void (*stop)(struct trace_array *tr);
|
void (*stop)(struct trace_array *tr);
|
||||||
void (*open)(struct trace_iterator *iter);
|
void (*open)(struct trace_iterator *iter);
|
||||||
void (*pipe_open)(struct trace_iterator *iter);
|
void (*pipe_open)(struct trace_iterator *iter);
|
||||||
|
void (*wait_pipe)(struct trace_iterator *iter);
|
||||||
void (*close)(struct trace_iterator *iter);
|
void (*close)(struct trace_iterator *iter);
|
||||||
ssize_t (*read)(struct trace_iterator *iter,
|
ssize_t (*read)(struct trace_iterator *iter,
|
||||||
struct file *filp, char __user *ubuf,
|
struct file *filp, char __user *ubuf,
|
||||||
@@ -432,6 +448,9 @@ void tracing_generic_entry_update(struct trace_entry *entry,
|
|||||||
unsigned long flags,
|
unsigned long flags,
|
||||||
int pc);
|
int pc);
|
||||||
|
|
||||||
|
void default_wait_pipe(struct trace_iterator *iter);
|
||||||
|
void poll_wait_pipe(struct trace_iterator *iter);
|
||||||
|
|
||||||
void ftrace(struct trace_array *tr,
|
void ftrace(struct trace_array *tr,
|
||||||
struct trace_array_cpu *data,
|
struct trace_array_cpu *data,
|
||||||
unsigned long ip,
|
unsigned long ip,
|
||||||
|
@@ -225,6 +225,7 @@ static struct tracer function_trace __read_mostly =
|
|||||||
.init = function_trace_init,
|
.init = function_trace_init,
|
||||||
.reset = function_trace_reset,
|
.reset = function_trace_reset,
|
||||||
.start = function_trace_start,
|
.start = function_trace_start,
|
||||||
|
.wait_pipe = poll_wait_pipe,
|
||||||
.flags = &func_flags,
|
.flags = &func_flags,
|
||||||
.set_flag = func_set_flag,
|
.set_flag = func_set_flag,
|
||||||
#ifdef CONFIG_FTRACE_SELFTEST
|
#ifdef CONFIG_FTRACE_SELFTEST
|
||||||
@@ -269,21 +270,21 @@ ftrace_traceoff(unsigned long ip, unsigned long parent_ip, void **data)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
|
ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
|
||||||
struct ftrace_hook_ops *ops, void *data);
|
struct ftrace_probe_ops *ops, void *data);
|
||||||
|
|
||||||
static struct ftrace_hook_ops traceon_hook_ops = {
|
static struct ftrace_probe_ops traceon_probe_ops = {
|
||||||
.func = ftrace_traceon,
|
.func = ftrace_traceon,
|
||||||
.print = ftrace_trace_onoff_print,
|
.print = ftrace_trace_onoff_print,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ftrace_hook_ops traceoff_hook_ops = {
|
static struct ftrace_probe_ops traceoff_probe_ops = {
|
||||||
.func = ftrace_traceoff,
|
.func = ftrace_traceoff,
|
||||||
.print = ftrace_trace_onoff_print,
|
.print = ftrace_trace_onoff_print,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
|
ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
|
||||||
struct ftrace_hook_ops *ops, void *data)
|
struct ftrace_probe_ops *ops, void *data)
|
||||||
{
|
{
|
||||||
char str[KSYM_SYMBOL_LEN];
|
char str[KSYM_SYMBOL_LEN];
|
||||||
long count = (long)data;
|
long count = (long)data;
|
||||||
@@ -291,12 +292,14 @@ ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
|
|||||||
kallsyms_lookup(ip, NULL, NULL, NULL, str);
|
kallsyms_lookup(ip, NULL, NULL, NULL, str);
|
||||||
seq_printf(m, "%s:", str);
|
seq_printf(m, "%s:", str);
|
||||||
|
|
||||||
if (ops == &traceon_hook_ops)
|
if (ops == &traceon_probe_ops)
|
||||||
seq_printf(m, "traceon");
|
seq_printf(m, "traceon");
|
||||||
else
|
else
|
||||||
seq_printf(m, "traceoff");
|
seq_printf(m, "traceoff");
|
||||||
|
|
||||||
if (count != -1)
|
if (count == -1)
|
||||||
|
seq_printf(m, ":unlimited\n");
|
||||||
|
else
|
||||||
seq_printf(m, ":count=%ld", count);
|
seq_printf(m, ":count=%ld", count);
|
||||||
seq_putc(m, '\n');
|
seq_putc(m, '\n');
|
||||||
|
|
||||||
@@ -306,15 +309,15 @@ ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
|
|||||||
static int
|
static int
|
||||||
ftrace_trace_onoff_unreg(char *glob, char *cmd, char *param)
|
ftrace_trace_onoff_unreg(char *glob, char *cmd, char *param)
|
||||||
{
|
{
|
||||||
struct ftrace_hook_ops *ops;
|
struct ftrace_probe_ops *ops;
|
||||||
|
|
||||||
/* we register both traceon and traceoff to this callback */
|
/* we register both traceon and traceoff to this callback */
|
||||||
if (strcmp(cmd, "traceon") == 0)
|
if (strcmp(cmd, "traceon") == 0)
|
||||||
ops = &traceon_hook_ops;
|
ops = &traceon_probe_ops;
|
||||||
else
|
else
|
||||||
ops = &traceoff_hook_ops;
|
ops = &traceoff_probe_ops;
|
||||||
|
|
||||||
unregister_ftrace_function_hook_func(glob, ops);
|
unregister_ftrace_function_probe_func(glob, ops);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -322,7 +325,7 @@ ftrace_trace_onoff_unreg(char *glob, char *cmd, char *param)
|
|||||||
static int
|
static int
|
||||||
ftrace_trace_onoff_callback(char *glob, char *cmd, char *param, int enable)
|
ftrace_trace_onoff_callback(char *glob, char *cmd, char *param, int enable)
|
||||||
{
|
{
|
||||||
struct ftrace_hook_ops *ops;
|
struct ftrace_probe_ops *ops;
|
||||||
void *count = (void *)-1;
|
void *count = (void *)-1;
|
||||||
char *number;
|
char *number;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -336,9 +339,9 @@ ftrace_trace_onoff_callback(char *glob, char *cmd, char *param, int enable)
|
|||||||
|
|
||||||
/* we register both traceon and traceoff to this callback */
|
/* we register both traceon and traceoff to this callback */
|
||||||
if (strcmp(cmd, "traceon") == 0)
|
if (strcmp(cmd, "traceon") == 0)
|
||||||
ops = &traceon_hook_ops;
|
ops = &traceon_probe_ops;
|
||||||
else
|
else
|
||||||
ops = &traceoff_hook_ops;
|
ops = &traceoff_probe_ops;
|
||||||
|
|
||||||
if (!param)
|
if (!param)
|
||||||
goto out_reg;
|
goto out_reg;
|
||||||
@@ -357,7 +360,7 @@ ftrace_trace_onoff_callback(char *glob, char *cmd, char *param, int enable)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
out_reg:
|
out_reg:
|
||||||
ret = register_ftrace_function_hook(glob, ops, count);
|
ret = register_ftrace_function_probe(glob, ops, count);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -397,6 +400,5 @@ static __init int init_function_trace(void)
|
|||||||
init_func_cmd_traceon();
|
init_func_cmd_traceon();
|
||||||
return register_tracer(&function_trace);
|
return register_tracer(&function_trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
device_initcall(init_function_trace);
|
device_initcall(init_function_trace);
|
||||||
|
|
||||||
|
@@ -757,6 +757,7 @@ static struct tracer graph_trace __read_mostly = {
|
|||||||
.name = "function_graph",
|
.name = "function_graph",
|
||||||
.open = graph_trace_open,
|
.open = graph_trace_open,
|
||||||
.close = graph_trace_close,
|
.close = graph_trace_close,
|
||||||
|
.wait_pipe = poll_wait_pipe,
|
||||||
.init = graph_trace_init,
|
.init = graph_trace_init,
|
||||||
.reset = graph_trace_reset,
|
.reset = graph_trace_reset,
|
||||||
.print_line = print_graph_function,
|
.print_line = print_graph_function,
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* trace irqs off criticall timings
|
* trace irqs off critical timings
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
|
* Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
|
||||||
* Copyright (C) 2008 Ingo Molnar <mingo@redhat.com>
|
* Copyright (C) 2008 Ingo Molnar <mingo@redhat.com>
|
||||||
|
@@ -93,7 +93,7 @@ static int tracing_sched_register(void)
|
|||||||
ret = register_trace_sched_switch(probe_sched_switch);
|
ret = register_trace_sched_switch(probe_sched_switch);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_info("sched trace: Couldn't activate tracepoint"
|
pr_info("sched trace: Couldn't activate tracepoint"
|
||||||
" probe to kernel_sched_schedule\n");
|
" probe to kernel_sched_switch\n");
|
||||||
goto fail_deprobe_wake_new;
|
goto fail_deprobe_wake_new;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,6 +221,7 @@ static struct tracer sched_switch_trace __read_mostly =
|
|||||||
.reset = sched_switch_trace_reset,
|
.reset = sched_switch_trace_reset,
|
||||||
.start = sched_switch_trace_start,
|
.start = sched_switch_trace_start,
|
||||||
.stop = sched_switch_trace_stop,
|
.stop = sched_switch_trace_stop,
|
||||||
|
.wait_pipe = poll_wait_pipe,
|
||||||
#ifdef CONFIG_FTRACE_SELFTEST
|
#ifdef CONFIG_FTRACE_SELFTEST
|
||||||
.selftest = trace_selftest_startup_sched_switch,
|
.selftest = trace_selftest_startup_sched_switch,
|
||||||
#endif
|
#endif
|
||||||
|
@@ -284,7 +284,7 @@ static void start_wakeup_tracer(struct trace_array *tr)
|
|||||||
ret = register_trace_sched_switch(probe_wakeup_sched_switch);
|
ret = register_trace_sched_switch(probe_wakeup_sched_switch);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_info("sched trace: Couldn't activate tracepoint"
|
pr_info("sched trace: Couldn't activate tracepoint"
|
||||||
" probe to kernel_sched_schedule\n");
|
" probe to kernel_sched_switch\n");
|
||||||
goto fail_deprobe_wake_new;
|
goto fail_deprobe_wake_new;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,6 +380,7 @@ static struct tracer wakeup_rt_tracer __read_mostly =
|
|||||||
.reset = wakeup_tracer_reset,
|
.reset = wakeup_tracer_reset,
|
||||||
.start = wakeup_tracer_start,
|
.start = wakeup_tracer_start,
|
||||||
.stop = wakeup_tracer_stop,
|
.stop = wakeup_tracer_stop,
|
||||||
|
.wait_pipe = poll_wait_pipe,
|
||||||
.print_max = 1,
|
.print_max = 1,
|
||||||
#ifdef CONFIG_FTRACE_SELFTEST
|
#ifdef CONFIG_FTRACE_SELFTEST
|
||||||
.selftest = trace_selftest_startup_wakeup,
|
.selftest = trace_selftest_startup_wakeup,
|
||||||
|
@@ -24,10 +24,20 @@ static int trace_test_buffer_cpu(struct trace_array *tr, int cpu)
|
|||||||
{
|
{
|
||||||
struct ring_buffer_event *event;
|
struct ring_buffer_event *event;
|
||||||
struct trace_entry *entry;
|
struct trace_entry *entry;
|
||||||
|
unsigned int loops = 0;
|
||||||
|
|
||||||
while ((event = ring_buffer_consume(tr->buffer, cpu, NULL))) {
|
while ((event = ring_buffer_consume(tr->buffer, cpu, NULL))) {
|
||||||
entry = ring_buffer_event_data(event);
|
entry = ring_buffer_event_data(event);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ring buffer is a size of trace_buf_size, if
|
||||||
|
* we loop more than the size, there's something wrong
|
||||||
|
* with the ring buffer.
|
||||||
|
*/
|
||||||
|
if (loops++ > trace_buf_size) {
|
||||||
|
printk(KERN_CONT ".. bad ring buffer ");
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
if (!trace_valid_entry(entry)) {
|
if (!trace_valid_entry(entry)) {
|
||||||
printk(KERN_CONT ".. invalid entry %d ",
|
printk(KERN_CONT ".. invalid entry %d ",
|
||||||
entry->type);
|
entry->type);
|
||||||
@@ -58,11 +68,20 @@ static int trace_test_buffer(struct trace_array *tr, unsigned long *count)
|
|||||||
|
|
||||||
cnt = ring_buffer_entries(tr->buffer);
|
cnt = ring_buffer_entries(tr->buffer);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The trace_test_buffer_cpu runs a while loop to consume all data.
|
||||||
|
* If the calling tracer is broken, and is constantly filling
|
||||||
|
* the buffer, this will run forever, and hard lock the box.
|
||||||
|
* We disable the ring buffer while we do this test to prevent
|
||||||
|
* a hard lock up.
|
||||||
|
*/
|
||||||
|
tracing_off();
|
||||||
for_each_possible_cpu(cpu) {
|
for_each_possible_cpu(cpu) {
|
||||||
ret = trace_test_buffer_cpu(tr, cpu);
|
ret = trace_test_buffer_cpu(tr, cpu);
|
||||||
if (ret)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
tracing_on();
|
||||||
__raw_spin_unlock(&ftrace_max_lock);
|
__raw_spin_unlock(&ftrace_max_lock);
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
|
||||||
@@ -107,9 +126,9 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
|
|||||||
func();
|
func();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some archs *cough*PowerPC*cough* add charachters to the
|
* Some archs *cough*PowerPC*cough* add characters to the
|
||||||
* start of the function names. We simply put a '*' to
|
* start of the function names. We simply put a '*' to
|
||||||
* accomodate them.
|
* accommodate them.
|
||||||
*/
|
*/
|
||||||
func_name = "*" STR(DYN_FTRACE_TEST_NAME);
|
func_name = "*" STR(DYN_FTRACE_TEST_NAME);
|
||||||
|
|
||||||
@@ -622,7 +641,7 @@ trace_selftest_startup_sysprof(struct tracer *trace, struct trace_array *tr)
|
|||||||
ret = tracer_init(trace, tr);
|
ret = tracer_init(trace, tr);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
warn_failed_init_tracer(trace, ret);
|
warn_failed_init_tracer(trace, ret);
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sleep for a 1/10 of a second */
|
/* Sleep for a 1/10 of a second */
|
||||||
@@ -634,6 +653,11 @@ trace_selftest_startup_sysprof(struct tracer *trace, struct trace_array *tr)
|
|||||||
trace->reset(tr);
|
trace->reset(tr);
|
||||||
tracing_start();
|
tracing_start();
|
||||||
|
|
||||||
|
if (!ret && !count) {
|
||||||
|
printk(KERN_CONT ".. no entries found ..");
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_SYSPROF_TRACER */
|
#endif /* CONFIG_SYSPROF_TRACER */
|
||||||
@@ -661,6 +685,11 @@ trace_selftest_startup_branch(struct tracer *trace, struct trace_array *tr)
|
|||||||
trace->reset(tr);
|
trace->reset(tr);
|
||||||
tracing_start();
|
tracing_start();
|
||||||
|
|
||||||
|
if (!ret && !count) {
|
||||||
|
printk(KERN_CONT ".. no entries found ..");
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BRANCH_TRACER */
|
#endif /* CONFIG_BRANCH_TRACER */
|
||||||
|
@@ -30,7 +30,7 @@ struct tracer_stat_session {
|
|||||||
struct dentry *file;
|
struct dentry *file;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* All of the sessions currently in use. Each stat file embeed one session */
|
/* All of the sessions currently in use. Each stat file embed one session */
|
||||||
static LIST_HEAD(all_stat_sessions);
|
static LIST_HEAD(all_stat_sessions);
|
||||||
static DEFINE_MUTEX(all_stat_sessions_mutex);
|
static DEFINE_MUTEX(all_stat_sessions_mutex);
|
||||||
|
|
||||||
|
@@ -327,5 +327,5 @@ void init_tracer_sysprof_debugfs(struct dentry *d_tracer)
|
|||||||
d_tracer, NULL, &sysprof_sample_fops);
|
d_tracer, NULL, &sysprof_sample_fops);
|
||||||
if (entry)
|
if (entry)
|
||||||
return;
|
return;
|
||||||
pr_warning("Could not create debugfs 'dyn_ftrace_total_info' entry\n");
|
pr_warning("Could not create debugfs 'sysprof_sample_period' entry\n");
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user