linux Tcp Small Queue
考虑以下场景
- 有两个tcp,其中一个连接的cwnd非常大,应用程序尽可能地发包
- 或者有个应用程序一直往外无限制地发送udp包 如果没有一种机制公平地限定各个连接的发送数量,底层的qdisc/网卡队列就会被高发包率的应用占用,同时造成上层tcp计算RTT和cwnd的偏差,以及bufferbloat问题。
尤其对于默认采用pfifo_fast qdisc算法来说非常常见, 因为基本上只使用一个队列(大多数流的TOS=0)
TCP Small Queues Question 内核草案 我们可以调整 /proc/sys/net/ipv4/tcp_limit_output_bytes
以实现队列长度,队列补丁看起来至少能够填补这一空白。它限制了任何给定的 Socket 可以排队传输的数据量,而不管数据在哪里排队。缺省值为 128KB 。
“bufferbloat”问题是网络堆栈缓冲过多的结果;它导致整个网络的延迟时间长和可靠性差。修复它是在任何两个端点之间的每个系统中缓冲较少数据的问题——这项任务听起来很简单,但事实证明比人们预期的更具挑战性。事实证明,缓冲可以出现在网络堆栈中许多令人惊讶的地方;追踪所有这些地方并修复它们并不总是那么容易。
在过去的一年里,许多抗膨胀的变化已经进入了内核。CoDel 队列管理算法可防止 数据包随时间在路由器队列中堆积。在低得多的级别上,字节队列限制对可以等待传出特定网络接口的数据量设置了上限。不过,字节队列限制仅在设备队列级别起作用,而网络堆栈还有其他地方(例如排队规则级别)可以进行缓冲。因此,在设备队列之上的级别上限制缓冲的实现将是有价值的。
Eric Dumazet 的TCP small queues 补丁看起来应该能够至少填补部分空白。它限制了任何给定套接字可以排队等待传输的数据量,而不管数据在何处排队,因此它不应该被潜伏在排队、流量控制或 netfilter 代码中的缓冲区所愚弄。该限制由位于以下位置的新 sysctl 旋钮设置:
/proc/sys/net/ipv4/tcp_limit_output_bytes
此限制的默认值为 128KB;在延迟是主要问题的系统上,它可以设置得更低。
网络堆栈已经跟踪等待通过任何给定套接字传输的数据量;该值位于 struct sock的sk_wmem_alloc字段中。所以应用限制相对容易;tcp_write_xmit()只需查看 sk_wmem_alloc是否超出限制。如果是这种情况,套接字将被标记为被限制并且不再有数据包排队。
更难的部分是弄清楚何时打开一些空间并且可以将更多数据包添加到队列中。队列空间变为空闲的时间是排队的数据包被释放的时间。因此,当输出限制生效时,Eric 的补丁会覆盖正常的 struct sk_buff析构函数;新的析构函数可以检查是否到了为相关套接字排队更多数据的时间。唯一的问题是这个析构函数可以从已经持有重要锁的网络堆栈深处调用,所以它不能直接对新数据进行排队。所以 Eric 不得不添加一个新的 tasklet 来完成排队新数据包的实际工作。
该补丁似乎具有预期的结果:
标签:限制,队列,排队,tcp,堆栈,数据包,TSQ From: https://www.cnblogs.com/codestack/p/17299743.html