Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 121177
b: refs/heads/master
c: cbe2f5a
h: refs/heads/master
i:
  121175: c87ab2e
v: v3
  • Loading branch information
Ingo Molnar committed Nov 23, 2008
1 parent f179993 commit 7fc5fea
Show file tree
Hide file tree
Showing 12 changed files with 63 additions and 153 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 65afa5e603d507014580ead016ec887b49e1afa6
refs/heads/master: cbe2f5a6e84eebb98ab42fc5e58c3cd5b7767349
1 change: 1 addition & 0 deletions trunk/arch/x86/include/asm/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ struct dyn_arch_ftrace {
#endif /* CONFIG_FUNCTION_TRACER */

#ifdef CONFIG_FUNCTION_RET_TRACER
#define FTRACE_RET_STACK_SIZE 20

#ifndef __ASSEMBLY__

Expand Down
29 changes: 29 additions & 0 deletions trunk/arch/x86/include/asm/thread_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,36 @@ struct thread_info {
*/
__u8 supervisor_stack[0];
#endif

#ifdef CONFIG_FUNCTION_RET_TRACER
/* Index of current stored adress in ret_stack */
int curr_ret_stack;
/* Stack of return addresses for return function tracing */
struct ftrace_ret_stack ret_stack[FTRACE_RET_STACK_SIZE];
/*
* Number of functions that haven't been traced
* because of depth overrun.
*/
atomic_t trace_overrun;
#endif
};

#ifdef CONFIG_FUNCTION_RET_TRACER
#define INIT_THREAD_INFO(tsk) \
{ \
.task = &tsk, \
.exec_domain = &default_exec_domain, \
.flags = 0, \
.cpu = 0, \
.preempt_count = 1, \
.addr_limit = KERNEL_DS, \
.restart_block = { \
.fn = do_no_restart_syscall, \
}, \
.curr_ret_stack = -1,\
.trace_overrun = ATOMIC_INIT(0) \
}
#else
#define INIT_THREAD_INFO(tsk) \
{ \
.task = &tsk, \
Expand All @@ -54,6 +82,7 @@ struct thread_info {
.fn = do_no_restart_syscall, \
}, \
}
#endif

#define init_thread_info (init_thread_union.thread_info)
#define init_stack (init_thread_union.stack)
Expand Down
29 changes: 14 additions & 15 deletions trunk/arch/x86/kernel/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,21 +350,19 @@ static int push_return_trace(unsigned long ret, unsigned long long time,
unsigned long func)
{
int index;

if (!current->ret_stack)
return -EBUSY;
struct thread_info *ti = current_thread_info();

/* The return trace stack is full */
if (current->curr_ret_stack == FTRACE_RETFUNC_DEPTH - 1) {
atomic_inc(&current->trace_overrun);
if (ti->curr_ret_stack == FTRACE_RET_STACK_SIZE - 1) {
atomic_inc(&ti->trace_overrun);
return -EBUSY;
}

index = ++current->curr_ret_stack;
index = ++ti->curr_ret_stack;
barrier();
current->ret_stack[index].ret = ret;
current->ret_stack[index].func = func;
current->ret_stack[index].calltime = time;
ti->ret_stack[index].ret = ret;
ti->ret_stack[index].func = func;
ti->ret_stack[index].calltime = time;

return 0;
}
Expand All @@ -375,12 +373,13 @@ static void pop_return_trace(unsigned long *ret, unsigned long long *time,
{
int index;

index = current->curr_ret_stack;
*ret = current->ret_stack[index].ret;
*func = current->ret_stack[index].func;
*time = current->ret_stack[index].calltime;
*overrun = atomic_read(&current->trace_overrun);
current->curr_ret_stack--;
struct thread_info *ti = current_thread_info();
index = ti->curr_ret_stack;
*ret = ti->ret_stack[index].ret;
*func = ti->ret_stack[index].func;
*time = ti->ret_stack[index].calltime;
*overrun = atomic_read(&ti->trace_overrun);
ti->curr_ret_stack--;
}

/*
Expand Down
8 changes: 0 additions & 8 deletions trunk/include/linux/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -323,21 +323,13 @@ struct ftrace_retfunc {
};

#ifdef CONFIG_FUNCTION_RET_TRACER
#define FTRACE_RETFUNC_DEPTH 50
#define FTRACE_RETSTACK_ALLOC_SIZE 32
/* Type of a callback handler of tracing return function */
typedef void (*trace_function_return_t)(struct ftrace_retfunc *);

extern int register_ftrace_return(trace_function_return_t func);
/* The current handler in use */
extern trace_function_return_t ftrace_function_return;
extern void unregister_ftrace_return(void);

extern void ftrace_retfunc_init_task(struct task_struct *t);
extern void ftrace_retfunc_exit_task(struct task_struct *t);
#else
static inline void ftrace_retfunc_init_task(struct task_struct *t) { }
static inline void ftrace_retfunc_exit_task(struct task_struct *t) { }
#endif

#endif /* _LINUX_FTRACE_H */
23 changes: 12 additions & 11 deletions trunk/include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -1352,17 +1352,6 @@ struct task_struct {
unsigned long default_timer_slack_ns;

struct list_head *scm_work_list;
#ifdef CONFIG_FUNCTION_RET_TRACER
/* Index of current stored adress in ret_stack */
int curr_ret_stack;
/* Stack of return addresses for return function tracing */
struct ftrace_ret_stack *ret_stack;
/*
* Number of functions that haven't been traced
* because of depth overrun.
*/
atomic_t trace_overrun;
#endif
};

/*
Expand Down Expand Up @@ -2017,6 +2006,18 @@ static inline void setup_thread_stack(struct task_struct *p, struct task_struct
{
*task_thread_info(p) = *task_thread_info(org);
task_thread_info(p)->task = p;

#ifdef CONFIG_FUNCTION_RET_TRACER
/*
* When fork() creates a child process, this function is called.
* But the child task may not inherit the return adresses traced
* by the return function tracer because it will directly execute
* in userspace and will not return to kernel functions its parent
* used.
*/
task_thread_info(p)->curr_ret_stack = -1;
atomic_set(&task_thread_info(p)->trace_overrun, 0);
#endif
}

static inline unsigned long *end_of_stack(struct task_struct *p)
Expand Down
1 change: 1 addition & 0 deletions trunk/kernel/exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1127,6 +1127,7 @@ NORET_TYPE void do_exit(long code)
preempt_disable();
/* causes final put_task_struct in finish_task_switch(). */
tsk->state = TASK_DEAD;

schedule();
BUG();
/* Avoid "noreturn function does return". */
Expand Down
3 changes: 0 additions & 3 deletions trunk/kernel/fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
#include <linux/mount.h>
#include <linux/audit.h>
#include <linux/memcontrol.h>
#include <linux/ftrace.h>
#include <linux/profile.h>
#include <linux/rmap.h>
#include <linux/acct.h>
Expand Down Expand Up @@ -140,7 +139,6 @@ void free_task(struct task_struct *tsk)
prop_local_destroy_single(&tsk->dirties);
free_thread_info(tsk->stack);
rt_mutex_debug_task_free(tsk);
ftrace_retfunc_exit_task(tsk);
free_task_struct(tsk);
}
EXPORT_SYMBOL(free_task);
Expand Down Expand Up @@ -1271,7 +1269,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
total_forks++;
spin_unlock(&current->sighand->siglock);
write_unlock_irq(&tasklist_lock);
ftrace_retfunc_init_task(p);
proc_fork_connector(p);
cgroup_post_fork(p);
return p;
Expand Down
13 changes: 3 additions & 10 deletions trunk/kernel/power/disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#include <linux/console.h>
#include <linux/cpu.h>
#include <linux/freezer.h>
#include <linux/ftrace.h>

#include "power.h"

Expand Down Expand Up @@ -257,7 +256,7 @@ static int create_image(int platform_mode)

int hibernation_snapshot(int platform_mode)
{
int error, ftrace_save;
int error;

/* Free memory before shutting down devices. */
error = swsusp_shrink_memory();
Expand All @@ -269,7 +268,6 @@ int hibernation_snapshot(int platform_mode)
goto Close;

suspend_console();
ftrace_save = __ftrace_enabled_save();
error = device_suspend(PMSG_FREEZE);
if (error)
goto Recover_platform;
Expand Down Expand Up @@ -299,7 +297,6 @@ int hibernation_snapshot(int platform_mode)
Resume_devices:
device_resume(in_suspend ?
(error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
__ftrace_enabled_restore(ftrace_save);
resume_console();
Close:
platform_end(platform_mode);
Expand Down Expand Up @@ -370,11 +367,10 @@ static int resume_target_kernel(void)

int hibernation_restore(int platform_mode)
{
int error, ftrace_save;
int error;

pm_prepare_console();
suspend_console();
ftrace_save = __ftrace_enabled_save();
error = device_suspend(PMSG_QUIESCE);
if (error)
goto Finish;
Expand All @@ -389,7 +385,6 @@ int hibernation_restore(int platform_mode)
platform_restore_cleanup(platform_mode);
device_resume(PMSG_RECOVER);
Finish:
__ftrace_enabled_restore(ftrace_save);
resume_console();
pm_restore_console();
return error;
Expand All @@ -402,7 +397,7 @@ int hibernation_restore(int platform_mode)

int hibernation_platform_enter(void)
{
int error, ftrace_save;
int error;

if (!hibernation_ops)
return -ENOSYS;
Expand All @@ -417,7 +412,6 @@ int hibernation_platform_enter(void)
goto Close;

suspend_console();
ftrace_save = __ftrace_enabled_save();
error = device_suspend(PMSG_HIBERNATE);
if (error) {
if (hibernation_ops->recover)
Expand Down Expand Up @@ -452,7 +446,6 @@ int hibernation_platform_enter(void)
hibernation_ops->finish();
Resume_devices:
device_resume(PMSG_RESTORE);
__ftrace_enabled_restore(ftrace_save);
resume_console();
Close:
hibernation_ops->end();
Expand Down
5 changes: 1 addition & 4 deletions trunk/kernel/power/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#include <linux/freezer.h>
#include <linux/vmstat.h>
#include <linux/syscalls.h>
#include <linux/ftrace.h>

#include "power.h"

Expand Down Expand Up @@ -317,7 +316,7 @@ static int suspend_enter(suspend_state_t state)
*/
int suspend_devices_and_enter(suspend_state_t state)
{
int error, ftrace_save;
int error;

if (!suspend_ops)
return -ENOSYS;
Expand All @@ -328,7 +327,6 @@ int suspend_devices_and_enter(suspend_state_t state)
goto Close;
}
suspend_console();
ftrace_save = __ftrace_enabled_save();
suspend_test_start();
error = device_suspend(PMSG_SUSPEND);
if (error) {
Expand Down Expand Up @@ -360,7 +358,6 @@ int suspend_devices_and_enter(suspend_state_t state)
suspend_test_start();
device_resume(PMSG_RESUME);
suspend_test_finish("resume devices");
__ftrace_enabled_restore(ftrace_save);
resume_console();
Close:
if (suspend_ops->end)
Expand Down
1 change: 0 additions & 1 deletion trunk/kernel/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -5901,7 +5901,6 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)
* The idle tasks have their own, simple scheduling class:
*/
idle->sched_class = &idle_sched_class;
ftrace_retfunc_init_task(idle);
}

/*
Expand Down
Loading

0 comments on commit 7fc5fea

Please sign in to comment.