Linux – How to Tune Initial TCP Retransmit Timeout

linuxlinux-kerneltcp

The initial TCP RTO value of 3s is too long for most LAN-based applications. How can I tune it lower? Is there a sysctl?

Best Answer

See this blog post for how you can make an eBPF program that will override the timeout.

In short, you need to load this sockops program:

#include<linux/bpf.h>
#define SEC(NAME) __attribute__((section(NAME), used))

// TODO: assumes little-endian (x86, amd64)
#define bpf_ntohl(x)  __builtin_bswap32(x)

SEC("sockops")
int bpf_sockmap(struct bpf_sock_ops *skops)
{
  const int op = (int) skops->op;
  if (op == BPF_SOCK_OPS_TIMEOUT_INIT) {
     // TODO: this is in jiffies, and despite `getconf CLK_TCK` return 100, HZ is clearly 250 on my kernel.
     // 5000 / 250 = 20 seconds
     skops->reply = 5000;
     return 1;
  }
  return 0;
}
char _license[] __attribute((section("license"),used)) = "GPL";
int _version SEC("version") = 1;

You can compile and load it with:

clang $CFLAGS -target bpf  -Wall -g -O2 -c set_rto.c -o set_rto.o
sudo bpftool prog load set_rto.o  /sys/fs/bpf/bpf_sockop
sudo bpftool cgroup attach /sys/fs/cgroup/unified/ sock_ops pinned /sys/fs/bpf/set_rto