TCP的TSO处理(一)(一)

2014-11-24 09:53:38 · 作者: · 浏览: 3

概述

In computer networking, large segment offload (LSO) is a technique for increasing outbound
throughput of high-bandwidth network connections by reducing CPU overhead. It works by queuing
up large buffers and letting the network interface card (NIC) split them into separate packets.
The technique is also called TCP segmentation offload (TSO) when applied to TCP, or generic
segmentation offload (GSO).
The inbound counterpart of large segment offload is large recive offload (LRO).
When large chunks of data are to be sent over a computer network, they need to be first broken
down to smaller segments that can pass through all the network elements like routers and
switches between the source and destination computers. This process it referred to as
segmentation. Segmentation is often done by the TCP protocol in the host computer. Offloading
this work to the NIC is called TCP segmentation offload (TSO).
For example, a unit of 64KB (65,536 bytes) of data is usually segmented to 46 segments of 1448
bytes each before it is sent over the network through the NIC. With some intelligence in the NIC,
the host CPU can hand over the 64KB of data to the NIC in a single transmit request, the NIC can
break that data down into smaller segments of 1448 bytes, add the TCP, IP, and data link layer
protocol headers——according to a template provided by the host's TCP/IP stack——to each
segment, and send the resulting frames over the network. This significantly reduces the work
done by the CPU. Many new NICs on the market today support TSO. [1]

具体

It is a method to reduce CPU workload of packet cutting in 1500byte and asking hardware to
perform the same functionality.
1. TSO feature is implemented using the hardware support. This means hardware should be
able to segment the packets in max size of 1500 byte and reattach the header with every
packets.
2. Every network hardware is represented by netdevice structure in kernel. If hardware supports
TSO, it enables the Segmentation offload features in netdevice, mainly represented by
" NETIF_F_TSO" and other fields. [2]
TCP Segmentation Offload is supported in Linux by the network device layer. A driver that wants
to offer TSO needs to set the NETIF_F_TSO bit in the network device structure. In order for a
device to support TSO, it needs to also support Net : TCP Checksum Offloading and
Net : Scatter Gather.
The driver will then receive super-sized skb's. These are indicated to the driver by
skb_shinfo(skb)->gso_size being non-zero. The gso_size is the size the hardware should

fragment the TCP data. TSO may change how and when TCP decides to send data. [3]

实现

[java]
/* This data is invariant across clones and lives at the end of the
* header data, ie. at skb->end.
*/
struct skb_share_info {
...
unsigned short gso_size; // 每个数据段的大小
unsigned short gso_segs; // skb被分割成多少个数据段
unsigned short gso_type;
struct sk_buff *frag_list; // 分割后的数据包列表
...
}
[java]
/* Initialize TSO state of skb.
* This must be invoked the first time we consider transmitting
* SKB onto the wire.
*/
static int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb,
unsigned int mss_now)
{
int tso_segs = tcp_skb_pcount(skb);

/* 如果还没有分段,或者有多个分段但是分段长度不等于当前MSS,则需处理*/
if (! tso_segs || (tso_segs > 1 && tcp_skb_mss(skb) != mss_now)) {
tcp_set_skb_tso_segs(sk, skb, mss_now);

tso_segs = tcp_skb_pcount(skb);/* 重新获取分段数量 */
}
return tso_segs;
}

/* Initialize TSO segments for a packet. */
static void tc