Linux kernel 为什么性能总是显示原始旋转解锁irqrestore或其他旋转解锁功能

Linux kernel 为什么性能总是显示原始旋转解锁irqrestore或其他旋转解锁功能,linux-kernel,perf,spinlock,Linux Kernel,Perf,Spinlock,有人知道为什么性能总是显示原始旋转解锁irqrestore或其他旋转解锁功能吗?与spin_lock相比,spin_解锁实现通常更简单。如果旋转锁上存在高竞争,性能不应该在旋转锁中显示结果吗?您正在运行什么工作负载?你确定首先会有争论吗 irq_restore之所以出现,是因为重新启用中断的成本很高,但使用中断的锁并不经常出现。当机器基本处于空闲状态时,您最有可能看到它 对于kicks,我运行了一个琐碎的工作负载,它与spinlock竞争,而最引人注目的是锁定例程: 81.36% [ker

有人知道为什么性能总是显示原始旋转解锁irqrestore或其他旋转解锁功能吗?与spin_lock相比,spin_解锁实现通常更简单。如果旋转锁上存在高竞争,性能不应该在旋转锁中显示结果吗?

您正在运行什么工作负载?你确定首先会有争论吗

irq_restore之所以出现,是因为重新启用中断的成本很高,但使用中断的锁并不经常出现。当机器基本处于空闲状态时,您最有可能看到它

对于kicks,我运行了一个琐碎的工作负载,它与spinlock竞争,而最引人注目的是锁定例程:

  81.36%  [kernel]                    [k] native_queued_spin_lock_slowpath
   4.67%  libc-2.17.so                [.] __memset_sse2
   1.63%  [kernel]                    [k] find_next_zero_bit
   0.92%  [kernel]                    [k] _raw_spin_lock
   0.81%  [kernel]                    [k] __audit_syscall_exit
   0.76%  [kernel]                    [k] __alloc_fd
   0.69%  [kernel]                    [k] __slab_free
   0.62%  [kernel]                    [k] security_compute_sid.part.13
   0.45%  [kernel]                    [k] kmem_cache_free
@当月最佳员工 我的最佳成绩片段

 3.32%  [kernel]       [k] native_queued_spin_lock_slowpath
 3.18%  [kernel]       [k] update_load_avg
 3.13%  [kernel]       [k] __switch_to
 3.12%  [kernel]       [k] native_write_msr
 3.02%  [kernel]       [k] __sched_text_start
 2.81%  [kernel]       [k] _raw_spin_lock
 2.20%  [kernel]       [k] _raw_spin_lock_irqsave
 1.97%  [kernel]       [k] switch_mm_irqs_off
 1.70%  [kernel]       [k] __blkdev_direct_IO_simple
 1.69%  [kernel]       [k] __get_user_pages_fast
这是我的框架图结果

当中断被禁用时,用于采样的计时器中断
perf
不会触发。当中断最终启用时(在任何
irqrestore
功能中),
perf
错误地计算整个时间跨度,就好像它是由该恢复功能执行的一样

如果您使用
perf annotate
进行更深入的研究,您将看到大多数(如果不是全部)示例都是在
popfq
之后的1个操作码,它更新EFLAGS寄存器,启用中断:

_raw_spin_unlock_irqrestore  /proc/kcore
Percent│    Disassembly of section load0:
       │
       │    ffffffff819bd790 <load0>:
       │      nop
       │      push   %rbp
       │      mov    %rsp,%rbp
       │      movb   $0x0,(%rdi)
       │      nop
       │      mov    %rsi,%rdi
       │      push   %rdi
       │      popfq
100.00 │      nop
       │      pop    %rbp
       │    ← retq
\u原始\u旋转\u解锁\u irqrestore/proc/kcore
百分比│    节段载荷0的分解:
│
│    ffffffff819bd790:
│      不
│      推送%rbp
│      mov%rsp,%rbp
│      movb$0x0,(%rdi)
│      不
│      移动%rsi,%rdi
│      推送%rdi
│      popfq
100│      不
│      弹出%rbp
│    ← retq
Linux用于性能监视中断。这一变化自v2.6.31~以来就出现在主线中,但我想这是针对裸机内核的,而不是针对作为VM运行的内核(即,裸机Linux机器上的
perf-record
不会出现此问题,而我机器上运行的KVM上的
perf-record
会出现此问题)


有关更多详细信息,请参阅。

我刚刚在本地计算机上运行了一个随机读取测试用例,并使用perf检查最新块mq的争用状态。结果,除了io调度程序应该调用的本机队列路径、自旋路径、锁定路径和慢路径路径外,还有原始路径、自旋路径、解锁路径和irqrestore路径。特别是在由FrameGraph生成的结果中。作为图片的FlameGraph不是很有用。假设您正在运行相同的工作负载,并且结果是可重复的,您可以看到cpu时间没有花费在irqrestore中。我怀疑发生了什么事。内核有专用的中断堆栈。当例程执行irqrestore时,所有排队的中断现在都被处理。但是获取回溯的报告模式不会检查中断堆栈,因此您只会得到一个顶部带有irqrestore的转储。嗯,帧图似乎不太准确。从perf top的结果来看,_raw_spin_unlock_irqrestore()不需要太多cpu。谢谢你的建议。