网卡驱动和协议栈代码大致流程
数据包经过的位置观测
__netif_receive_skb_core
观察该函数是否有被调用,并观察调用的栈中使用的网卡驱动是否为virtio_net。
这里看到有被触发,说明该函数有被调用,数据包经过了该函数的处理,在这之前应该是正常的。
stap -ve 'probe kernel.function("__netif_receive_skb_core") \ {printf("vars: %s\n", $$vars$$); print_backtrace();}' | grep -C 10 -i virtio
ip_local_deliver_finish
tcp_v4_rcv
tcp_v4_do_rcv没有触发
丢包细节函数观测
上面排查,可以判断,数据包是在函数tcp_v4_rcv中被丢弃了,没有继续往上送
tcp_v4_rcv函数内容如下,里面宏、内联函数、运算语句等,不适合继续使用kernel.function的方式观测,没法在这些位置进行探针抓执行。
更换一种方式观测,由kernel.function更换为kernel.statement,查看可以观测的点如下,对照上面源码各行的位置,继续排查tcp_v4_rcv函数内部的执行情况
tcp_v4_rcv函数:1686行,执行了
tcp_v4_rcv函数:1723行,没有执行
tcp_v4_rcv函数:1686行返回失败(skb_checksum_init)
1686有被调用,但是1691没有调用,所以应该是1686行函数返回了错误,执行了goto csum_error;
下面观测1761行有被调用,正常该行是不应该被调用的,应该在上面1753行的return返回结束该函数。
1761行执行完毕后,会继续,直到执行到1770行是否skb包(丢弃)然后再return结束该函数。
所以,从执行情况来看,skb数据包并没有被tcp层正常处理,所以也没有回应答包。
出错函数展开分析(skb_checksum_init)
网卡的checksum情况查看
host的tx csum打开了,但是soc的rx端关闭了csum,所以rx的csum由软件计算的,计算出错了。
尝试关闭两侧的tx的csum,均由软件来进行csum计算
执行iperf测试,soc为server,host为client,测试通了