Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 100636
b: refs/heads/master
c: cd2134b
h: refs/heads/master
v: v3
  • Loading branch information
Soeren Sandmann Pedersen authored and Thomas Gleixner committed May 23, 2008
1 parent 4515fb5 commit b93bf65
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 10 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: 5fc4511c756860149b81aead6eca5bdf5c438ea7
refs/heads/master: cd2134b1dda92fd450e6a1e12b1c7960dd6a2178
89 changes: 80 additions & 9 deletions trunk/kernel/trace/trace_sysprof.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include <linux/irq.h>
#include <linux/fs.h>

#include <asm/stacktrace.h>

#include "trace.h"

static struct trace_array *sysprof_trace;
Expand Down Expand Up @@ -52,6 +54,77 @@ static int copy_stack_frame(const void __user *fp, struct stack_frame *frame)
return ret;
}

struct backtrace_info {
struct trace_array_cpu *data;
struct trace_array *tr;
int pos;
};

static void
backtrace_warning_symbol(void *data, char *msg, unsigned long symbol)
{
/* Ignore warnings */
}

static void backtrace_warning(void *data, char *msg)
{
/* Ignore warnings */
}

static int backtrace_stack(void *data, char *name)
{
/* Don't bother with IRQ stacks for now */
return -1;
}

static void backtrace_address(void *data, unsigned long addr, int reliable)
{
struct backtrace_info *info = data;

if (info->pos < sample_max_depth && reliable) {
__trace_special(info->tr, info->data, 1, addr, 0);

info->pos++;
}
}

const static struct stacktrace_ops backtrace_ops = {
.warning = backtrace_warning,
.warning_symbol = backtrace_warning_symbol,
.stack = backtrace_stack,
.address = backtrace_address,
};

static struct pt_regs *
trace_kernel(struct pt_regs *regs, struct trace_array *tr,
struct trace_array_cpu *data)
{
struct backtrace_info info;
unsigned long bp;
char *user_stack;
char *stack;

info.tr = tr;
info.data = data;
info.pos = 1;

__trace_special(info.tr, info.data, 1, regs->ip, 0);

stack = ((char *)regs + sizeof(struct pt_regs));
#ifdef CONFIG_FRAME_POINTER
bp = regs->bp;
#else
bp = 0;
#endif

dump_trace(NULL, regs, (void *)stack, bp, &backtrace_ops, &info);

/* Now trace the user stack */
user_stack = ((char *)current->thread.sp0 - sizeof(struct pt_regs));

return (struct pt_regs *)user_stack;
}

static void timer_notify(struct pt_regs *regs, int cpu)
{
struct trace_array_cpu *data;
Expand All @@ -74,17 +147,15 @@ static void timer_notify(struct pt_regs *regs, int cpu)
if (is_user && current->state != TASK_RUNNING)
return;

if (!is_user) {
/* kernel */
ftrace(tr, data, current->pid, 1, 0);
return;
__trace_special(tr, data, 0, 0, current->pid);

}

__trace_special(tr, data, 0, current->pid, regs->ip);
if (!is_user)
regs = trace_kernel(regs, tr, data);

fp = (void __user *)regs->bp;

__trace_special(tr, data, 2, regs->ip, 0);

for (i = 0; i < sample_max_depth; i++) {
frame.next_fp = 0;
frame.return_address = 0;
Expand All @@ -93,12 +164,12 @@ static void timer_notify(struct pt_regs *regs, int cpu)
if ((unsigned long)fp < regs->sp)
break;

__trace_special(tr, data, 1, frame.return_address,
__trace_special(tr, data, 2, frame.return_address,
(unsigned long)fp);
fp = frame.next_fp;
}

__trace_special(tr, data, 2, current->pid, i);
__trace_special(tr, data, 3, current->pid, i);

/*
* Special trace entry if we overflow the max depth:
Expand Down

0 comments on commit b93bf65

Please sign in to comment.