ftrace: force recording
Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
Родитель
57f50be14d
Коммит
e1c08bdd9f
|
@ -54,6 +54,8 @@ struct dyn_ftrace {
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int ftrace_force_update(void);
|
||||||
|
|
||||||
/* defined in arch */
|
/* defined in arch */
|
||||||
extern int ftrace_ip_converted(unsigned long ip);
|
extern int ftrace_ip_converted(unsigned long ip);
|
||||||
extern unsigned char *ftrace_nop_replace(void);
|
extern unsigned char *ftrace_nop_replace(void);
|
||||||
|
@ -66,6 +68,8 @@ extern int ftrace_update_ftrace_func(ftrace_func_t func);
|
||||||
extern void ftrace_caller(void);
|
extern void ftrace_caller(void);
|
||||||
extern void ftrace_call(void);
|
extern void ftrace_call(void);
|
||||||
extern void mcount_call(void);
|
extern void mcount_call(void);
|
||||||
|
#else
|
||||||
|
# define ftrace_force_update() do { } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline void tracer_disable(void)
|
static inline void tracer_disable(void)
|
||||||
|
|
|
@ -146,6 +146,10 @@ static int notrace __unregister_ftrace_function(struct ftrace_ops *ops)
|
||||||
|
|
||||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||||
|
|
||||||
|
static struct task_struct *ftraced_task;
|
||||||
|
static DECLARE_WAIT_QUEUE_HEAD(ftraced_waiters);
|
||||||
|
static unsigned long ftraced_iteration_counter;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
FTRACE_ENABLE_CALLS = (1 << 0),
|
FTRACE_ENABLE_CALLS = (1 << 0),
|
||||||
FTRACE_DISABLE_CALLS = (1 << 1),
|
FTRACE_DISABLE_CALLS = (1 << 1),
|
||||||
|
@ -590,9 +594,12 @@ static int notrace ftraced(void *ignore)
|
||||||
ftraced_trigger = 0;
|
ftraced_trigger = 0;
|
||||||
ftrace_record_suspend--;
|
ftrace_record_suspend--;
|
||||||
}
|
}
|
||||||
|
ftraced_iteration_counter++;
|
||||||
mutex_unlock(&ftraced_lock);
|
mutex_unlock(&ftraced_lock);
|
||||||
mutex_unlock(&ftrace_sysctl_lock);
|
mutex_unlock(&ftrace_sysctl_lock);
|
||||||
|
|
||||||
|
wake_up_interruptible(&ftraced_waiters);
|
||||||
|
|
||||||
ftrace_shutdown_replenish();
|
ftrace_shutdown_replenish();
|
||||||
|
|
||||||
set_current_state(TASK_INTERRUPTIBLE);
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
|
@ -1050,6 +1057,49 @@ static struct file_operations ftrace_filter_fops = {
|
||||||
.release = ftrace_filter_release,
|
.release = ftrace_filter_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ftrace_force_update - force an update to all recording ftrace functions
|
||||||
|
*
|
||||||
|
* The ftrace dynamic update daemon only wakes up once a second.
|
||||||
|
* There may be cases where an update needs to be done immediately
|
||||||
|
* for tests or internal kernel tracing to begin. This function
|
||||||
|
* wakes the daemon to do an update and will not return until the
|
||||||
|
* update is complete.
|
||||||
|
*/
|
||||||
|
int ftrace_force_update(void)
|
||||||
|
{
|
||||||
|
unsigned long last_counter;
|
||||||
|
DECLARE_WAITQUEUE(wait, current);
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (!ftraced_task)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
mutex_lock(&ftraced_lock);
|
||||||
|
last_counter = ftraced_iteration_counter;
|
||||||
|
|
||||||
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
|
add_wait_queue(&ftraced_waiters, &wait);
|
||||||
|
|
||||||
|
do {
|
||||||
|
mutex_unlock(&ftraced_lock);
|
||||||
|
wake_up_process(ftraced_task);
|
||||||
|
schedule();
|
||||||
|
mutex_lock(&ftraced_lock);
|
||||||
|
if (signal_pending(current)) {
|
||||||
|
ret = -EINTR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
|
} while (last_counter == ftraced_iteration_counter);
|
||||||
|
|
||||||
|
mutex_unlock(&ftraced_lock);
|
||||||
|
remove_wait_queue(&ftraced_waiters, &wait);
|
||||||
|
set_current_state(TASK_RUNNING);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static __init int ftrace_init_debugfs(void)
|
static __init int ftrace_init_debugfs(void)
|
||||||
{
|
{
|
||||||
struct dentry *d_tracer;
|
struct dentry *d_tracer;
|
||||||
|
@ -1095,6 +1145,7 @@ static int __init notrace ftrace_dynamic_init(void)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
last_ftrace_enabled = ftrace_enabled = 1;
|
last_ftrace_enabled = ftrace_enabled = 1;
|
||||||
|
ftraced_task = p;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче