专栏名称: 企业存储技术
企业存储、服务器、SSD、灾备等领域技术分享,交流 | @唐僧_huangliang (新浪微博 )
目录
相关文章推荐
51好读  ›  专栏  ›  企业存储技术

探索与解决:Intel E810网卡的4ms单并发IO延迟问题

企业存储技术  · 公众号  · 硬件  · 2024-09-28 17:27

主要观点总结

本文探讨了zStorage分布式块存储系统在特定环境下使用FIO工具测试时出现的IO延迟问题,通过对问题的定界和深入分析,最终找到了问题所在并提供了解决方案。

关键观点总结

关键观点1: 问题现象和背景

近期,zStorage系统在海光+麒麟+E810网卡环境下使用FIO工具测试4K单并发随机读/写IO时,延迟达到4ms,而使用Mellanox网卡时延迟正常。

关键观点2: 问题定界

通过时延分析、更换HOST、Ftrace跟踪分析等手段,确定问题可能与内核有关。

关键观点3: 4ms延迟流程深究

根据Ftrace信息,发现4ms的延迟出现在Host端的内核处理上,与APIC定时器和软中断处理机制有关。

关键观点4: 解决策略

通过分析IO处理流程,确定问题出在__raise_softirq_irqoff函数上,提出使用不带下划线的raise_softirq_irqoff或Tasklet来触发延迟任务作为解决方案。

关键观点5: 实验结果

使用Tasklet触发延迟任务后,时延降低至130us,解决了4ms延迟的问题。


正文

注:本文内容引用自张洋老师的知乎文章 https://zhuanlan.zhihu.com/p/735757082,他 是一位存储研发专家。

问题现象和背景

近期,zStorage分布式块存储系统在海光+麒麟 +E810网卡环境下,使用FIO工具测试4K单并发随机读/写IO时,延迟达到4ms。而这里唯一的变量是E810网卡;如果采用Mellanox网卡,在同样的测试用例下,IO延迟约为100us左右。那么问题出在网卡吗?还是另有原因?以下是分析和探索的过程分享。

问题定界

要分析上述高时延问题,首先需要对问题进行定界:是zStorage存储软件的问题,还是Host端的问题?针对这一问题,我们做了以下几件事情:

  • - 时延分析 :zStorage FrontEnd从收到IO到应答IO给Host,耗时 < 100us,符合预期。这个实验表明问题大概率不在存储端,但仍不能完全断定问题在Host端。


  • - 更换HOST:重新使用一个内核版本为5.10的系统,进行相同的测试用例,时延恢复正常。这个结果至少说明,更换内核可以解决问题,问题大概率与内核有关。


  • - Ftrace跟踪分析:在出问题的HOST上开启Ftrace,跟踪nvmf和rdma相关函数。发现4ms的时延确实出现在Host端的处理上。如下图所示:在58225.458457这个时间点,Host的IB驱动已经收到了存储节点的ACK应答,但直到58225.462423这个时间点才调用 nvme_rdma_send_done 。这个实验表明,确实是Host端的内核存在一个4ms的延迟。

4ms延迟流程深究

根据Ftrace的信息,可以看到在4ms后,由 smp_apic_timer_interrupt 触发,完成了消息的发送。

在 Linux 内核中,smp_apic_timer_interrupt 是处理APIC(Advanced Programmable Interrupt Controller)定时器中断的中断处理程序。当该中断触发时,它可以调用定时器相关的处理程序,通常与调度器、进程切换、软中断 等内核机制相关。APIC 定时器是每个 CPU 的本地定时器,用于周期性地触发中断,从而执行某些周期性的任务。

具体来说,这个APIC定时器的频率较低,通常在1000Hz以下,而当前出问题的Host为250Hz,因此每4ms调度一次,这与IO延迟4ms是相吻合的。然而,这个频率是在内核编译时确定的,修改起来并不容易,且直觉上问题不太可能出在这里。毕竟,为了解决这个问题,不可能将频率改为100万Hz。那么,为什么IO会在 smp_apic_timer_interrupt 的调度流程中完成呢?IO真正的完成应该是在什么流程中呢?

继续探究IO未及时处理的原因

继续使用Ftrace跟踪更多详细的信息。

ib_cq_completion_softirq 的下一个函数调用是 __raise_softirq_irqoff 。翻阅内核源码后,发现 irq_poll_sched 这个函数至关重要。它负责调度软中断处理,并与IO完成的路径密切相关。进一步分析 irq_poll_sched 的调用时机和作用,可能揭示出为何IO在软中断处理链中被延迟触发。

这意味着, irq_poll_sched 函数并不希望在当前流程中立即处理I/O,而是将当前I/O加入到CPU的延迟任务处理队列中,等待延迟处理。然而,实际情况是处理延迟了4ms,这个延迟确实过长了。注意这一行代码: __raise_softirq_irqoff(IRQ_POLL_SOFTIRQ); __raise_softirq_irqoff() 触发了指定类型的软中断,这里是 IRQ_POLL_SOFTIRQ ,用于调度一个软中断处理函数来处理加入轮询队列 的I/O任务。

接下来,进一步查看内核源码,以分析 IRQ_POLL_SOFTIRQ 如何调度以及为什么延迟长达4ms?

IRQ_POLL_SOFTIRQ 这个软中断是与 irq_poll_softirq 函数绑定在一起的。这意味着,一旦使用 __raise_softirq_irqoff 触发了软中断,应该在短时间内调用 irq_poll_softirq ,以处理刚才的I/O完成。然而,在实际情况中,I/O处理延迟了4ms,这表明在软中断的调度和处理之间存在瓶颈或延迟。

对IO处理流程稍作总结

ROCE网卡的中断处理流程已经梳理清楚:

  • - irdma 发送数据到存储节点,使用 RDMA 协议传递数据。







请到「今天看啥」查看全文