我正在 Linux 跟踪这个兔子洞里爬行。我对 perf 及其功能比较陌生,但我认为它可以满足我的要求,但我不确定如何继续我的工作。我需要一点指导。
我想测量单个节点(无论是容器还是主机)的数据包处理延迟,我认为这也称为网络传播延迟。我了解基本网络延迟的工作原理,并且我使用 Ping for (RTT) 和 iPerf3 来跟踪和绘制一些简单的统计数据。虽然这可以让我们了解整个网络的整体情况,但它并不能真正告诉我们太多有关 Linux 网络堆栈引起的延迟的信息。
现在我想考虑测量 Linux 内核堆栈的数据包处理延迟。以我目前的知识,我知道我们可以跟踪“net:*”事件,例如当数据包首次进入时,它将触发“netif_rx”。这应该是数据包进入网卡并由linux内核处理的开始时间。
例如,运行
perf trace --no-syscalls --event 'net:*' ping 172.19.0.4 -c1 > /dev/null
会导致
0.000 ping/811 net:net_dev_queue(skbaddr: 0xffff8d110b2a4600, len: 98, name: "eth0")
0.049 ping/811 net:net_dev_start_xmit(name: "eth0", skbaddr: 0xffff8d110b2a4600, protocol: 2048, len: 98, network_offset: 14, transport_offset_valid: 1, transport_offset: 34)
0.077 ping/811 net:netif_rx_entry(name: "veth1c585f6", napi_id: 3, skbaddr: 0xffff8d110b2a4600, protocol: 2048, len: 84, truesize: 768, mac_header_valid: 1, mac_header: 4294967282)
0.102 ping/811 net:netif_rx(skbaddr: 0xffff8d110b2a4600, len: 84, name: "veth1c585f6")
0.143 ping/811 net:netif_rx_exit(skbaddr: 0xffff8d110b2a4600, len: 84, name: "veth1c585f6")
0.169 ping/811 net:net_dev_xmit(skbaddr: 0xffff8d110b2a4600, len: 98, name: "eth0")
0.186 ping/811 net:netif_receive_skb(skbaddr: 0xffff8d110b2a4600, len: 84, name: "veth1c585f6")
0.224 ping/811 net:netif_receive_skb_entry(name: "br-e26d82c11b7e", napi_id: 3, skbaddr: 0xffff8d110b2a4600, protocol: 2048, ip_summed: 2, len: 84, truesize: 768, mac_header_valid: 1, mac_header: 4294967282)
0.240 ping/811 net:netif_receive_skb(skbaddr: 0xffff8d110b2a4600, len: 84, name: "br-e26d82c11b7e")
0.271 ping/811 net:netif_receive_skb_exit(skbaddr: 0xffff8d110b2a4600, len: 84, name: "br-e26d82c11b7e")
这里我正在 ping 另一个 docker 容器(目前在同一主机上)。我比较明白这些步骤是做什么的。
net:net_dev_queue
:网络设备队列在名为 eth0 的以太网接口上收到大小为 len 的新数据包 (skbaddr)。net:net_dev_start_xmit
:以太网驱动程序开始使用协议号协议在名为 eth0 的接口上传输大小为 len 的数据包 (skbaddr)。net:netif_rx_entry
:网络接口 veth1c585f6 收到一个大小为 len 且协议为 protocol 的数据包(skbaddr),现在正在处理它。net:netif_rx
:网络接口 veth1c585f6 收到大小为 len 的数据包 (skbaddr)。net:netif_rx_exit
:veth1c585f6 收到的数据包已完全处理,现在可以在堆栈中向上传递。net:net_dev_xmit
:内核即将在名为 eth0 的接口上传输大小为 len 的数据包(skbaddr)。net:netif_receive_skb
:在名为 veth1c585f6 的接口上收到大小为 len 的数据包 (skbaddr)。net:netif_receive_skb_entry
:网桥 br-e26d82c11b7e 收到一个大小为 len 和协议 protocol 的数据包 (skbaddr),现在正在处理它(使用 NAPI id 3)。net:netif_receive_skb
:网桥 br-e26d82c11b7e 收到一个大小为 len 的数据包(skbaddr)。net:netif_receive_skb_exit
: br-e26d82c11b7e 收到的数据包已经完全处理完毕,现在可以投递了。我阅读了一些 Linux 内核来做到这一点。
因此。这是我的问题。我将如何使用此跟踪点方法来计算数据包处理延迟(以及因此的抖动)。我可以使用 perf 对大数据包流进行此类测量(将数据包从一个容器发送到另一个容器)吗?
一个思考过程:我还知道跟踪点
syscalls:sys_exit_execve()
,这是一个跟踪点函数,当执行新程序后execve()
系统调用返回时触发。因此,在处理数据包时,这应该是数据包之前的“最后”跟踪点调用。找到这两个时间之间的差异就等于粗略估计吗?
谢谢!
我很遗憾看到没有人回答这个问题,但你可以使用
perf record -e skb:* -e net:* ping -c 10 host
# show raw perf log
perf script
这应该可以向您展示时间并至少让您开始。当我刚刚测试时,它工作得很好,但我怀疑您需要添加更多带有更多“-e foo”的事件。