6.stap script

在probe一些函数的时候,会有额外的开销,systemtap在检测到overhead过大时,会终止脚本运行,下面我们利用一个脚本来验证:

  #system-overhead.stp
  1 global veth_xmit_cnt
  2 
  3 probe begin
  4 {
  5         veth_xmit_cnt=0;
  6 }       
  7 
  8 probe module("veth").function("veth_xmit")
  9 {
 10         veth_xmit_cnt++;
 11 }       
 12 
 13 probe timer.s(1)
 14 {
 15         printf("veth xmit :%d pps\n",veth_xmit_cnt);
 16         veth_xmit_cnt=0;
 17 }

这个脚本能够probe veth模块中veth_xmit()函数被调用的次数,通过pktgen对veth建立的两个接口发包测试,开启probe时候,通过stap统计得到veth上传输的速率:

另一方面,通过sar命令统计接口上的传输速率,得到一致的结果:

接下来,我们停止stap脚本,可以看出veth传输具有明显的提升:

甚至在解析数据结构的时候会出现overhead过重而终止脚本,我们可以使用-DSTP_NO_OVERLOAD来使得脚本即使在负重下也能运行。因此接下来我们使用stap脚本在性能探测的时候probe点每次只放置在一个地方。probe结果应该偏功能。

接下来探测linux设备驱动将数据包扔到linux网络协议栈后,来自一个以太网接口的数据包的在SMP多对成处理器上的分散情形。 首先探测来自网卡驱动的手包情况,通常网卡驱动的硬件中断会触发所在队列的NAPI,从而进行收发包并通过netif_receive_skb()或者netif_rx()函数递交给协议栈,单最终会经过enqueue_to_backlog()函数在硬件中断NAPI底半部分发给其他cpu,且在这个过程中完成RPS分布。

探测RPS功能的脚本如下所示:

主要记录enqueue_to_backlog()由谁调用,以及入队列的时候将数据包交给谁。

接下来我们利用pktgen发包测试,pktgen构造数据包的时候源地址随机保障hash值变化。并且初始状态下网卡的队列掩码为0.

开始发包后,可以看到脚本输出:

通过观察发现,我们可以知道:

  • 由驱动接收数据包都在一个cpu上完成,这个cpu是cpu0,原因是veth虚拟网卡只有一个队列。

  • 虚拟网卡队列0默认没有开启RPS,所以在网上入队列的时候会与处理函数这个cpu所在的队列softnet上。

Last updated

Was this helpful?