How to Trace TCP Socket TCP_INFO tcpi_rcv_wnd Scaling in Linux Using eBPF

Monitoring local receive buffer availability across high-capacity Linux servers is essential for preventing host-side TCP window clamping. The kernel struct tcp_info maintains tcpi_rcv_wnd, reflecting the current receive window advertised by the local host to remote senders. Tracing this value with eBPF gives real-time insights into socket memory consumption and auto-tuning performance.

Receive Window Scaling Mechanics

Linux employs dynamic receive buffer auto-tuning controlled by net.ipv4.tcp_rmem. When host processes read data slowly from the socket queue or when system RAM enters memory pressure zones, the kernel contracts the advertised receive window (rcv_wnd) to prevent packet drops at the transport interface.

eBPF BCC Program for Receive Window Tracing

Deploy the following BCC Python script to attach a kprobe to tcp_rcv_space_adjust and track receive window adaptations:

from bcc import BPF

bpf_code = """
#include <net/sock.h>
#include <linux/tcp.h>

struct rcv_event_t {
    u32 pid;
    u16 sport;
    u16 dport;
    u32 rcv_wnd;
};

BPF_PERF_OUTPUT(rcv_events);

int trace_rcv_adjust(struct pt_regs *ctx, struct sock *sk) {
    if (sk->sk_family != AF_INET)
        return 0;

    struct tcp_sock *tp = tcp_sk(sk);
    struct rcv_event_t evt = {};

    evt.pid = bpf_get_current_pid_tgid() >> 32;
    evt.sport = sk->sk_num;
    evt.dport = bpf_ntohs(sk->sk_dport);
    evt.rcv_wnd = tp->rcv_wnd;

    rcv_events.perf_submit(ctx, &evt, sizeof(evt));
    return 0;
}
"""

b = BPF(text=bpf_code)
b.attach_kprobe(event="tcp_rcv_space_adjust", fn_name="trace_rcv_adjust")

def print_rcv(cpu, data, size):
    evt = b["rcv_events"].event(data)
    print(f"PID {evt.pid:<6} | Port {evt.sport} -> {evt.dport} | Advertised rcv_wnd: {evt.rcv_wnd} bytes")

b["rcv_events"].open_perf_buffer(print_rcv)
print("Listening for tcpi_rcv_wnd adaptations... Press Ctrl+C to exit.")
while True:
    b.perf_buffer_poll()

Operational Diagnosis and Tuning

Run the script under root privileges:

sudo python3 trace_rcv_wnd.py

If rcv_wnd consistently shrinks under moderate load, audit the maximum socket buffer limits using sysctl net.ipv4.tcp_rmem and verify that socket reader threads are not experiencing worker thread starvation.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.