1.什么是TSO GSO
TSO是tcp segment offload的缩写,GSO是 generic segmentation offload 的缩写。
详细解释参看http://en.wikipedia.org/wiki/Large_segment_offload
对TSO的简单理解就是:
比如:我们要用汽车把3000本书送到另一个城市,每趟车只能装下1000本书,
那么我们就要书分成3次来发。如何把3000本书分成3份的事情是我们做的,汽车司机只负责运输。
TSO的概念就是:我们把3000本书一起给司机,由他去负责拆分的事情,这样我们就有更多的时间处理其他事情。
对应到计算机系统中,“我们”就是CPU,“司机”就是网卡。
在网络系统中,发送tcp数据之前,CPU需要根据MTU(一般为1500)来将数据放到多个包中发送,对每个数据包都要添加ip头,tcp头,分别计算IP校验和,TCP校验和。如果有了支持TSO的网卡,CPU可以直接将要发送的大数据发送到网卡上,由网卡硬件去负责分片和计算校验和。
2. TSO GSO网卡驱动与系统的接口:
步骤1. 设置支持TSO support flag, 同时需要支持SG
netdev->features |= NETIF_F_TSO;
netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
步骤2 设置GSO最大值
netdev ->gso_max_size = 8*1024; //网卡支持的gso size,通知系统每个tcp数据块的最大长度。
//TCP的窗口大小最大为64K,
步骤3: 发送函数需要处理skb数据。
支持tso的skb数据存储格式如下:
第一块数据存储在skb的data->tail之间,其他分块存储在skb_shinfo(skb)->frags中。
代码示例如下:
步骤4: 支持 ethtool
static struct ethtool_ops comNIC_ethtool_ops = {
.get_settings = netdev_get_settings,
.set_settings = netdev_set_settings,
.get_drvinfo = netdev_get_drvinfo,
.get_link = netdev_get_link,
.get_rx_csum = cmb_ethtool_op_get_rx_csum,
.set_rx_csum = cmb_ethtool_op_set_rx_csum,
.get_tx_csum = cmb_ethtool_op_get_tx_csum,
.set_tx_csum = cmb_ethtool_op_set_tx_csum,
//.set_sg = ethtool_op_set_sg,
#ifdef NETIF_F_TSO
.get_tso = cmb_ethtool_op_get_tso,
.set_tso = cmb_ethtool_op_set_tso,
#endif
}
命令行检验:
查看是否支持tso gso等:
ethtool -k comnic0
设置tso gso打开和关闭
ethtool -K comnic0 tso off
ethtool -K comnic0 gso off
-----------------------------------驱动对tso gso的支持完成-----------------------------------------------
ps:1.支持tso需要同时声明支持scattle / gather, 因为skb的分片数据不是存储在一个连续的地址上。当然:网卡硬件可以不支持scattle/gather这种DMA方式。
2. 需要同时支持硬件校验和。