GSO和TSO
http://www.cnhalo.net/2016/09/13/linux-tcp-gso-tso/
TSO(TCP Segmentation Offload):
是一种利用网卡来对大数据包进行自动分段,降低CPU负载的技术。 其主要是延迟分段
GSO(Generic Segmentation Offload):
GSO是协议栈是否推迟分段,在发送到网卡之前判断网卡是否支持TSO,如果网卡支持TSO则让网卡分段,否则协议栈分完段再交给驱动。 如果TSO开启,GSO会自动开启
- GSO开启, TSO开启: 协议栈推迟分段,并直接传递大数据包到网卡,让网卡自动分段
- GSO开启, TSO关闭: 协议栈推迟分段,在最后发送到网卡前才执行分段
- GSO关闭, TSO开启: 同GSO开启, TSO开启
- GSO关闭, TSO关闭: 不推迟分段,在tcp_sendmsg中直接发送MSS大小的数据包
驱动程序在注册网卡设备的时候默认开启GSO: NETIF_F_GSO
驱动程序会根据网卡硬件是否支持来设置TSO: NETIF_F_TSO
可以通过ethtool -K来开关GSO/TSO
#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO)
int register_netdevice(struct net_device *dev)
{
----------------------------------------------- /* Transfer changeable features to wanted_features and enable
* software offloads (GSO and GRO).
*/
dev->hw_features |= NETIF_F_SOFT_FEATURES;
dev->features |= NETIF_F_SOFT_FEATURES;//默认开启GRO/GSO
dev->wanted_features = dev->features & dev->hw_features; if (!(dev->flags & IFF_LOOPBACK)) {
dev->hw_features |= NETIF_F_NOCACHE_COPY;
} /* Make NETIF_F_HIGHDMA inheritable to VLAN devices.
*/
dev->vlan_features |= NETIF_F_HIGHDMA; /* Make NETIF_F_SG inheritable to tunnel devices.
*/
dev->hw_enc_features |= NETIF_F_SG; /* Make NETIF_F_SG inheritable to MPLS.
*/
dev->mpls_features |= NETIF_F_SG;
GSO/TSO是否开启是保存在dev->features中,而设备和路由关联,当我们查询到路由后就可以把配置保存在sock中
比如在tcp_v4_connect和tcp_v4_syn_recv_sock都会调用sk_setup_caps来设置GSO/TSO配置
/* This will initiate an outgoing connection. */
int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
{
--------------------------------
orig_sport = inet->inet_sport;
orig_dport = usin->sin_port;
fl4 = &inet->cork.fl.u.ip4;
rt = ip_route_connect(fl4, nexthop, inet->inet_saddr,
RT_CONN_FLAGS(sk), sk->sk_bound_dev_if,
IPPROTO_TCP,
orig_sport, orig_dport, sk);
--------------------------------------
//调用sk_setup_caps来设置GSO/TSO配置
/* OK, now commit destination to socket. */
sk->sk_gso_type = SKB_GSO_TCPV4;
sk_setup_caps(sk, &rt->dst); ----------------------------------------- err = tcp_connect(sk); rt = NULL;
if (err)
void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
{
/* List of features with software fallbacks. */
#define NETIF_F_GSO_SOFTWARE (NETIF_F_TSO | NETIF_F_TSO_ECN | \
NETIF_F_TSO6 | NETIF_F_UFO)
u32 max_segs = 1; sk_dst_set(sk, dst);
sk->sk_route_caps = dst->dev->features;
if (sk->sk_route_caps & NETIF_F_GSO)//软件GSO,默认开启
sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE;//开启延时gso延时选项,包括NETIF_F_TSO
sk->sk_route_caps &= ~sk->sk_route_nocaps;
if (sk_can_gso(sk)) {
if (dst->header_len) {
sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
} else {
sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;// 开启gso后,设置sg和校验
sk->sk_gso_max_size = dst->dev->gso_max_size;//GSO_MAX_SIZE=65536
max_segs = max_t(u32, dst->dev->gso_max_segs, 1);
}
}
sk->sk_gso_max_segs = max_segs;
}
//判断GSO或TSO是否开启
static inline bool sk_can_gso(const struct sock *sk)
{
return net_gso_ok(sk->sk_route_caps, sk->sk_gso_type);
}
static inline bool net_gso_ok(netdev_features_t features, int gso_type)
{
netdev_features_t feature = gso_type << NETIF_F_GSO_SHIFT;
//对于tcp4, 判断NETIF_F_TSO是否被设置, 即使硬件不支持TSO,开启GSO的情况下也会被设置 /* check flags correspondence */
BUILD_BUG_ON(SKB_GSO_TCPV4 != (NETIF_F_TSO >> NETIF_F_GSO_SHIFT));
BUILD_BUG_ON(SKB_GSO_UDP != (NETIF_F_UFO >> NETIF_F_GSO_SHIFT));
BUILD_BUG_ON(SKB_GSO_DODGY != (NETIF_F_GSO_ROBUST >> NETIF_F_GSO_SHIFT));
BUILD_BUG_ON(SKB_GSO_TCP_ECN != (NETIF_F_TSO_ECN >> NETIF_F_GSO_SHIFT));
BUILD_BUG_ON(SKB_GSO_TCPV6 != (NETIF_F_TSO6 >> NETIF_F_GSO_SHIFT));
BUILD_BUG_ON(SKB_GSO_FCOE != (NETIF_F_FSO >> NETIF_F_GSO_SHIFT));
BUILD_BUG_ON(SKB_GSO_GRE != (NETIF_F_GSO_GRE >> NETIF_F_GSO_SHIFT));
BUILD_BUG_ON(SKB_GSO_GRE_CSUM != (NETIF_F_GSO_GRE_CSUM >> NETIF_F_GSO_SHIFT));
BUILD_BUG_ON(SKB_GSO_IPIP != (NETIF_F_GSO_IPIP >> NETIF_F_GSO_SHIFT));
BUILD_BUG_ON(SKB_GSO_SIT != (NETIF_F_GSO_SIT >> NETIF_F_GSO_SHIFT));
BUILD_BUG_ON(SKB_GSO_UDP_TUNNEL != (NETIF_F_GSO_UDP_TUNNEL >> NETIF_F_GSO_SHIFT));
BUILD_BUG_ON(SKB_GSO_UDP_TUNNEL_CSUM != (NETIF_F_GSO_UDP_TUNNEL_CSUM >> NETIF_F_GSO_SHIFT));
BUILD_BUG_ON(SKB_GSO_TUNNEL_REMCSUM != (NETIF_F_GSO_TUNNEL_REMCSUM >> NETIF_F_GSO_SHIFT)); return (features & feature) == feature;
}
对紧急数据包或GSO/TSO都不开启的情况,才不会推迟发送, 默认使用当前MSS
开启GSO后,tcp_send_mss返回mss和单个skb的GSO大小,为mss的整数倍
int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
{
------------------------------------------------------------
/* This should be in poll */
sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); mss_now = tcp_send_mss(sk, &size_goal, flags); }
GSO和TSO的更多相关文章
- CEPH经常出现slow request的排查解决
现象: 通过ceph -w日志经常发现有request blocked的问题(如果虚拟机系统跑在ceph上时,就会发现严重的卡顿现象) 排查: 1.通过dstat未发现有明显的瓶颈 (dstat -t ...
- TCP系列50—拥塞控制—13、Eifel探测下的拥塞撤销
一.概述 我们之前在SACK关闭场景下的拥塞撤销那篇文章中提到过Eifel探测算法(Eifel Detection Algorithm),最早在介绍DSACK和FRTO的时候我们就有提到过Eifel探 ...
- virtio使用
Windows 参考文档 下载virtio驱动 下载地址 如果是在Fedora或CentOS环境下,可使用yum的方式下载驱动 [root@centos centos]#wget https://fe ...
- Linux3.5内核以后的路由下一跳缓存
在Linux3.5版本号(包括)之前.存在一个路由cache.这个路由cache的初衷是美好的,可是现实往往是令人遗憾的.下面是陈列得出的两个问题:1.面临针对hash算法的ddos问题(描写叙述该问 ...
- 从C10K到C10M高性能网络的探索与实践
在高性能网络的场景下,C10K是一个具有里程碑意义的场景,15年前它给互联网领域带来了非常大的挑战.发展至今,我们已经进入C10M的场景进行网络性能优化. 这期间有怎样的发展和趋势?环绕着各类指标分别 ...
- KVM原理及使用
Qemu 和 Qemu-kvm Qemu: http://qemu-project.org/Download Qemu-kvm:https://sourceforge.net/projects/kvm ...
- [ kvm ] 学习笔记 4:KVM 高级功能详解
1. 半虚拟化驱动 1.1 virtio 概述 KVM 是必须使用硬件虚拟化辅助技术(如 Intel VT-x .AMD-V)的 Hypervisor,在CPU 运行效率方面有硬件支持,其效率是比较高 ...
- 网络虚拟化中的 offload 技术:LSO/LRO、GSO/GRO、TSO/UFO、VXLAN
offload 现在,越来越多的网卡设备支持 offload 特性,来提升网络收/发性能.offload 是将本来该操作系统进行的一些数据包处理(如分片.重组等)放到网卡硬件中去做,降低系统 CPU ...
- GSO/TSO/GRO等对VirtIO虚机的网络性能影响分析(by quqi99)
作者:张华 发表于:2016-04-05版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 ( http://blog.csdn.net/quqi99 ) IP层 ...
随机推荐
- c# 误区系列(一)
前言 整理很早以前认为的一些误区,准备整理一个系列.新手可以看下,然后大佬指点一下是否哪些地方错了. 正文 值类型存在栈上,引用类型存在堆上 很多人认为用这句话来解释值类型和栈类型的区别,甚至有些文章 ...
- Java 10 种常用第三方服务
严格意义上说,所有软件的第三方服务都可以自己开发,不过从零到一是需要时间和金钱成本的.就像我们研发芯片,投入了巨大的成本,但仍然没有取得理想的成绩,有些事情并不是一朝一夕,投机取巧就能完成的. Jav ...
- Mysql架构与内部模块-第二章
接上文,上文简述到了Mysql中的查询缓存和解析器,今日我们继续. 先来看一段SQL:SELECT * FROM `jianghuadong`; 先假设我们数据库中并没有一张名为jianghuadon ...
- json对象去重,根据指定字段
function FilterByName(data, Name) { //data是json对象,Name是根据什么字段去重 var map = {}, dest = []; for (var i ...
- 如果你想or即将成为一名程序员,那你需要知道这些东西!上岗须知~
前两天公司学院的同学给我看了一下即将入职的应届生的数量,真是不少.感慨一下,一批新人即将到来,而自己又老去了一岁.码农是一个必将终身学习的职业.而相关的知识越来越多了.接下来该学什么?接下来该干什么? ...
- scp带密码拷贝文件
应用场景:将B服务器的文件传输到A服务器.核心命令: sshpass -p 123456 scp ubuntu@192.168.52.1:/home/ubuntu/"TEST"'' ...
- 运行bee run之后出现的错误以及解决方法Failed to build the application:
运行bee run之后出现的错误以及解决方法 创建一个beego项目 bee new myapp 在该项目执行下面的代码 bee run 出现的问题 2020/04/22 21:12:07 INF ...
- Linux+Nginx/Apache下的PHP exec函数执行Linux命令
1.php.ini配置文件 打开PHP的配置文件,里面有一行 disable_function 的值,此处记录了禁止运行的函数,在里面将exec和shell_exec.system等函数删除. 2.权 ...
- elastic后台运行
nohup./bin/elasticsearch&
- MySQL全面瓦解:安装部署与准备
下载与安装 互联网高速时代下,我们的生活发生了巨大的变化,从购物(淘宝.京东),出行(滴滴.快狗),支付(支付宝.微信)等,遍及我们生活的方方面面,我们使用这些系统和应用的时候,会在上面获取.存储大量 ...