Loading include/linux/ftrace.h +4 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,8 @@ struct dyn_ftrace { unsigned long flags; }; int ftrace_force_update(void); /* defined in arch */ extern int ftrace_ip_converted(unsigned long ip); extern unsigned char *ftrace_nop_replace(void); Loading @@ -66,6 +68,8 @@ extern int ftrace_update_ftrace_func(ftrace_func_t func); extern void ftrace_caller(void); extern void ftrace_call(void); extern void mcount_call(void); #else # define ftrace_force_update() do { } while (0) #endif static inline void tracer_disable(void) Loading kernel/trace/ftrace.c +51 −0 Original line number Diff line number Diff line Loading @@ -146,6 +146,10 @@ static int notrace __unregister_ftrace_function(struct ftrace_ops *ops) #ifdef CONFIG_DYNAMIC_FTRACE static struct task_struct *ftraced_task; static DECLARE_WAIT_QUEUE_HEAD(ftraced_waiters); static unsigned long ftraced_iteration_counter; enum { FTRACE_ENABLE_CALLS = (1 << 0), FTRACE_DISABLE_CALLS = (1 << 1), Loading Loading @@ -590,9 +594,12 @@ static int notrace ftraced(void *ignore) ftraced_trigger = 0; ftrace_record_suspend--; } ftraced_iteration_counter++; mutex_unlock(&ftraced_lock); mutex_unlock(&ftrace_sysctl_lock); wake_up_interruptible(&ftraced_waiters); ftrace_shutdown_replenish(); set_current_state(TASK_INTERRUPTIBLE); Loading Loading @@ -1050,6 +1057,49 @@ static struct file_operations ftrace_filter_fops = { .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) { struct dentry *d_tracer; Loading Loading @@ -1095,6 +1145,7 @@ static int __init notrace ftrace_dynamic_init(void) return -1; last_ftrace_enabled = ftrace_enabled = 1; ftraced_task = p; return 0; } Loading Loading
include/linux/ftrace.h +4 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,8 @@ struct dyn_ftrace { unsigned long flags; }; int ftrace_force_update(void); /* defined in arch */ extern int ftrace_ip_converted(unsigned long ip); extern unsigned char *ftrace_nop_replace(void); Loading @@ -66,6 +68,8 @@ extern int ftrace_update_ftrace_func(ftrace_func_t func); extern void ftrace_caller(void); extern void ftrace_call(void); extern void mcount_call(void); #else # define ftrace_force_update() do { } while (0) #endif static inline void tracer_disable(void) Loading
kernel/trace/ftrace.c +51 −0 Original line number Diff line number Diff line Loading @@ -146,6 +146,10 @@ static int notrace __unregister_ftrace_function(struct ftrace_ops *ops) #ifdef CONFIG_DYNAMIC_FTRACE static struct task_struct *ftraced_task; static DECLARE_WAIT_QUEUE_HEAD(ftraced_waiters); static unsigned long ftraced_iteration_counter; enum { FTRACE_ENABLE_CALLS = (1 << 0), FTRACE_DISABLE_CALLS = (1 << 1), Loading Loading @@ -590,9 +594,12 @@ static int notrace ftraced(void *ignore) ftraced_trigger = 0; ftrace_record_suspend--; } ftraced_iteration_counter++; mutex_unlock(&ftraced_lock); mutex_unlock(&ftrace_sysctl_lock); wake_up_interruptible(&ftraced_waiters); ftrace_shutdown_replenish(); set_current_state(TASK_INTERRUPTIBLE); Loading Loading @@ -1050,6 +1057,49 @@ static struct file_operations ftrace_filter_fops = { .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) { struct dentry *d_tracer; Loading Loading @@ -1095,6 +1145,7 @@ static int __init notrace ftrace_dynamic_init(void) return -1; last_ftrace_enabled = ftrace_enabled = 1; ftraced_task = p; return 0; } Loading