nds32: Perf Support
Subsystems (2)
v3 cover nds32: Perf Support
* Sorry everyone, I forgot to add the version number of the patch set I just sent.
These four commits are perf supporting for nds32. There are three perfomance counters in nds32, and each of them can counts different events. You can use 'perf list' to show the available events that can be used.
Changes in V2:
1. Change the definition 'PFM_CTL_xxx' to
array form.
2. Simplify the PMU driver.
3. Stop all counters when handling irq
caused by performance counters overflow.
4. Rename the compatible string in
devicetree.
Changes in V3:
Fix the typo in Documentation/devicetree/bindings/nds32/pmu.txt.
Nickhu (4):
nds32: Fix bug in bitfield.h
nds32: Perf porting
nds32: Add perf call-graph support.
nds32: Add document for NDS32 PMU.
.../devicetree/bindings/nds32/pmu.txt | 17 + arch/nds32/Kconfig | 1 + arch/nds32/boot/dts/ae3xx.dts | 5 + arch/nds32/include/asm/Kbuild | 1 + arch/nds32/include/asm/bitfield.h | 4 +- arch/nds32/include/asm/perf_event.h | 16 + arch/nds32/include/asm/pmu.h | 386 +++++ arch/nds32/include/asm/stacktrace.h | 39 + arch/nds32/kernel/Makefile | 3 +- arch/nds32/kernel/perf_event_cpu.c | 1522 +++++++++++++++++ arch/nds32/mm/fault.c | 13 +- tools/include/asm/barrier.h | 2 + tools/perf/arch/nds32/Build | 1 + tools/perf/arch/nds32/util/Build | 1 + tools/perf/arch/nds32/util/header.c | 29 + tools/perf/pmu-events/arch/nds32/mapfile.csv | 15 + .../pmu-events/arch/nds32/n13/atcpmu.json | 290 ++++ 17 files changed, 2337 insertions(+), 8 deletions(-) create mode 100644 Documentation/devicetree/bindings/nds32/pmu.txt create mode 100644 arch/nds32/include/asm/perf_event.h create mode 100644 arch/nds32/include/asm/pmu.h create mode 100644 arch/nds32/include/asm/stacktrace.h create mode 100644 arch/nds32/kernel/perf_event_cpu.c create mode 100644 tools/perf/arch/nds32/Build create mode 100644 tools/perf/arch/nds32/util/Build create mode 100644 tools/perf/arch/nds32/util/header.c create mode 100644 tools/perf/pmu-events/arch/nds32/mapfile.csv create mode 100644 tools/perf/pmu-events/arch/nds32/n13/atcpmu.json
Signature · 1 line
2.17.0
PATCH v3 1/4 nds32: Fix bug in bitfield.h
There two bitfield bug for perfomance counter
in bitfield.h:
PFM_CTL_offSEL1 21 --> 16 PFM_CTL_offSEL2 27 --> 22
This commit fix it.
--- arch/nds32/include/asm/bitfield.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/nds32/include/asm/bitfield.h +2 -2
@@ -692,8 +692,8 @@#define PFM_CTL_offKU1 13/* Enable user mode event counting for PFMC1 */ #define PFM_CTL_offKU2 14/* Enable user mode event counting for PFMC2 */ #define PFM_CTL_offSEL0 15/* The event selection for PFMC0 */ -#define PFM_CTL_offSEL1 21/* The event selection for PFMC1 */ -#define PFM_CTL_offSEL2 27/* The event selection for PFMC2 */ +#define PFM_CTL_offSEL1 16/* The event selection for PFMC1 */ +#define PFM_CTL_offSEL2 22/* The event selection for PFMC2 */ /* bit 28:31 reserved */ #define PFM_CTL_mskEN0 ( 0x01 << PFM_CTL_offEN0 )
Signature · 1 line
2.17.0
PATCH v3 2/4 nds32: Perf porting
In reply to NickhuThis is the commit that porting the perf for nds32.
1.Raw event:
The raw events start with 'r'.
Usage:
perf stat -e rXYZ ./app
X: the index of performance counter.
YZ: the index(convert to hexdecimal) of events
Example:
'perf stat -e r101 ./app' means the counter 1 will count the instruction
event.
The index of counter and events can be found in "Andes System Privilege Architecture Version 3 Manual".
Or you can perform the 'perf list' to find the symbolic name of raw events.
2.Perf mmap2:
Fix unexpected perf mmap2() page fault
When the mmap2() called by perf application, you will encounter such condition:"failed to write." With return value -EFAULT
This is due to the page fault caused by "reading" buffer from the mapped legal address region to write to the descriptor. The page_fault handler will get a VM_FAULT_SIGBUS return value, which should not happens here.(Due to this is a read request.)
You can refer to kernel/events/core.c:perf_mmap_fault(...) If "(vmf->pgoff && (vmf->flags & FAULT_FLAG_WRITE))" is evaluated as true, you will get VM_FAULT_SIGBUS as return value.
However, this is not an write request. The flags which indicated why the page fault happens is wrong.
Furthermore, NDS32 SPAv3 is not able to detect it is read or write. It only know either it is instruction fetch or data access.
Therefore, by removing the wrong flag assignment(actually, the hardware is not able to show the reason), we can fix this bug.
3.Perf multiple events map to same counter.
When there are multiple events map to the same counter, the counter counts inaccurately. This is because each counter only counts one event in the same time.
So when there are multiple events map to same counter, they have to take turns in each context.
There are two solution:
1. Print the error message when multiple events map to the same counter. But print the error message would let the program hang in loop. The ltp (linux test program) would be failed when the program hang in loop.
2. Don't print the error message, the ltp would pass. But the user need to have the knowledge that don't count the events which map to the same counter, or the user will get the inaccurate results.
We choose method 2 for the solution
--- arch/nds32/Kconfig | 1 + arch/nds32/boot/dts/ae3xx.dts | 5 + arch/nds32/include/asm/Kbuild | 1 + arch/nds32/include/asm/perf_event.h | 16 + arch/nds32/include/asm/pmu.h | 386 ++++++ arch/nds32/include/asm/stacktrace.h | 39 + arch/nds32/kernel/Makefile | 3 +- arch/nds32/kernel/perf_event_cpu.c | 1223 +++++++++++++++++ arch/nds32/mm/fault.c | 13 +- tools/include/asm/barrier.h | 2 + tools/perf/arch/nds32/Build | 1 + tools/perf/arch/nds32/util/Build | 1 + tools/perf/arch/nds32/util/header.c | 29 + tools/perf/pmu-events/arch/nds32/mapfile.csv | 15 + .../pmu-events/arch/nds32/n13/atcpmu.json | 290 ++++ 15 files changed, 2019 insertions(+), 6 deletions(-) create mode 100644 arch/nds32/include/asm/perf_event.h create mode 100644 arch/nds32/include/asm/pmu.h create mode 100644 arch/nds32/include/asm/stacktrace.h create mode 100644 arch/nds32/kernel/perf_event_cpu.c create mode 100644 tools/perf/arch/nds32/Build create mode 100644 tools/perf/arch/nds32/util/Build create mode 100644 tools/perf/arch/nds32/util/header.c create mode 100644 tools/perf/pmu-events/arch/nds32/mapfile.csv create mode 100644 tools/perf/pmu-events/arch/nds32/n13/atcpmu.json
arch/nds32/Kconfig +1 -0
@@ -31,6 +31,7 @@ config NDS32 select HAVE_DEBUG_KMEMLEAK select HAVE_MEMBLOCK select HAVE_REGS_AND_STACK_ACCESS_API + select HAVE_PERF_EVENTS select IRQ_DOMAIN select LOCKDEP_SUPPORT select MODULES_USE_ELF_RELA
arch/nds32/boot/dts/ae3xx.dts +5 -0
@@ -82,4 +82,9 @@ interrupts = <18>; }; }; + + pmu { + compatible = "andestech,nds32v3-pmu"; + interrupts= <13>; + }; };
arch/nds32/include/asm/Kbuild +1 -0
@@ -36,6 +36,7 @@ generic-y += kprobes.h generic-y += kvm_para.h generic-y += limits.h generic-y += local.h +generic-y += local64.h generic-y += mm-arch-hooks.h generic-y += mman.h generic-y += parport.h
arch/nds32/include/asm/perf_event.h new file +16 -0
@@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2008-2018 Andes Technology Corporation */ + +#ifndef __ASM_PERF_EVENT_H +#define __ASM_PERF_EVENT_H + +/* +* This file is request by Perf, +* please refer to tools/perf/design.txt for more details +*/ +struct pt_regs ; +unsigned long perf_instruction_pointer (struct pt_regs *regs); +unsigned long perf_misc_flags (struct pt_regs *regs); +#define perf_misc_flags (regs) perf_misc_flags(regs) + +#endif
arch/nds32/include/asm/pmu.h new file +386 -0
386 lines not on this page · raw message
arch/nds32/include/asm/stacktrace.h new file +39 -0
@@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2008-2018 Andes Technology Corporation */ + +#ifndef __ASM_STACKTRACE_H +#define __ASM_STACKTRACE_H + +/* Kernel callchain */ +struct stackframe { +unsigned long fp; +unsigned long sp; +unsigned long lp; +}; + +/* +* struct frame_tail: User callchain +* IMPORTANT: +* This struct is used for call-stack walking, +* the order and types matters. +* Do not use array, it only stores sizeof(pointer) +* +* The details can refer to arch/arm/kernel/perf_event.c +*/ +struct frame_tail { +unsigned long stack_fp; +unsigned long stack_lp; +}; + +/* For User callchain with optimize for size */ +struct frame_tail_opt_size { +unsigned long stack_r6; +unsigned long stack_fp; +unsigned long stack_gp; +unsigned long stack_lp; +}; + +extern void +get_real_ret_addr (unsigned long *addr,struct task_struct *tsk,int *graph); + +#endif /* __ASM_STACKTRACE_H */
arch/nds32/kernel/Makefile +1 -2
@@ -4,7 +4,6 @@ CPPFLAGS_vmlinux.lds := -DTEXTADDR=$(TEXTADDR) AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR) - # Object file lists. obj-y := ex-entry.o ex-exit.o ex-scall.o irq.o \
@@ -16,10 +15,10 @@ obj-$(CONFIG_MODULES) += nds32_ksyms.o module.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_OF) += devtree.o obj-$(CONFIG_CACHE_L2) += atl2c.o +obj-$(CONFIG_PERF_EVENTS) += perf_event_cpu.o extra-y := head.o vmlinux.lds - obj-y += vdso/ obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o
arch/nds32/kernel/perf_event_cpu.c new file +1223 -0
1,223 lines not on this page · raw message
arch/nds32/mm/fault.c +9 -4
@@ -9,6 +9,7 @@#include <linux/init.h> #include <linux/hardirq.h> #include <linux/uaccess.h> +#include <linux/perf_event.h> #include <asm/pgtable.h> #include <asm/tlbflush.h>
@@ -169,8 +170,6 @@ void do_page_fault(unsigned long entry, unsigned long addr, mask =VM_EXEC ; else { mask =VM_READ |VM_WRITE ; -if (vma->vm_flags &VM_WRITE ) - flags |=FAULT_FLAG_WRITE ; } }else if (entry ==ENTRY_TLB_MISC ) {switch (error_code & ITYPE_mskETYPE) {
@@ -231,11 +230,17 @@ void do_page_fault(unsigned long entry, unsigned long addr,* attempt. If we go through a retry, it is extremely likely that the * page will be found in page cache at that point. */ +perf_sw_event (PERF_COUNT_SW_PAGE_FAULTS ,1 , regs, addr);if (flags &FAULT_FLAG_ALLOW_RETRY ) { -if (fault &VM_FAULT_MAJOR ) +if (fault &VM_FAULT_MAJOR ) { tsk->maj_flt++; -else +perf_sw_event (PERF_COUNT_SW_PAGE_FAULTS_MAJ , +1 , regs, addr); + }else { tsk->min_flt++; +perf_sw_event (PERF_COUNT_SW_PAGE_FAULTS_MIN , +1 , regs, addr); + }if (fault &VM_FAULT_RETRY ) { flags &= ~FAULT_FLAG_ALLOW_RETRY ; flags |=FAULT_FLAG_TRIED ;
tools/include/asm/barrier.h +2 -0
@@ -23,6 +23,8 @@#include "../../arch/ia64/include/asm/barrier.h" #elif defined(__xtensa__)#include "../../arch/xtensa/include/asm/barrier.h" +#elif defined(__nds32__) +#include "../../arch/nds32/include/asm/barrier.h" #else #include <asm-generic/barrier.h> #endif
tools/perf/arch/nds32/Build new file +1 -0
@@ -0,0 +1 @@ +libperf-y += util/
tools/perf/arch/nds32/util/Build new file +1 -0
@@ -0,0 +1 @@ +libperf-y += header.o
tools/perf/arch/nds32/util/header.c new file +29 -0
@@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2005-2017 Andes Technology Corporation + +#include <stdio.h> +#include <stdlib.h> +#include <api/fs/fs.h> +#include "header.h" + +#define STR_LEN 1024 + +char *get_cpuid_str (struct perf_pmu *pmu) +{ +/* In nds32, we only have one cpu */ +char *buf =NULL ; +struct cpu_map *cpus; +const char *sysfs =sysfs__mountpoint (); + +if (!sysfs || !pmu || !pmu->cpus) +return NULL ; + + buf =malloc (STR_LEN ); +if (!buf) +return NULL ; + + cpus =cpu_map__get (pmu->cpus); +sprintf (buf,"0x%x" , cpus->nr -1 ); +cpu_map__put (cpus); +return buf; +}
tools/perf/pmu-events/arch/nds32/mapfile.csv new file +15 -0
@@ -0,0 +1,15 @@ +# Format: +# MIDR,Version,JSON/file/pathname,Type +# +# where +# MIDR Processor version +# Variant[23:20] and Revision [3:0] should be zero. +# Version could be used to track version of of JSON file +# but currently unused. +# JSON/file/pathname is the path to JSON file, relative +# to tools/perf/pmu-events/arch/arm64/. +# Type is core, uncore etc +# +# +#Family-model,Version,Filename,EventType +0x0,v3,n13,core
tools/perf/pmu-events/arch/nds32/n13/atcpmu.json new file +290 -0
290 lines not on this page · raw message
Signature · 1 line
2.17.0
PATCH v3 3/4 nds32: Add perf call-graph support.
In reply to NickhuThe perf call-graph option can trace the callchain between functions. This commit add the perf callchain for nds32. There are kerenl callchain and user callchain. The kerenl callchain can trace the function in kernel space. There are two type for user callchain. One for the 'optimize for size' config is set, and another one for the config is not set. The difference between two types is that the index of frame-pointer in user stack is not the same.
For example:
With optimize for size: User Stack: --------- | lp | --------- | gp | --------- | fp | Without optimize for size: User Stack: 1. non-leaf function: --------- | lp | --------- | fp | 2. leaf function: --------- | fp |
--- arch/nds32/kernel/perf_event_cpu.c | 299 +++++++++++++++++++++++++++++ 1 file changed, 299 insertions(+)
arch/nds32/kernel/perf_event_cpu.c +299 -0
@@ -1193,6 +1193,305 @@ static int __init register_pmu_driver(void)device_initcall (register_pmu_driver); +/* +* References: arch/nds32/kernel/traps.c:__dump() +* You will need to know the NDS ABI first. +*/ +static int unwind_frame_kernel (struct stackframe *frame) +{ +int graph =0 ; +#ifdef CONFIG_FRAME_POINTER +/* 0x3 means misalignment */ +if (!kstack_end ((void *)frame->fp) && + !((unsigned long )frame->fp &0x3 ) && + ((unsigned long )frame->fp >=TASK_SIZE )) { +/* +* The array index is based on the ABI, the below graph +* illustrate the reasons. +* Function call procedure: "smw" and "lmw" will always +* update SP and FP for you automatically. +* +* Stack Relative Address +* | | 0 +* ---- +* |LP| <-- SP(before smw) <-- FP(after smw) -1 +* ---- +* |FP| -2 +* ---- +* | | <-- SP(after smw) -3 +*/ + frame->lp = ((unsigned long *)frame->fp)[-1 ]; + frame->fp = ((unsigned long *)frame->fp)[FP_OFFSET ]; +/* make sure CONFIG_FUNCTION_GRAPH_TRACER is turned on */ +if (__kernel_text_address (frame->lp)) + frame->lp =ftrace_graph_ret_addr + (NULL , &graph, frame->lp,NULL ); + +return 0 ; + }else { +return -EPERM ; + } +#else +/* +* You can refer to arch/nds32/kernel/traps.c:__dump() +* Treat "sp" as "fp", but the "sp" is one frame ahead of "fp". +* And, the "sp" is not always correct. +* +* Stack Relative Address +* | | 0 +* ---- +* |LP| <-- SP(before smw) -1 +* ---- +* | | <-- SP(after smw) -2 +* ---- +*/ +if (!kstack_end ((void *)frame->sp)) { + frame->lp = ((unsigned long *)frame->sp)[1 ]; +/* TODO: How to deal with the value in first +* "sp" is not correct? +*/ +if (__kernel_text_address (frame->lp)) + frame->lp =ftrace_graph_ret_addr + (tsk, &graph, frame->lp,NULL ); + + frame->sp = ((unsigned long *)frame->sp) +1 ; + +return 0 ; + }else { +return -EPERM ; + } +#endif +} + +static void notrace +walk_stackframe (struct stackframe *frame, +int (*fn_record)(struct stackframe *,void *), +void *data) +{ +while (1 ) { +int ret; + +if (fn_record (frame, data)) +break ; + + ret =unwind_frame_kernel (frame); +if (ret <0 ) +break ; + } +} + +/* +* Gets called by walk_stackframe() for every stackframe. This will be called +* whist unwinding the stackframe and is like a subroutine return so we use +* the PC. +*/ +static int callchain_trace (struct stackframe *fr,void *data) +{ +struct perf_callchain_entry_ctx *entry = data; + +perf_callchain_store (entry, fr->lp); +return 0 ; +} + +/* +* Get the return address for a single stackframe and return a pointer to the +* next frame tail. +*/ +static unsigned long +user_backtrace (struct perf_callchain_entry_ctx *entry,unsigned long fp) +{ +struct frame_tail buftail; +unsigned long lp =0 ; +unsigned long *user_frame_tail = + (unsigned long *)(fp - (unsigned long )sizeof (buftail)); + +/* Check accessibility of one struct frame_tail beyond */ +if (!access_ok (VERIFY_READ , user_frame_tail,sizeof (buftail))) +return 0 ; +if (__copy_from_user_inatomic + (&buftail, user_frame_tail,sizeof (buftail))) +return 0 ; + +/* +* Refer to unwind_frame_kernel() for more illurstration +*/ + lp = buftail.stack_lp;/* ((unsigned long *)fp)[-1] */ + fp = buftail.stack_fp;/* ((unsigned long *)fp)[FP_OFFSET] */ +perf_callchain_store (entry, lp); +return fp; +} + +static unsigned long +user_backtrace_opt_size (struct perf_callchain_entry_ctx *entry, +unsigned long fp) +{ +struct frame_tail_opt_size buftail; +unsigned long lp =0 ; + +unsigned long *user_frame_tail = + (unsigned long *)(fp - (unsigned long )sizeof (buftail)); + +/* Check accessibility of one struct frame_tail beyond */ +if (!access_ok (VERIFY_READ , user_frame_tail,sizeof (buftail))) +return 0 ; +if (__copy_from_user_inatomic + (&buftail, user_frame_tail,sizeof (buftail))) +return 0 ; + +/* +* Refer to unwind_frame_kernel() for more illurstration +*/ + lp = buftail.stack_lp;/* ((unsigned long *)fp)[-1] */ + fp = buftail.stack_fp;/* ((unsigned long *)fp)[FP_OFFSET] */ + +perf_callchain_store (entry, lp); +return fp; +} + +/* +* This will be called when the target is in user mode +* This function will only be called when we use +* "PERF_SAMPLE_CALLCHAIN" in +* kernel/events/core.c:perf_prepare_sample() +* +* How to trigger perf_callchain_[user/kernel] : +* $ perf record -e cpu-clock --call-graph fp ./program +* $ perf report --call-graph +*/ +unsigned long leaf_fp; +void +perf_callchain_user (struct perf_callchain_entry_ctx *entry, +struct pt_regs *regs) +{ +unsigned long fp =0 ; +unsigned long gp =0 ; +unsigned long lp =0 ; +unsigned long sp =0 ; +unsigned long *user_frame_tail; + + leaf_fp =0 ; + +if (perf_guest_cbs && perf_guest_cbs->is_in_guest ()) { +/* We don't support guest os callchain now */ +return ; + } + +perf_callchain_store (entry, regs->ipc); + fp = regs->fp; + gp = regs->gp; + lp = regs->lp; + sp = regs->sp; +if (entry->nr <PERF_MAX_STACK_DEPTH && + (unsigned long )fp && !((unsigned long )fp &0x7 ) && fp > sp) { + user_frame_tail = + (unsigned long *)(fp - (unsigned long )sizeof (fp)); + +if (!access_ok (VERIFY_READ , user_frame_tail,sizeof (fp))) +return ; + +if (__copy_from_user_inatomic + (&leaf_fp, user_frame_tail,sizeof (fp))) +return ; + +if (leaf_fp == lp) { +/* +* Maybe this is non leaf function +* with optimize for size, +* or maybe this is the function +* with optimize for size +*/ +struct frame_tail buftail; + + user_frame_tail = + (unsigned long *)(fp - + (unsigned long )sizeof (buftail)); + +if (!access_ok + (VERIFY_READ , user_frame_tail,sizeof (buftail))) +return ; + +if (__copy_from_user_inatomic + (&buftail, user_frame_tail,sizeof (buftail))) +return ; + +if (buftail.stack_fp == gp) { +/* non leaf function with optimize +* for size condition +*/ +struct frame_tail_opt_size buftail_opt_size; + + user_frame_tail = + (unsigned long *)(fp - (unsigned long ) +sizeof (buftail_opt_size)); + +if (!access_ok (VERIFY_READ , user_frame_tail, +sizeof (buftail_opt_size))) +return ; + +if (__copy_from_user_inatomic + (&buftail_opt_size, user_frame_tail, +sizeof (buftail_opt_size))) +return ; + +perf_callchain_store (entry, lp); + fp = buftail_opt_size.stack_fp; + +while ((entry->nr <PERF_MAX_STACK_DEPTH ) && + (unsigned long )fp && + !((unsigned long )fp &0x7 ) && + fp > sp) { + sp = fp; + fp =user_backtrace_opt_size (entry, fp); + } + + }else { +/* this is the function +* without optimize for size +*/ + fp = buftail.stack_fp; +perf_callchain_store (entry, lp); +while ((entry->nr <PERF_MAX_STACK_DEPTH ) && + (unsigned long )fp && + !((unsigned long )fp &0x7 ) && + fp > sp) { + sp = fp; + fp =user_backtrace (entry, fp); + } + } + }else { +/* this is leaf function */ + fp = leaf_fp; +perf_callchain_store (entry, lp); + +/* previous function callcahin */ +while ((entry->nr <PERF_MAX_STACK_DEPTH ) && + (unsigned long )fp && + !((unsigned long )fp &0x7 ) && fp > sp) { + sp = fp; + fp =user_backtrace (entry, fp); + } + } +return ; + } +} + +/* This will be called when the target is in kernel mode */ +void +perf_callchain_kernel (struct perf_callchain_entry_ctx *entry, +struct pt_regs *regs) +{ +struct stackframe fr; + +if (perf_guest_cbs && perf_guest_cbs->is_in_guest ()) { +/* We don't support guest os callchain now */ +return ; + } + fr.fp = regs->fp; + fr.lp = regs->lp; + fr.sp = regs->sp; +walk_stackframe (&fr, callchain_trace, entry); +} +unsigned long perf_instruction_pointer (struct pt_regs *regs) {/* However, NDS32 does not support virtualization */
Signature · 1 line
2.17.0
PATCH v3 4/4 nds32: Add document for NDS32 PMU.
In reply to NickhuThe document for how to add NDS32 PMU
in devicetree.
--- Documentation/devicetree/bindings/nds32/pmu.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 Documentation/devicetree/bindings/nds32/pmu.txt
Documentation/devicetree/bindings/nds32/pmu.txt new file +17 -0
@@ -0,0 +1,17 @@ +* NDS32 Performance Monitor Units + +NDS32 core have a PMU for counting cpu and cache events like cache misses. +The NDS32 PMU representation in the device tree should be done as under: + +Required properties: + +- compatible : + "andestech,nds32v3-pmu" + +- interrupts : The interrupt number for NDS32 PMU is 13. + +Example: +pmu{ + compatible = "andestech,nds32v3-pmu"; + interrupts = <13>; +}
Signature · 1 line
2.17.0
Re: [PATCH v3 4/4] nds32: Add document for NDS32 PMU.
Quoted 8 lines · Nickhu
The document for how to add NDS32 PMU
in devicetree.Signed-off-by Nickhu <[email protected]>--- Documentation/devicetree/bindings/nds32/pmu.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 Documentation/devicetree/bindings/nds32/pmu.txt
Can you move to bindings/perf/ with other similar h/w. With that,
Re: [PATCH v3 4/4] nds32: Add document for NDS32 PMU.
Hi Rob,
Quoted 10 lines · Rob Herring
Quoted 8 lines · Nickhu
The document for how to add NDS32 PMU
in devicetree.Signed-off-by Nickhu <[email protected]>--- Documentation/devicetree/bindings/nds32/pmu.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 Documentation/devicetree/bindings/nds32/pmu.txt
Quoted 3 lines
Can you move to bindings/perf/ with other similar h/w. With that,
Reviewed-by Rob Herring <[email protected]>
Sure, thanks!
Nick