【问题标题】:Sources of latency in sending-receiving tcp/udp packets in linuxlinux中收发tcp/udp数据包延迟的来源
【发布时间】:2011-02-10 20:27:28
【问题描述】:

linux 2.6 发送/接收 TCP/UDP 数据包的延迟来源是什么?

我想知道“乒乓”延迟测试中的延迟来源。

有一些关于以太网延迟的相当不错的论文,但它们仅涵盖了线路和交换机中的延迟源(并且相当粗略,仅针对特定交换机)。

一个数据包之后有哪些处理步骤?

对常用 ping (icmp) 进行深度延迟分析的论文也会很有用。

我依赖社区:)

【问题讨论】:

    标签: performance networking linux-kernel latency low-latency


    【解决方案1】:

    尽管它已经很老了,但本指南详细介绍了 linux 网络堆栈。

    http://www.cs.unh.edu/cnrg/people/gherrin/linux-net.html

    如果您通读那里,您应该能够发现可以通过内核添加延迟的地方。

    例如如果帧在内核中临时缓冲

    【讨论】:

      【解决方案2】:

      简短回答:对于内核中的确切延迟,您应该使用 perf probe 和 perf script。

      更多详情: 让我们看下面的例子。首先我们想看看TCP乒乓测试使用了哪些函数(我用的是netperf)。

      关于接收流:

      关于传输流:

      让我们来跟踪传输流的一些功能(它很长,所以我将展示 TCP 流中的主要功能)。我们可以使用 perf probe 来采样每个函数的入口和出口点:

      perf probe --add sock_sendmsg='sock_sendmsg'
      perf probe --add sock_sendmsg_exit='sock_sendmsg%return'
      perf probe --add inet_sendmsg='inet_sendmsg'
      perf probe --add inet_sendmsg_exit='inet_sendmsg%return'
      perf probe --add tcp_sendmsg_exit='tcp_sendmsg%return'
      perf probe --add tcp_sendmsg='tcp_sendmsg'
      perf probe --add tcp_sendmsg_locked='tcp_sendmsg_locked'
      perf probe --add tcp_sendmsg_locked_exit='tcp_sendmsg_locked%return'
      perf probe --add sk_stream_alloc_skb='sk_stream_alloc_skb'
      perf probe --add sk_stream_alloc_skb_exit='sk_stream_alloc_skb%return'
      perf probe --add tcp_push_exit='tcp_push%return'
      perf probe --add tcp_push='tcp_push'
      perf probe --add tcp_send_mss='tcp_send_mss'
      perf probe --add tcp_send_mss_exit='tcp_send_mss%return'
      perf probe --add __tcp_push_pending_frames='__tcp_push_pending_frames'
      perf probe --add __tcp_push_pending_frames_exit='__tcp_push_pending_frames%return'
      perf probe --add tcp_write_xmit_exit='tcp_write_xmit%return'
      perf probe --add tcp_transmit_skb_exit='tcp_transmit_skb%return'
      perf probe --add tcp_transmit_skb='tcp_transmit_skb'
      

      不,我们可以记录这些:

      perf record -e probe:* -aR taskset -c 7 netperf -t TCP_RR -l 5 -T 7,7
      

      并为延迟报告运行 perf 脚本:

      perf script -F time,event --ns
      

      输出(1 次迭代):

      525987.403094082:                   probe:sock_sendmsg:
      525987.403095586:                   probe:inet_sendmsg:
      525987.403096192:                    probe:tcp_sendmsg:
      525987.403098203:             probe:tcp_sendmsg_locked:
      525987.403099296:                   probe:tcp_send_mss:
      525987.403100002:              probe:tcp_send_mss_exit:
      525987.403100740:            probe:sk_stream_alloc_skb:
      525987.403101697:       probe:sk_stream_alloc_skb_exit:
      525987.403103079:                       probe:tcp_push:
      525987.403104284:      probe:__tcp_push_pending_frames:
      525987.403105575:               probe:tcp_transmit_skb:
      525987.403110178:               probe:tcp_transmit_skb:
      525987.403111640:          probe:tcp_transmit_skb_exit:
      525987.403112876:          probe:tcp_transmit_skb_exit:
      525987.403114351:            probe:tcp_write_xmit_exit:
      525987.403114768: probe:__tcp_push_pending_frames_exit:
      525987.403115191:                  probe:tcp_push_exit:
      525987.403115718:        probe:tcp_sendmsg_locked_exit:
      525987.403117576:               probe:tcp_sendmsg_exit:
      525987.403118082:              probe:inet_sendmsg_exit:
      525987.403118568:              probe:sock_sendmsg_exit:
      

      现在很容易看出延迟用在了哪里。例如,我们可以注意到在 sock_sendmsg() 调用和 inet_sendmsg() 调用之间有 1504 纳秒 (ns) 或 1.504 微秒 (us) 的延迟。此外,我们可以看到 sk_stream_alloc_skb 需要 957 ns。总的来说,整个过程(sock_sendmsg 进入到退出)大约需要 24.5us。请记住,这不是您在 netperf 中看到的,因为数据包是在流中间的某处物理传输的。

      您可以使用相同的方法来跟踪内核中的任何一段代码。

      希望这会有所帮助。

      P.S. 这是在 kernel-4.14 而不是 2.6 上完成的。不知道当时的性能是如何发展起来的,所以它可能无法正常工作。

      【讨论】:

      • 谢谢!现在可以使用现代内核了。你是怎么得到火焰图的?我知道的经典火焰图使用“总和”,它不是在绝对时间线上绘制函数,而是在多次执行中绘制时间百分比,并在分析模式下与 perf 一起使用。那么,您是否使用绝对时间线对perf script 输出进行了类似火焰图的绘制?我将如何在图中看到访问硬件的延迟(驱动程序应在 hw/dma 队列中创建描述符并通过端口/pio/mmio 向网络控制器发送新描述符)?
      • [1] 这些火焰图是使用这本(优秀的)手册创建的:brendangregg.com/flamegraphs.html。它是基于性能的,需要记录数据才能工作。我总是从它们开始性能调试,因为它们完美地说明了运行时发生的事情。其余的调试(性能探测、记录和脚本)在下一次迭代中完成,而不是使用相同的数据。 [2]关于硬件访问,每个驱动程序都有自己的。对于 mlx5 驱动程序 TX,这是:elixir.free-electrons.com/linux/latest/source/drivers/net/….
      猜你喜欢
      • 1970-01-01
      • 2021-01-28
      • 1970-01-01
      • 1970-01-01
      • 2016-03-26
      • 2011-04-20
      • 2010-11-07
      • 2018-10-23
      • 1970-01-01
      相关资源
      最近更新 更多