This is the minimal support for the SW perf events, required as a part of the measurable stuff by the Linux performance counter subsystem. Signed-off-by: Deng-Cheng Zhu <dengcheng.zhu@xxxxxxxxx> --- arch/mips/Kconfig | 2 ++ arch/mips/include/asm/perf_event.h | 28 ++++++++++++++++++++++++++++ arch/mips/mm/fault.c | 11 +++++++++-- 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 arch/mips/include/asm/perf_event.h diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 7161751..cf33418 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -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 select HAVE_ARCH_KGDB select HAVE_FUNCTION_TRACER diff --git a/arch/mips/include/asm/perf_event.h b/arch/mips/include/asm/perf_event.h new file mode 100644 index 0000000..bcf54bc --- /dev/null +++ b/arch/mips/include/asm/perf_event.h @@ -0,0 +1,28 @@ +/* + * linux/arch/mips/include/asm/perf_event.h + * + * Copyright (C) 2010 MIPS Technologies, Inc. Deng-Cheng Zhu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __MIPS_PERF_EVENT_H__ +#define __MIPS_PERF_EVENT_H__ + +extern int (*perf_irq)(void); + +/* + * MIPS performance counters do not raise NMI upon overflow, a regular + * interrupt will be signaled. Hence we can do the pending perf event + * work at the tail of the irq handler. + */ +static inline void +set_perf_event_pending(void) +{ +} + +#endif /* __MIPS_PERF_EVENT_H__ */ + diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index b78f7d9..5987d2b 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c @@ -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; -- 1.7.0.4