最近在调查网络收包延时问题,出现了发包时间戳和收包时间戳差距200ms左右的情况。这就先要明确pcap文件包数据包的时间戳是谁标记的。
想偷懒,但两个大模型回答完全相反:
文心一言回答
ChatGPT 3.5回答
NewBing ChatGPT 4.0 回答
2比1,可能是驱动。
tcpdump帮助文档
其实tcpdump帮助文档,有很明确的说明,man tcpdump:
ChatGPT翻译一下,效果不怎么地
时间戳
默认情况下,所有输出行都以时间戳开头。时间戳采用以下形式的当前时钟时间:
hh:mm:ss.frac
并且与内核时钟一样准确。时间戳反映了内核为数据包应用时间戳的时间。没有尝试考虑网络接口完成从网络接收数据包到内核为数据包应用时间戳之间的时间滞后;这个时间滞后包括网络接口完成从网络接收数据包到内核传递中断以便读取数据包的时间,以及内核处理“新数据包”中断和为数据包应用时间戳之间的延迟。
从上面帮助文档可知,是内核在收包时,标记的时间戳。并不是tcpdump应用程序标记。
分析收包过程
说驱动标记的也可以,下面引用NAPI流程图来说明一下收包流程(图是发包流程):
1,网卡NIC从网线上收到数据包,DMA方式写入内存
2,发送中断通知CPU来包了或CPU Poll查询到来包了
3,CPU从内存取包
4,包交给内核网络协议处理
5,网络应用软件处理网络数据
第3步也就是内核线程(或SoftIRQ)调用驱动函数取包时,打的时间戳。也就是帮助中说的:
that time lag could include a delay between the time when the network interface finished receiving a packet from the network and the time when an interrupt was delivered to the kernel
to get it to read the packet and a delay between the time when the kernel serviced the `new packet' interrupt and the time when it applied a time stamp to the packet.
下面这几个步骤的时间延迟,未包含在时间中,就是说从收包到打时间戳的时间点,之前还有几步操作:
硬件收包>发送中断(poll查询到)>内核线程(或SoftIRQ)取包>打时间戳
因此当ksoftirqd/x存在调度不及时情况时(ksoftirqd/x在Linux中并非实时优先级),存在实际收包时间与时间戳差距较大的情况。
结论
PCAP文件数据包的时间戳是在内核(调用驱动)收包时,标记的时间戳。
既不是硬件收包时标记的,也不是tcpdump应用程序标记的。