ARM A7 PMU+perf简单记录.
关键词:pmu,perf等等。
简单记录PMU及其内核驱动,内核中perf相关内容,以及两者是如何关联的。然后记录perf应用是如何和PMU硬件关联的,以及如何使用perf查看PMU结果。
A7 PMU概要
PMU作为一个扩展功能,是一种非侵入式的调试组件。
对PMU寄存器的访问可以通过CP15协处理器指令和Memory-Mapped地址。
更详细内容参考:
《Arm CoreSight Performance Monitoring Unit Architecture》:关于PMU架构介绍,包括寄存器解释、规格、安全等等。
《ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition》:介绍了PMU在Armv7-A/R中的实现。
《Chapter C12 The Performance Monitors Extension》:PMU基本功能介绍
《Appendix D2 Recommended Memory-mapped and External Debug Interfaces for the Performance Monitors》:PMU寄存器介绍。
kernel PMU
Linux内核中已经集成了PMU代码,需要配置的是dts部分:
pmu-a7 {
compatible = "arm,cortex-a7-pmu";
interrupts = <GIC_SPI 12 (IRQ_TYPE_LEVEL_HIGH)>;
interrupt-patent = <&gic>;
}
PMU默认使用CP15寄存器即可进行配置,还提供了Memory-Mapped方式。
这里主要配置了中断号。
arm_pmu_hp_init()注册CPU HogPlug时online和offline回调函数。
arm_pmu_hp_init
->cpuhp_setup_state_multi
->arm_perf_starting_cpu
->arm_perf_teardown_cpu
armv7 pmu驱动根据dts compatile匹配到对应的函数初始化struct armpmu结构体,并从dts中获取中断并注册。
然后对接perf,提供相关初始化函数。
armv7_pmu_driver(builtin_platfrom_driver)
->armv7_pmu_device_probe
->arm_pmu_device_probe
->armpmu_alloc
->__armpmu_alloc--分配struct pmu结构体,并给相关的处理函数赋值。
->pmu_parse_irqs
->platform_get_irq--从dts中获取中断号。
->__platform_get_irq
->of_irq_get
->of_irq_parse_one
->of_irq_parse_raw
->request_irq
->request_threaded_irq
->__setup_irq
->__irq_set_trigger
->gic_set_type--irq-gic.c中chip->irq_set_type,型号为GIC400。
->gic_configure_irq ->of_id->data--根据“arm,cortex-a7-pmu”指向armv7_a7_pmu_init,对struct arm_pmu进行初始化。 ->armv7_a7_pmu_init--“arm,cortex-a7-pmu”对应的初始化函数。 ->armv7pmu_init--给struct arm_pmu结构体函数赋值。 ->armv7_read_num_pmnc_events--读取PMCR寄存器,获取PMU支持的事件数量。
->armpmu_request_irqs
->armpmu_request_irq--注册pmu中断处理函数armpmu_dispatch_irq()。
->armpmu_register
->cpu_pmu_init
->cpuhp_state_add_instance
->cpu_pm_pmu_register
->perf_pmu_register--和perf工具相关的初始化,包括一些函数指针初始化。
->perf_pmu_register
->armv7_pmu_of_device_ids--支持的dts compatible列表。
kernel perf
perf的sw/hw等事件注册初始化。
start_kernel
->perf_event_init
->idr_init
->perf_event_init_all_cpus
->perf_pmu_register(perf_swevent/perf_cpu_clock/perf_task_clock)
->perf_tp_register
->perf_event_init_cpu ->perf_swevent_init_cpu
->register_reboot_notifier--注册reboot回调函数。
->init_hw_breakpoint--perf使用断点初始化。
内核提供系统调用perf_event_open()返回CPU+PID组合的文件句柄,应用通过此句柄设置刚兴趣的事件。
在kernel/events/core.c中:
/**
* sys_perf_event_open - open a performance event, associate it to a task/cpu
*
* @attr_uptr: event_id type attributes for monitoring/sampling
* @pid: target pid
* @cpu: target cpu
* @group_fd: group leader event fd
*/
SYSCALL_DEFINE5(perf_event_open,
struct perf_event_attr __user *, attr_uptr,
pid_t, pid, int, cpu, int, group_fd, unsigned long, flags)
{
}
perf文件操作函数集是perf_fops:
static const struct file_operations perf_fops = {
.llseek = no_llseek,
.release = perf_release,
.read = perf_read,--读取结果。
.poll = perf_poll,
.unlocked_ioctl = perf_ioctl,--对event进行配置。
.compat_ioctl = perf_compat_ioctl,
.mmap = perf_mmap,
.fasync = perf_fasync,--
};
perf
perf命令源码位于内核tools/perf中,有多个子命令组成,下面以perf list hw为例,简单看一下是如何和PMU关联的。
main
->commands
->cmd_list(list)
->print_symbol_events--perf list hw命令对应函数。 ->is_event_supported ->evsel__new ->evsel__open ->perf_event_open ->sys_perf_event_open--对应内核的perf_event_open系统调用。
->cmd_record(record)
PMU+perf使用
perf list hw查看A7支持的PMU事件,在armv7_pmuv2_event_attrs中包含30个events:
armv7cortex_a7/br_immed_retired
armv7_cortex_a7/br_mis_pred/
armv7_cortex_a7/br_pred/
armv7_cortex_a7/br_return_retired/
armv7_cortex_a7/bus_access/
armv7_cortex_a7/bus_cycles/
armv7_cortex_a7/cid_write_retired/
armv7_cortex_a7/cpu_cycles/
armv7_cortex_a7/exc_return/
armv7_cortex_a7/exc_taken/
armv7_cortex_a7/inst_retired/
armv7_cortex_a7/inst_spec/
armv7_cortex_a7/l1d_cache/
armv7_cortex_a7/l1d_cache_refill/
armv7_cortex_a7/l1d_cache_wb/
armv7_cortex_a7/l1d_tlb_refill/
armv7_cortex_a7/l1i_cache/
armv7_cortex_a7/l1i_cache_refill/
armv7_cortex_a7/lli_tlb_refill/
armv7_cortex_a7/12d_cache/
armv7_cortex_a7/l1d_cache_refill/
armv7_cortex_a7/12d_cache_wb/
armv7_cortex_a7/ld_retired/
armv7_cortex_a7/mem_access/
armv7_cortex_a7/memory_error/
armv7_cortex_a7/pc_write_retired/
armv7_cortex_a7/st_retired/
armv7_cortex_a7/sw_incr/
armv7_cortex_a7/ttbr_write_retired/
armv7_cortex_a7/unaligned_ldst_retired/
如果想查看某一程序执行时PMU事件,比如bus-cycles:
perf stat -e bus-cycles xxx


浙公网安备 33010602011771号