Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 188269
b: refs/heads/master
c: 5331d7b
h: refs/heads/master
i:
  188267: 7e8e4cb
v: v3
  • Loading branch information
Frederic Weisbecker committed Mar 10, 2010
1 parent be76815 commit c7c7d05
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 2 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: 61e67fb9d3ed13e6a7f58652ae4979b9c872fa57
refs/heads/master: 5331d7b84613b8325362dde53dc2bff2fb87d351
12 changes: 12 additions & 0 deletions trunk/arch/x86/kernel/cpu/perf_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -1707,3 +1707,15 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)

return entry;
}

void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip)
{
regs->ip = ip;
/*
* perf_arch_fetch_caller_regs adds another call, we need to increment
* the skip level
*/
regs->bp = rewind_frame_pointer(skip + 1);
regs->cs = __KERNEL_CS;
local_save_flags(regs->flags);
}
15 changes: 15 additions & 0 deletions trunk/arch/x86/kernel/dumpstack.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,19 @@ struct stack_frame {
struct stack_frame *next_frame;
unsigned long return_address;
};

static inline unsigned long rewind_frame_pointer(int n)
{
struct stack_frame *frame;

get_bp(frame);

#ifdef CONFIG_FRAME_POINTER
while (n--)
frame = frame->next_frame;
#endif

return (unsigned long)frame;
}

#endif /* DUMPSTACK_H */
42 changes: 41 additions & 1 deletion trunk/include/linux/perf_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ enum perf_callchain_context {
#include <linux/fs.h>
#include <linux/pid_namespace.h>
#include <linux/workqueue.h>
#include <linux/ftrace.h>
#include <asm/atomic.h>

#define PERF_MAX_STACK_DEPTH 255
Expand Down Expand Up @@ -847,6 +848,44 @@ perf_sw_event(u32 event_id, u64 nr, int nmi, struct pt_regs *regs, u64 addr)
__perf_sw_event(event_id, nr, nmi, regs, addr);
}

extern void
perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip);

/*
* Take a snapshot of the regs. Skip ip and frame pointer to
* the nth caller. We only need a few of the regs:
* - ip for PERF_SAMPLE_IP
* - cs for user_mode() tests
* - bp for callchains
* - eflags, for future purposes, just in case
*/
static inline void perf_fetch_caller_regs(struct pt_regs *regs, int skip)
{
unsigned long ip;

memset(regs, 0, sizeof(*regs));

switch (skip) {
case 1 :
ip = CALLER_ADDR0;
break;
case 2 :
ip = CALLER_ADDR1;
break;
case 3 :
ip = CALLER_ADDR2;
break;
case 4:
ip = CALLER_ADDR3;
break;
/* No need to support further for now */
default:
ip = 0;
}

return perf_arch_fetch_caller_regs(regs, ip, skip);
}

extern void __perf_event_mmap(struct vm_area_struct *vma);

static inline void perf_event_mmap(struct vm_area_struct *vma)
Expand Down Expand Up @@ -880,7 +919,8 @@ static inline bool perf_paranoid_kernel(void)
}

extern void perf_event_init(void);
extern void perf_tp_event(int event_id, u64 addr, u64 count, void *record, int entry_size);
extern void perf_tp_event(int event_id, u64 addr, u64 count, void *record,
int entry_size, struct pt_regs *regs);
extern void perf_bp_event(struct perf_event *event, void *data);

#ifndef perf_misc_flags
Expand Down
5 changes: 5 additions & 0 deletions trunk/kernel/perf_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -2786,6 +2786,11 @@ __weak struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
return NULL;
}

__weak
void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip)
{
}

/*
* Output
*/
Expand Down

0 comments on commit c7c7d05

Please sign in to comment.