Linux kernel TCP smoothed-RTT estimation
2021/12/6 7:17:16
本文主要是介绍Linux kernel TCP smoothed-RTT estimation,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
https://strugglingcoder.info/index.php/linux-kernel-tcp-smoothed-rtt-estimation/
Posted: February 18th, 2018 | Author: hiren | Filed under: Linux, networking, tcp | Tags: linux, networking, rtt, srtt, tcp | Comments Off on Linux kernel TCP smoothed-RTT estimation
Recently I decided to look under the hood to see how exactly srtt is calculated in Linux. Actual (Exponentially Weighted Moving Average) srtt calculation is a rather straight-forward part but what goes in as input to that calculation under various scenarios is interesting and very important in getting correct rtt estimate.
Also useful to note the difference between Linux and FreeBSD in this regard. Linux doesn’t trust tcp packet Timestamps option provided value whenever possible as middle-boxes can meddle with it.
Basic algorithm is:
For non-retransmitted packets, use saved packet send timestamp and ack arrival time.
For retransmitted packets, use timestamp option and if that’s not enabled, rtt is not calculated for such packets.
Let’s look at the code. I am using net-next.
When a TCP sender sends packets, it has to wait for acks for those packets before throwing them away. It stores them in a queue called ‘retransmission queue’.
When sent packets get acked, tcp_clean_rtx_queue() gets called to clear those packets from the retransmission queue.
A few useful variables in that function are:
seq_rtt_us – uses first packet from ackd range
ca_rtt_us – uses last packet from ackd range (mainly used for congestion control)
sack_rtt_us – uses sacked ack
tcp_mstamp is a tcp_sock member which represents timestamp of most recent packet received/sent. It gets updated by tcp_mstamp_refresh().
For a clean ack (not sack), seq_rtt_us = ca_rtt_us (as there is no range)
If such a clean is also for a non-retransmitted packet,
[sourcecode language=”c”]seq_rtt_us = tcp_stamp_us_delta(tp->tcp_mstamp, first_ackt);[/sourcecode]
and for a sack which is again for a non-retransmitted packet,
[sourcecode language=”c”]sack_rtt_us = tcp_stamp_us_delta(tp->tcp_mstamp, sack->first_sackt);[/sourcecode]
Code that updates sack→first_sackt is in tcp_sacktag_one() where it gets populated when the sack is for a non-retransmitted packet.
tcp_stamp_us_delta() gets the difference with timestamp that the stack maintains.
Now tcp_ack_update_rtt() gets called which starts out with:
[sourcecode language=”c”]
/* Prefer RTT measured from ACK’s timing to TS-ECR. This is because
* broken middle-boxes or peers may corrupt TS-ECR fields. But
* Karn’s algorithm forbids taking RTT if some retransmitted data
* is acked (RFC6298).
*/
if (seq_rtt_us < 0)
seq_rtt_us = sack_rtt_us;
[/sourcecode]
For acks acking retransmitted packets, seq_rtt_us would be -ve.
But if there is a SACK timestamp from a non-retransmitted packet, it would use that as it carries valid and useful timestamps.
Then it takes TS-opt provided timestamps only if seq_rtt_us is -ve.
[sourcecode language=”c”]
if (seq_rtt_us < 0 && tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr &&
flag & FLAG_ACKED) {
u32 delta = tcp_time_stamp(tp) – tp->rx_opt.rcv_tsecr;
u32 delta_us = delta * (USEC_PER_SEC / TCP_TS_HZ);
seq_rtt_us = ca_rtt_us = delta_us;
}
[/sourcecode]
By this point, there is seq_rtt_us that can be fed into tcp_rtt_estimator() that’d generate smoothed-RTT (which is more or less based on SIGCOMM 88 paper by Van Jacobson).
这篇关于Linux kernel TCP smoothed-RTT estimation的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-18git仓库有更新,jenkins 自动触发拉代码怎么配置的?-icode9专业技术文章分享
- 2024-12-18Jenkins webhook 方式怎么配置指定的分支?-icode9专业技术文章分享
- 2024-12-13Linux C++项目实战入门教程
- 2024-12-13Linux C++编程项目实战入门教程
- 2024-12-11Linux部署Scrapy教程:新手入门指南
- 2024-12-11怎么将在本地创建的 Maven 仓库迁移到 Linux 服务器上?-icode9专业技术文章分享
- 2024-12-10Linux常用命令
- 2024-12-06谁看谁服! Linux 创始人对于进程和线程的理解是…
- 2024-12-04操作系统教程:新手入门及初级技巧详解
- 2024-12-04操作系统入门:新手必学指南