DPC 延迟高并不等于 VPN 路径慢
驱动时间、回声往返和会话事件会被互相归罪。更换组件之前,先弄清每个计数器到底在测量什么。
一次音频故障和一次 VPN 暂停落在同样的十秒钟里,而某个工具报告了一个标着“DPC 延迟”的高数值。人很容易由此断定:驱动拖慢了隧道,或者隧道给驱动施加了压力。这两个结论都无法从那个数值推出来。
这里涉及三种测量,它们并不共享同一个边界。
三个数字,三种边界
延迟过程调用是驱动从自己的中断处理程序里推迟执行的工作,而这些例程内部花费的时间,是以处理器为单位的本地测量,归属到各模块与函数。回声往返是在套接字处观测到的时间,由网络栈和远端响应者产生。断开事件则是客户端记录的状态转换。每种测量都回答其他两种回答不了的问题,单位相同并不意味着它们可以互换。
有用的纪律是先命名边界,再读取数值。把单位和边界写在一起。如果工具报告的是毫秒,就要问清楚是哪一种毫秒:例程内部的时间、等待调度执行的时间,还是直到收到回复的时间。
某一类里的高数值只是线索,从来不是诊断。
读懂标题背后的定义
各种工具对“延迟”的叫法并不一致。有的报告驱动例程的耗时,有的报告调度延迟,而在同一台机器上,这两个量可以背道而驰。一个把其中某一项直接叫作 DPC 延迟的仪表盘,实际告诉你的比表面看起来要少。因此,两个仪表盘可能对一台毫无变化的机器给出不一致的说法。
同样的谨慎也适用于单个分析工具内部。包含时长统计例程从进入到退出的全过程,而独占时长只累加该例程自身真正执行的那些片段。选错列,就会把调用者当成元凶。
本地驱动工作与网络延迟也会相互作用,但并不融合。过度的中断相关活动可能拖延机器上对时间敏感的工作,拥塞的路径可能拖延数据包,而在同一次可见的停顿中,这两件事可以同时成立。
把每一项观测放进同一个时间窗
只有读取包含症状的那段时间,跟踪才有意义。把跟踪记录、客户端事件和应用故障连同时间戳一起记下来,然后在这三者中查看同一批秒数。一小时跟踪里的最大值和当天下午晚些时候的断开,是两件互不相干的事实。
wpr -start CPU -filemode
wpr -stop vpn-trace.etl
xperf -i vpn-trace.etl -a dpcisr -o dpc.txt
然后在分析工具中打开跟踪,按该时间窗内的持续时间排序,而不是按整段捕获排序。CPU 分析指南 介绍了把时间归属到模块与函数的 DPC/ISR 持续时间视图。
确认隧道实际发生了什么,趁你还在那里的时候。应用流量短暂丢失并不意味着客户端开始了新的协商,一次小型探测成功也不能证明其余一切仍在正常工作。
只更换证据指向的组件
繁忙的模块是值得调查的地方,而不是判决。它可能在做别的组件造成的工作,也可能在做你制造的工作负载。把模块名、设备、驱动版本和观测到的时间段放在一起,因为供应商能着手处理的正是这一组信息。
每次实验只改一个变量,才是从结果中学到东西的唯一办法。有线对比能缩小范围,但它同时改变了无线路径和驱动活动,所以要把它当作线索,而不是证据。
把跟踪当作敏感数据。它可能包含进程名和环境细节,因此应当放在受支持的捕获渠道里,而不是公开附件。要说明这份跟踪本来是要回答哪一项观测。