MIPS: adding support for software performance events
PATCH v2 3/4 MIPS: adding support for software performance events
Software events are required as a part of the measurable stuff by the Linux performance counter subsystem. Here is the list of events added by this patch:PERF_COUNT_SW_PAGE_FAULTSPERF_COUNT_SW_PAGE_FAULTS_MINPERF_COUNT_SW_PAGE_FAULTS_MAJPERF_COUNT_SW_ALIGNMENT_FAULTS PERF_COUNT_SW_EMULATION_FAULTS
Signed-off-by Deng-Cheng Zhu <[email protected]>
--- arch/mips/Kconfig | 2 ++ arch/mips/kernel/traps.c | 18 +++++++++++++++--- arch/mips/kernel/unaligned.c | 5 +++++ arch/mips/math-emu/cp1emu.c | 3 +++ arch/mips/mm/fault.c | 11 +++++++++-- 5 files changed, 34 insertions(+), 5 deletions(-)
arch/mips/Kconfig +2 -0
@@ -4,6 +4,8 @@ config MIPS select HAVE_GENERIC_DMA_COHERENT select HAVE_IDE select HAVE_OPROFILE + select HAVE_PERF_EVENTS + select PERF_USE_VMALLOC select GENERIC_ATOMIC64 if !64BIT select HAVE_ARCH_KGDB select HAVE_FUNCTION_TRACER
arch/mips/kernel/traps.c +15 -3
@@ -26,6 +26,7 @@#include <linux/kgdb.h> #include <linux/kdebug.h> #include <linux/notifier.h> +#include <linux/perf_event.h> #include <asm/bootinfo.h> #include <asm/branch.h>
@@ -557,10 +558,16 @@ static inline int simulate_sc(struct pt_regs *regs, unsigned int opcode)*/ static int simulate_llsc (struct pt_regs *regs,unsigned int opcode) { -if ((opcode &OPCODE ) ==LL ) +if ((opcode &OPCODE ) ==LL ) { +perf_sw_event (PERF_COUNT_SW_EMULATION_FAULTS , +1 ,0 , regs,0 );return simulate_ll (regs, opcode); -if ((opcode &OPCODE ) ==SC ) + } +if ((opcode &OPCODE ) ==SC ) { +perf_sw_event (PERF_COUNT_SW_EMULATION_FAULTS , +1 ,0 , regs,0 );return simulate_sc (regs, opcode); + }return -1 ;/* Must be something else ... */ }
@@ -576,6 +583,8 @@ static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode)if ((opcode &OPCODE ) ==SPEC3 && (opcode &FUNC ) ==RDHWR ) {int rd = (opcode &RD ) >>11 ;int rt = (opcode &RT ) >>16 ; +perf_sw_event (PERF_COUNT_SW_EMULATION_FAULTS , +1 ,0 , regs,0 );switch (rd) {case 0 :/* CPU number */ regs->regs[rt] =smp_processor_id ();
@@ -611,8 +620,11 @@ static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode)static int simulate_sync (struct pt_regs *regs,unsigned int opcode) { -if ((opcode &OPCODE ) ==SPEC0 && (opcode &FUNC ) ==SYNC ) +if ((opcode &OPCODE ) ==SPEC0 && (opcode &FUNC ) ==SYNC ) { +perf_sw_event (PERF_COUNT_SW_EMULATION_FAULTS , +1 ,0 , regs,0 );return 0 ; + }return -1 ;/* Must be something else ... */ }
arch/mips/kernel/unaligned.c +5 -0
@@ -78,6 +78,7 @@#include <linux/smp.h> #include <linux/sched.h> #include <linux/debugfs.h> +#include <linux/perf_event.h> #include <asm/asm.h> #include <asm/branch.h> #include <asm/byteorder.h>
@@ -109,6 +110,8 @@ static void emulate_load_store_insn(struct pt_regs *regs,unsigned long value;unsigned int res; +perf_sw_event (PERF_COUNT_SW_EMULATION_FAULTS , +1 ,0 , regs,0 ); regs->regs[0 ] =0 ;/*
@@ -513,6 +516,8 @@ asmlinkage void do_ade(struct pt_regs *regs)unsigned int __user *pc;mm_segment_t seg; +perf_sw_event (PERF_COUNT_SW_ALIGNMENT_FAULTS , +1 ,0 , regs, regs->cp0_badvaddr);/* * Did we catch a fault trying to load an instruction? * Or are we running in MIPS16 mode?
arch/mips/math-emu/cp1emu.c +3 -0
@@ -37,6 +37,7 @@#include <linux/sched.h> #include <linux/module.h> #include <linux/debugfs.h> +#include <linux/perf_event.h> #include <asm/inst.h> #include <asm/bootinfo.h>
@@ -256,6 +257,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) } emul: +perf_sw_event (PERF_COUNT_SW_EMULATION_FAULTS , +1 ,0 , xcp,0 );MIPS_FPU_EMU_INC_STATS (emulated);switch (MIPSInst_OPCODE (ir)) {case ldc1_op:{
arch/mips/mm/fault.c +9 -2
@@ -18,6 +18,7 @@#include <linux/smp.h> #include <linux/vt_kern.h> /* For unblank_screen() */ #include <linux/module.h> +#include <linux/perf_event.h> #include <asm/branch.h> #include <asm/mmu_context.h>
@@ -132,6 +133,7 @@ good_area:* the fault. */ fault =handle_mm_fault (mm, vma, address, write ?FAULT_FLAG_WRITE :0 ); +perf_sw_event (PERF_COUNT_SW_PAGE_FAULTS ,1 ,0 , regs, address);if (unlikely (fault &VM_FAULT_ERROR )) {if (fault &VM_FAULT_OOM ) goto out_of_memory;
@@ -139,10 +141,15 @@ good_area: goto do_sigbus;BUG (); } -if (fault &VM_FAULT_MAJOR ) +if (fault &VM_FAULT_MAJOR ) { +perf_sw_event (PERF_COUNT_SW_PAGE_FAULTS_MAJ , +1 ,0 , regs, address); tsk->maj_flt++; -else + }else { +perf_sw_event (PERF_COUNT_SW_PAGE_FAULTS_MIN , +1 ,0 , regs, address); tsk->min_flt++; + }up_read (&mm->mmap_sem);return ;
Signature · 1 line
1.7.0.4