重新编译Linux内核不要使用特定的CPU寄存器

时间:2017-06-05 02:52:34

标签: linux-kernel cpu-registers perf

我正在做一个实验,将循环索引写入CPU寄存器R11,然后使用gcc -ffixed-r11构建它,尝试让编译器知道不使用该reg,最后使用perf来测量它

但是当我检查报告时(使用perf script),大多数记录条目的R11值不是我预期的,它应该是数字序列,如1..2..3或1 .. 4..7等等但实际上只是几个固定值。 (可能受系统调用覆盖影响?)

如何让perf记录我在程序中设置的值?或者我必须用-ffixed-r11重新编译整个内核才能实现?

谢谢大家。

2 个答案:

答案 0 :(得分:0)

当您只想使用perf对一些寄存器进行采样时,不应该尝试重新编译内核。据我所知,内核有自己的一组寄存器,不会覆盖用户R11。 syscall接口使用一些无法更改的固定寄存器(可以尝试不同的reg吗?)并且通常有glibc网关到syscall,可能会使用一些额外的寄存器(它们不在内核中,它们是用户空间)代码;通常用汇编程序生成或编写)。您可以尝试使用gdb监视寄存器以进行更改以查找是谁。它可以做到这一点(嗯,另一个链接到同一个用户的SO):gdb: breakpoint when register will have value 0xffaa,如gdb ./program,然后gdb命令start; watch $r11; continue; where

两周大的时候,问题perf-report show value of CPU register关于寄存器值采样有问题:

  

我关注this document并将perf record--intr-regs=ax,bx,r15一起使用,尝试使用PEBS记录记录其他CPU注册信息。

虽然有x86& PEBS,ARM也可以实现--intr-regs。检查perf record --intr-regs=\?的输出(man perf-record:“列出可用的寄存器使用--intr-regs=\?”)以查找支持状态和注册名称。

要打印寄存器,请使用perf script -F ip,sym,iregs命令。在一些linux提交中有例子:

  # perf record --intr-regs=AX,SP usleep 1
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 0.016 MB perf.data (8 samples) ]
  # perf script -F ip,sym,iregs | tail -5
   ffffffff8105f42a native_write_msr_safe   AX:0xf    SP:0xffff8802629c3c00
   ffffffff8105f42a native_write_msr_safe   AX:0xf    SP:0xffff8802629c3c00
   ffffffff81761ac0 _raw_spin_lock   AX:0xffff8801bfcf8020    SP:0xffff8802629c3ce8
   ffffffff81202bf8 __vma_adjust_trans_huge   AX:0x7ffc75200000    SP:0xffff8802629c3b30
   ffffffff8122b089 dput   AX:0x101    SP:0xffff8802629c3c78
  #

答案 1 :(得分:0)

如果您需要对金属CPU活动进行循环精确分析,那么perf不是正确的工具,因为它最多只是近似值,因为它只在选择点对程序进行采样。见this video on perf by Clang developer Chandler Carruth

相反,您应该单步执行该程序,以便准确监视寄存器发生的情况。或者您可以在没有操作系统的情况下对系统裸机进行编程,但这可能超出了此范围。