Skip to content

Commit

Permalink
sh: Hook up page fault events for software perf counters.
Browse files Browse the repository at this point in the history
This adds page fault instrumentation for the software performance
counters. Follows the x86 and powerpc changes.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
  • Loading branch information
Paul Mundt committed Jun 24, 2009
1 parent d94d4ad commit 7433ab7
Showing 1 changed file with 32 additions and 29 deletions.
61 changes: 32 additions & 29 deletions arch/sh/mm/fault_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,28 @@
#include <linux/mm.h>
#include <linux/hardirq.h>
#include <linux/kprobes.h>
#include <linux/marker.h>
#include <linux/perf_counter.h>
#include <asm/io_trapped.h>
#include <asm/system.h>
#include <asm/mmu_context.h>
#include <asm/tlbflush.h>

static inline int notify_page_fault(struct pt_regs *regs, int trap)
{
int ret = 0;

#ifdef CONFIG_KPROBES
if (!user_mode(regs)) {
preempt_disable();
if (kprobe_running() && kprobe_fault_handler(regs, trap))
ret = 1;
preempt_enable();
}
#endif

return ret;
}

/*
* This routine handles page faults. It determines the address,
* and the problem, and then passes it off to one of the appropriate
Expand Down Expand Up @@ -87,13 +103,16 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
return;
}

mm = tsk->mm;

if (unlikely(notify_page_fault(regs, lookup_exception_vector())))
return;

/* Only enable interrupts if they were on before the fault */
if ((regs->sr & SR_IMASK) != SR_IMASK) {
trace_hardirqs_on();
if ((regs->sr & SR_IMASK) != SR_IMASK)
local_irq_enable();
}

mm = tsk->mm;
perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);

/*
* If we're in an interrupt or have no user
Expand Down Expand Up @@ -141,10 +160,15 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
goto do_sigbus;
BUG();
}
if (fault & VM_FAULT_MAJOR)
if (fault & VM_FAULT_MAJOR) {
tsk->maj_flt++;
else
perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
regs, address);
} else {
tsk->min_flt++;
perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
regs, address);
}

up_read(&mm->mmap_sem);
return;
Expand Down Expand Up @@ -245,22 +269,6 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
goto no_context;
}

static inline int notify_page_fault(struct pt_regs *regs, int trap)
{
int ret = 0;

#ifdef CONFIG_KPROBES
if (!user_mode(regs)) {
preempt_disable();
if (kprobe_running() && kprobe_fault_handler(regs, trap))
ret = 1;
preempt_enable();
}
#endif

return ret;
}

/*
* Called with interrupts disabled.
*/
Expand All @@ -273,12 +281,7 @@ asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs,
pmd_t *pmd;
pte_t *pte;
pte_t entry;
int ret = 0;

if (notify_page_fault(regs, lookup_exception_vector()))
goto out;

ret = 1;
int ret = 1;

/*
* We don't take page faults for P1, P2, and parts of P4, these
Expand Down

0 comments on commit 7433ab7

Please sign in to comment.