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中。
代碼示例如下:
{
size = (skb->tail - skb->data); // the first fragment is stored in the skb.
for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
size += skb_shinfo(skb)->frags[f].size; ////other frags .
}
memcpy(dbg_send_queue, skb->data, skb->tail - skb->data); //real first frag
for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) //process frags.
{
struct skb_frag_struct *frag;
int f_offset = 0;
int f_len = 0;
char *addr;
frag = &skb_shinfo(skb)->frags[f];
f_len = frag->size;
f_offset = frag->page_offset;
addr = (char *)page_address(frag->page) ; //change page addr to virt addr.
memcpy(dbg_send_queue, addr + f_offset, f_len);
offset += f_len;
}
}
步驟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. 需要同時支持硬件校驗和。