ftrace: remove daemon
The ftrace daemon is complex and error prone. This patch strips it out of the code. Signed-off-by: Steven Rostedt <srostedt@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
07c4cc1cda
commit
cb7be3b2fc
@ -165,25 +165,8 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||||
|
|
||||||
#ifndef CONFIG_FTRACE_MCOUNT_RECORD
|
#ifndef CONFIG_FTRACE_MCOUNT_RECORD
|
||||||
/*
|
# error Dynamic ftrace depends on MCOUNT_RECORD
|
||||||
* The hash lock is only needed when the recording of the mcount
|
|
||||||
* callers are dynamic. That is, by the caller themselves and
|
|
||||||
* not recorded via the compilation.
|
|
||||||
*/
|
|
||||||
static DEFINE_SPINLOCK(ftrace_hash_lock);
|
|
||||||
#define ftrace_hash_lock(flags) spin_lock_irqsave(&ftrace_hash_lock, flags)
|
|
||||||
#define ftrace_hash_unlock(flags) \
|
|
||||||
spin_unlock_irqrestore(&ftrace_hash_lock, flags)
|
|
||||||
static void ftrace_release_hash(unsigned long start, unsigned long end);
|
|
||||||
#else
|
|
||||||
/* This is protected via the ftrace_lock with MCOUNT_RECORD. */
|
|
||||||
#define ftrace_hash_lock(flags) do { (void)(flags); } while (0)
|
|
||||||
#define ftrace_hash_unlock(flags) do { } while(0)
|
|
||||||
static inline void ftrace_release_hash(unsigned long start, unsigned long end)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -194,8 +177,6 @@ static inline void ftrace_release_hash(unsigned long start, unsigned long end)
|
|||||||
*/
|
*/
|
||||||
static unsigned long mcount_addr = MCOUNT_ADDR;
|
static unsigned long mcount_addr = MCOUNT_ADDR;
|
||||||
|
|
||||||
static struct task_struct *ftraced_task;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
FTRACE_ENABLE_CALLS = (1 << 0),
|
FTRACE_ENABLE_CALLS = (1 << 0),
|
||||||
FTRACE_DISABLE_CALLS = (1 << 1),
|
FTRACE_DISABLE_CALLS = (1 << 1),
|
||||||
@ -212,7 +193,6 @@ static struct hlist_head ftrace_hash[FTRACE_HASHSIZE];
|
|||||||
|
|
||||||
static DEFINE_PER_CPU(int, ftrace_shutdown_disable_cpu);
|
static DEFINE_PER_CPU(int, ftrace_shutdown_disable_cpu);
|
||||||
|
|
||||||
static DEFINE_MUTEX(ftraced_lock);
|
|
||||||
static DEFINE_MUTEX(ftrace_regex_lock);
|
static DEFINE_MUTEX(ftrace_regex_lock);
|
||||||
|
|
||||||
struct ftrace_page {
|
struct ftrace_page {
|
||||||
@ -230,10 +210,6 @@ struct ftrace_page {
|
|||||||
static struct ftrace_page *ftrace_pages_start;
|
static struct ftrace_page *ftrace_pages_start;
|
||||||
static struct ftrace_page *ftrace_pages;
|
static struct ftrace_page *ftrace_pages;
|
||||||
|
|
||||||
static int ftraced_trigger;
|
|
||||||
static int ftraced_suspend;
|
|
||||||
static int ftraced_stop;
|
|
||||||
|
|
||||||
static int ftrace_record_suspend;
|
static int ftrace_record_suspend;
|
||||||
|
|
||||||
static struct dyn_ftrace *ftrace_free_records;
|
static struct dyn_ftrace *ftrace_free_records;
|
||||||
@ -398,7 +374,6 @@ static void
|
|||||||
ftrace_record_ip(unsigned long ip)
|
ftrace_record_ip(unsigned long ip)
|
||||||
{
|
{
|
||||||
struct dyn_ftrace *node;
|
struct dyn_ftrace *node;
|
||||||
unsigned long flags;
|
|
||||||
unsigned long key;
|
unsigned long key;
|
||||||
int resched;
|
int resched;
|
||||||
int cpu;
|
int cpu;
|
||||||
@ -430,24 +405,18 @@ ftrace_record_ip(unsigned long ip)
|
|||||||
if (ftrace_ip_in_hash(ip, key))
|
if (ftrace_ip_in_hash(ip, key))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ftrace_hash_lock(flags);
|
|
||||||
|
|
||||||
/* This ip may have hit the hash before the lock */
|
/* This ip may have hit the hash before the lock */
|
||||||
if (ftrace_ip_in_hash(ip, key))
|
if (ftrace_ip_in_hash(ip, key))
|
||||||
goto out_unlock;
|
goto out;
|
||||||
|
|
||||||
node = ftrace_alloc_dyn_node(ip);
|
node = ftrace_alloc_dyn_node(ip);
|
||||||
if (!node)
|
if (!node)
|
||||||
goto out_unlock;
|
goto out;
|
||||||
|
|
||||||
node->ip = ip;
|
node->ip = ip;
|
||||||
|
|
||||||
ftrace_add_hash(node, key);
|
ftrace_add_hash(node, key);
|
||||||
|
|
||||||
ftraced_trigger = 1;
|
|
||||||
|
|
||||||
out_unlock:
|
|
||||||
ftrace_hash_unlock(flags);
|
|
||||||
out:
|
out:
|
||||||
per_cpu(ftrace_shutdown_disable_cpu, cpu)--;
|
per_cpu(ftrace_shutdown_disable_cpu, cpu)--;
|
||||||
|
|
||||||
@ -647,7 +616,7 @@ ftrace_code_disable(struct dyn_ftrace *rec)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __ftrace_update_code(void *ignore);
|
static int ftrace_update_code(void *ignore);
|
||||||
|
|
||||||
static int __ftrace_modify_code(void *data)
|
static int __ftrace_modify_code(void *data)
|
||||||
{
|
{
|
||||||
@ -659,7 +628,7 @@ static int __ftrace_modify_code(void *data)
|
|||||||
* Update any recorded ips now that we have the
|
* Update any recorded ips now that we have the
|
||||||
* machine stopped
|
* machine stopped
|
||||||
*/
|
*/
|
||||||
__ftrace_update_code(NULL);
|
ftrace_update_code(NULL);
|
||||||
ftrace_replace_code(1);
|
ftrace_replace_code(1);
|
||||||
tracing_on = 1;
|
tracing_on = 1;
|
||||||
} else if (*command & FTRACE_DISABLE_CALLS) {
|
} else if (*command & FTRACE_DISABLE_CALLS) {
|
||||||
@ -686,26 +655,9 @@ static void ftrace_run_update_code(int command)
|
|||||||
stop_machine(__ftrace_modify_code, &command, NULL);
|
stop_machine(__ftrace_modify_code, &command, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ftrace_disable_daemon(void)
|
|
||||||
{
|
|
||||||
/* Stop the daemon from calling kstop_machine */
|
|
||||||
mutex_lock(&ftraced_lock);
|
|
||||||
ftraced_stop = 1;
|
|
||||||
mutex_unlock(&ftraced_lock);
|
|
||||||
|
|
||||||
ftrace_force_update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ftrace_enable_daemon(void)
|
|
||||||
{
|
|
||||||
mutex_lock(&ftraced_lock);
|
|
||||||
ftraced_stop = 0;
|
|
||||||
mutex_unlock(&ftraced_lock);
|
|
||||||
|
|
||||||
ftrace_force_update();
|
|
||||||
}
|
|
||||||
|
|
||||||
static ftrace_func_t saved_ftrace_func;
|
static ftrace_func_t saved_ftrace_func;
|
||||||
|
static int ftrace_start;
|
||||||
|
static DEFINE_MUTEX(ftrace_start_lock);
|
||||||
|
|
||||||
static void ftrace_startup(void)
|
static void ftrace_startup(void)
|
||||||
{
|
{
|
||||||
@ -714,9 +666,9 @@ static void ftrace_startup(void)
|
|||||||
if (unlikely(ftrace_disabled))
|
if (unlikely(ftrace_disabled))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mutex_lock(&ftraced_lock);
|
mutex_lock(&ftrace_start_lock);
|
||||||
ftraced_suspend++;
|
ftrace_start++;
|
||||||
if (ftraced_suspend == 1)
|
if (ftrace_start == 1)
|
||||||
command |= FTRACE_ENABLE_CALLS;
|
command |= FTRACE_ENABLE_CALLS;
|
||||||
|
|
||||||
if (saved_ftrace_func != ftrace_trace_function) {
|
if (saved_ftrace_func != ftrace_trace_function) {
|
||||||
@ -729,7 +681,7 @@ static void ftrace_startup(void)
|
|||||||
|
|
||||||
ftrace_run_update_code(command);
|
ftrace_run_update_code(command);
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&ftraced_lock);
|
mutex_unlock(&ftrace_start_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ftrace_shutdown(void)
|
static void ftrace_shutdown(void)
|
||||||
@ -739,9 +691,9 @@ static void ftrace_shutdown(void)
|
|||||||
if (unlikely(ftrace_disabled))
|
if (unlikely(ftrace_disabled))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mutex_lock(&ftraced_lock);
|
mutex_lock(&ftrace_start_lock);
|
||||||
ftraced_suspend--;
|
ftrace_start--;
|
||||||
if (!ftraced_suspend)
|
if (!ftrace_start)
|
||||||
command |= FTRACE_DISABLE_CALLS;
|
command |= FTRACE_DISABLE_CALLS;
|
||||||
|
|
||||||
if (saved_ftrace_func != ftrace_trace_function) {
|
if (saved_ftrace_func != ftrace_trace_function) {
|
||||||
@ -754,7 +706,7 @@ static void ftrace_shutdown(void)
|
|||||||
|
|
||||||
ftrace_run_update_code(command);
|
ftrace_run_update_code(command);
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&ftraced_lock);
|
mutex_unlock(&ftrace_start_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ftrace_startup_sysctl(void)
|
static void ftrace_startup_sysctl(void)
|
||||||
@ -764,15 +716,15 @@ static void ftrace_startup_sysctl(void)
|
|||||||
if (unlikely(ftrace_disabled))
|
if (unlikely(ftrace_disabled))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mutex_lock(&ftraced_lock);
|
mutex_lock(&ftrace_start_lock);
|
||||||
/* Force update next time */
|
/* Force update next time */
|
||||||
saved_ftrace_func = NULL;
|
saved_ftrace_func = NULL;
|
||||||
/* ftraced_suspend is true if we want ftrace running */
|
/* ftrace_start is true if we want ftrace running */
|
||||||
if (ftraced_suspend)
|
if (ftrace_start)
|
||||||
command |= FTRACE_ENABLE_CALLS;
|
command |= FTRACE_ENABLE_CALLS;
|
||||||
|
|
||||||
ftrace_run_update_code(command);
|
ftrace_run_update_code(command);
|
||||||
mutex_unlock(&ftraced_lock);
|
mutex_unlock(&ftrace_start_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ftrace_shutdown_sysctl(void)
|
static void ftrace_shutdown_sysctl(void)
|
||||||
@ -782,20 +734,20 @@ static void ftrace_shutdown_sysctl(void)
|
|||||||
if (unlikely(ftrace_disabled))
|
if (unlikely(ftrace_disabled))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mutex_lock(&ftraced_lock);
|
mutex_lock(&ftrace_start_lock);
|
||||||
/* ftraced_suspend is true if ftrace is running */
|
/* ftrace_start is true if ftrace is running */
|
||||||
if (ftraced_suspend)
|
if (ftrace_start)
|
||||||
command |= FTRACE_DISABLE_CALLS;
|
command |= FTRACE_DISABLE_CALLS;
|
||||||
|
|
||||||
ftrace_run_update_code(command);
|
ftrace_run_update_code(command);
|
||||||
mutex_unlock(&ftraced_lock);
|
mutex_unlock(&ftrace_start_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cycle_t ftrace_update_time;
|
static cycle_t ftrace_update_time;
|
||||||
static unsigned long ftrace_update_cnt;
|
static unsigned long ftrace_update_cnt;
|
||||||
unsigned long ftrace_update_tot_cnt;
|
unsigned long ftrace_update_tot_cnt;
|
||||||
|
|
||||||
static int __ftrace_update_code(void *ignore)
|
static int ftrace_update_code(void *ignore)
|
||||||
{
|
{
|
||||||
int i, save_ftrace_enabled;
|
int i, save_ftrace_enabled;
|
||||||
cycle_t start, stop;
|
cycle_t start, stop;
|
||||||
@ -869,7 +821,6 @@ static int __ftrace_update_code(void *ignore)
|
|||||||
stop = ftrace_now(raw_smp_processor_id());
|
stop = ftrace_now(raw_smp_processor_id());
|
||||||
ftrace_update_time = stop - start;
|
ftrace_update_time = stop - start;
|
||||||
ftrace_update_tot_cnt += ftrace_update_cnt;
|
ftrace_update_tot_cnt += ftrace_update_cnt;
|
||||||
ftraced_trigger = 0;
|
|
||||||
|
|
||||||
ftrace_enabled = save_ftrace_enabled;
|
ftrace_enabled = save_ftrace_enabled;
|
||||||
ftrace_record_suspend--;
|
ftrace_record_suspend--;
|
||||||
@ -877,17 +828,6 @@ static int __ftrace_update_code(void *ignore)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ftrace_update_code(void)
|
|
||||||
{
|
|
||||||
if (unlikely(ftrace_disabled) ||
|
|
||||||
!ftrace_enabled || !ftraced_trigger)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
stop_machine(__ftrace_update_code, NULL, NULL);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __init ftrace_dyn_table_alloc(unsigned long num_to_init)
|
static int __init ftrace_dyn_table_alloc(unsigned long num_to_init)
|
||||||
{
|
{
|
||||||
struct ftrace_page *pg;
|
struct ftrace_page *pg;
|
||||||
@ -1425,10 +1365,10 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&ftrace_sysctl_lock);
|
mutex_lock(&ftrace_sysctl_lock);
|
||||||
mutex_lock(&ftraced_lock);
|
mutex_lock(&ftrace_start_lock);
|
||||||
if (iter->filtered && ftraced_suspend && ftrace_enabled)
|
if (iter->filtered && ftrace_start && ftrace_enabled)
|
||||||
ftrace_run_update_code(FTRACE_ENABLE_CALLS);
|
ftrace_run_update_code(FTRACE_ENABLE_CALLS);
|
||||||
mutex_unlock(&ftraced_lock);
|
mutex_unlock(&ftrace_start_lock);
|
||||||
mutex_unlock(&ftrace_sysctl_lock);
|
mutex_unlock(&ftrace_sysctl_lock);
|
||||||
|
|
||||||
kfree(iter);
|
kfree(iter);
|
||||||
@ -1448,55 +1388,6 @@ ftrace_notrace_release(struct inode *inode, struct file *file)
|
|||||||
return ftrace_regex_release(inode, file, 0);
|
return ftrace_regex_release(inode, file, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
|
||||||
ftraced_read(struct file *filp, char __user *ubuf,
|
|
||||||
size_t cnt, loff_t *ppos)
|
|
||||||
{
|
|
||||||
/* don't worry about races */
|
|
||||||
char *buf = ftraced_stop ? "disabled\n" : "enabled\n";
|
|
||||||
int r = strlen(buf);
|
|
||||||
|
|
||||||
return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t
|
|
||||||
ftraced_write(struct file *filp, const char __user *ubuf,
|
|
||||||
size_t cnt, loff_t *ppos)
|
|
||||||
{
|
|
||||||
char buf[64];
|
|
||||||
long val;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (cnt >= sizeof(buf))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (copy_from_user(&buf, ubuf, cnt))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
if (strncmp(buf, "enable", 6) == 0)
|
|
||||||
val = 1;
|
|
||||||
else if (strncmp(buf, "disable", 7) == 0)
|
|
||||||
val = 0;
|
|
||||||
else {
|
|
||||||
buf[cnt] = 0;
|
|
||||||
|
|
||||||
ret = strict_strtoul(buf, 10, &val);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
val = !!val;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (val)
|
|
||||||
ftrace_enable_daemon();
|
|
||||||
else
|
|
||||||
ftrace_disable_daemon();
|
|
||||||
|
|
||||||
filp->f_pos += cnt;
|
|
||||||
|
|
||||||
return cnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct file_operations ftrace_avail_fops = {
|
static struct file_operations ftrace_avail_fops = {
|
||||||
.open = ftrace_avail_open,
|
.open = ftrace_avail_open,
|
||||||
.read = seq_read,
|
.read = seq_read,
|
||||||
@ -1527,38 +1418,6 @@ static struct file_operations ftrace_notrace_fops = {
|
|||||||
.release = ftrace_notrace_release,
|
.release = ftrace_notrace_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct file_operations ftraced_fops = {
|
|
||||||
.open = tracing_open_generic,
|
|
||||||
.read = ftraced_read,
|
|
||||||
.write = ftraced_write,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ftrace_force_update - force an update to all recording ftrace functions
|
|
||||||
*/
|
|
||||||
int ftrace_force_update(void)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (unlikely(ftrace_disabled))
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
mutex_lock(&ftrace_sysctl_lock);
|
|
||||||
mutex_lock(&ftraced_lock);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If ftraced_trigger is not set, then there is nothing
|
|
||||||
* to update.
|
|
||||||
*/
|
|
||||||
if (ftraced_trigger && !ftrace_update_code())
|
|
||||||
ret = -EBUSY;
|
|
||||||
|
|
||||||
mutex_unlock(&ftraced_lock);
|
|
||||||
mutex_unlock(&ftrace_sysctl_lock);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __init int ftrace_init_debugfs(void)
|
static __init int ftrace_init_debugfs(void)
|
||||||
{
|
{
|
||||||
struct dentry *d_tracer;
|
struct dentry *d_tracer;
|
||||||
@ -1589,17 +1448,11 @@ static __init int ftrace_init_debugfs(void)
|
|||||||
pr_warning("Could not create debugfs "
|
pr_warning("Could not create debugfs "
|
||||||
"'set_ftrace_notrace' entry\n");
|
"'set_ftrace_notrace' entry\n");
|
||||||
|
|
||||||
entry = debugfs_create_file("ftraced_enabled", 0644, d_tracer,
|
|
||||||
NULL, &ftraced_fops);
|
|
||||||
if (!entry)
|
|
||||||
pr_warning("Could not create debugfs "
|
|
||||||
"'ftraced_enabled' entry\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_initcall(ftrace_init_debugfs);
|
fs_initcall(ftrace_init_debugfs);
|
||||||
|
|
||||||
#ifdef CONFIG_FTRACE_MCOUNT_RECORD
|
|
||||||
static int ftrace_convert_nops(unsigned long *start,
|
static int ftrace_convert_nops(unsigned long *start,
|
||||||
unsigned long *end)
|
unsigned long *end)
|
||||||
{
|
{
|
||||||
@ -1619,7 +1472,7 @@ static int ftrace_convert_nops(unsigned long *start,
|
|||||||
|
|
||||||
/* p is ignored */
|
/* p is ignored */
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
__ftrace_update_code(p);
|
ftrace_update_code(p);
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1666,122 +1519,6 @@ void __init ftrace_init(void)
|
|||||||
failed:
|
failed:
|
||||||
ftrace_disabled = 1;
|
ftrace_disabled = 1;
|
||||||
}
|
}
|
||||||
#else /* CONFIG_FTRACE_MCOUNT_RECORD */
|
|
||||||
|
|
||||||
static void ftrace_release_hash(unsigned long start, unsigned long end)
|
|
||||||
{
|
|
||||||
struct dyn_ftrace *rec;
|
|
||||||
struct hlist_node *t, *n;
|
|
||||||
struct hlist_head *head, temp_list;
|
|
||||||
unsigned long flags;
|
|
||||||
int i, cpu;
|
|
||||||
|
|
||||||
preempt_disable_notrace();
|
|
||||||
|
|
||||||
/* disable incase we call something that calls mcount */
|
|
||||||
cpu = raw_smp_processor_id();
|
|
||||||
per_cpu(ftrace_shutdown_disable_cpu, cpu)++;
|
|
||||||
|
|
||||||
ftrace_hash_lock(flags);
|
|
||||||
|
|
||||||
for (i = 0; i < FTRACE_HASHSIZE; i++) {
|
|
||||||
INIT_HLIST_HEAD(&temp_list);
|
|
||||||
head = &ftrace_hash[i];
|
|
||||||
|
|
||||||
/* all CPUS are stopped, we are safe to modify code */
|
|
||||||
hlist_for_each_entry_safe(rec, t, n, head, node) {
|
|
||||||
if (rec->flags & FTRACE_FL_FREE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((rec->ip >= start) && (rec->ip < end))
|
|
||||||
ftrace_free_rec(rec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ftrace_hash_unlock(flags);
|
|
||||||
|
|
||||||
per_cpu(ftrace_shutdown_disable_cpu, cpu)--;
|
|
||||||
preempt_enable_notrace();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ftraced(void *ignore)
|
|
||||||
{
|
|
||||||
unsigned long usecs;
|
|
||||||
|
|
||||||
while (!kthread_should_stop()) {
|
|
||||||
|
|
||||||
set_current_state(TASK_INTERRUPTIBLE);
|
|
||||||
|
|
||||||
/* check once a second */
|
|
||||||
schedule_timeout(HZ);
|
|
||||||
|
|
||||||
if (unlikely(ftrace_disabled))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
mutex_lock(&ftrace_sysctl_lock);
|
|
||||||
mutex_lock(&ftraced_lock);
|
|
||||||
if (!ftraced_suspend && !ftraced_stop &&
|
|
||||||
ftrace_update_code()) {
|
|
||||||
usecs = nsecs_to_usecs(ftrace_update_time);
|
|
||||||
if (ftrace_update_tot_cnt > 100000) {
|
|
||||||
ftrace_update_tot_cnt = 0;
|
|
||||||
pr_info("hm, dftrace overflow: %lu change%s"
|
|
||||||
" (%lu total) in %lu usec%s\n",
|
|
||||||
ftrace_update_cnt,
|
|
||||||
ftrace_update_cnt != 1 ? "s" : "",
|
|
||||||
ftrace_update_tot_cnt,
|
|
||||||
usecs, usecs != 1 ? "s" : "");
|
|
||||||
FTRACE_WARN_ON_ONCE(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mutex_unlock(&ftraced_lock);
|
|
||||||
mutex_unlock(&ftrace_sysctl_lock);
|
|
||||||
|
|
||||||
ftrace_shutdown_replenish();
|
|
||||||
}
|
|
||||||
__set_current_state(TASK_RUNNING);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __init ftrace_dynamic_init(void)
|
|
||||||
{
|
|
||||||
struct task_struct *p;
|
|
||||||
unsigned long addr;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
addr = (unsigned long)ftrace_record_ip;
|
|
||||||
|
|
||||||
stop_machine(ftrace_dyn_arch_init, &addr, NULL);
|
|
||||||
|
|
||||||
/* ftrace_dyn_arch_init places the return code in addr */
|
|
||||||
if (addr) {
|
|
||||||
ret = (int)addr;
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = ftrace_dyn_table_alloc(NR_TO_INIT);
|
|
||||||
if (ret)
|
|
||||||
goto failed;
|
|
||||||
|
|
||||||
p = kthread_run(ftraced, NULL, "ftraced");
|
|
||||||
if (IS_ERR(p)) {
|
|
||||||
ret = -1;
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
last_ftrace_enabled = ftrace_enabled = 1;
|
|
||||||
ftraced_task = p;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
failed:
|
|
||||||
ftrace_disabled = 1;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
core_initcall(ftrace_dynamic_init);
|
|
||||||
#endif /* CONFIG_FTRACE_MCOUNT_RECORD */
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
# define ftrace_startup() do { } while (0)
|
# define ftrace_startup() do { } while (0)
|
||||||
@ -1801,9 +1538,6 @@ void ftrace_kill(void)
|
|||||||
{
|
{
|
||||||
ftrace_disabled = 1;
|
ftrace_disabled = 1;
|
||||||
ftrace_enabled = 0;
|
ftrace_enabled = 0;
|
||||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
|
||||||
ftraced_suspend = -1;
|
|
||||||
#endif
|
|
||||||
clear_ftrace_function();
|
clear_ftrace_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,13 +99,6 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
|
|||||||
/* passed in by parameter to fool gcc from optimizing */
|
/* passed in by parameter to fool gcc from optimizing */
|
||||||
func();
|
func();
|
||||||
|
|
||||||
/* update the records */
|
|
||||||
ret = ftrace_force_update();
|
|
||||||
if (ret) {
|
|
||||||
printk(KERN_CONT ".. ftraced failed .. ");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some archs *cough*PowerPC*cough* add charachters to the
|
* Some archs *cough*PowerPC*cough* add charachters to the
|
||||||
* start of the function names. We simply put a '*' to
|
* start of the function names. We simply put a '*' to
|
||||||
@ -183,13 +176,6 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr)
|
|||||||
/* make sure msleep has been recorded */
|
/* make sure msleep has been recorded */
|
||||||
msleep(1);
|
msleep(1);
|
||||||
|
|
||||||
/* force the recorded functions to be traced */
|
|
||||||
ret = ftrace_force_update();
|
|
||||||
if (ret) {
|
|
||||||
printk(KERN_CONT ".. ftraced failed .. ");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* start the tracing */
|
/* start the tracing */
|
||||||
ftrace_enabled = 1;
|
ftrace_enabled = 1;
|
||||||
tracer_enabled = 1;
|
tracer_enabled = 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user