Skip to content

Tags: bobrik/linux

Tags

ivan/tcp-listen-drop-tracepoint-inline.const.v2

Toggle ivan/tcp-listen-drop-tracepoint-inline.const.v2's commit message
tcp: add a tracepoint for tcp_listen_queue_drop

There's already a way to count the overall numbers of queue overflows:

    $ sudo netstat -s | grep 'listen queue'
    4 times the listen queue of a socket overflowed

However, it's too coarse for monitoring and alerting when a user wants to
track errors per socket and route alerts to people responsible for those
sockets directly. For UDP there's udp_fail_queue_rcv_skb, which fills
a similar need for UDP sockets. This patch adds a TCP equivalent.

--

The goal is to use this new tracepoint with ebpf_exporter:

* https://github.com/cloudflare/ebpf_exporter

There's an example configuration for UDP drops there that we use:

* https://github.com/cloudflare/ebpf_exporter/blob/master/examples/udp-drops.bpf.c
* https://github.com/cloudflare/ebpf_exporter/blob/master/examples/udp-drops.yaml

I added a TCP example utilizing this patch here:

* cloudflare/ebpf_exporter#221

Not so long ago we hit a bug in one of our services that broke its accept
loop, which in resulted in the listen queue overflow. With this new
tracepoint we can have a metric for this and alert the service owners
directly, cutting the middleman SRE and improving the alert fidelity.

We don't really need a tracepoint for this, just a place to hook a kprobe
or an fprobe to. The existing tcp_listendrop is great for this, except
it's a short inlined function, so there's no way to attach a probe to it.

There are two ways to approach this:

* Un-inline tcp_listendrop to allow probe attachment
* Un-inline tcp_listendrop and add a stable tracepoint
* Keep tcp_listendrop inlined, but add a tracepoint wrapper to call into

There is no option to keep tcp_listendrop inlined and call into tracepoint:

* https://docs.kernel.org/trace/tracepoints.html

Therefore I went with the third option, which this patch implements.

Example output from perf:

    $ sudo perf trace -a -e tcp:tcp_listen_queue_drop
    0.000 sockfull/5459 tcp:tcp_listen_queue_drop(skaddr: 0xffffff90d7a25580, sport: 12345, saddr: 0x7faa1aed26, saddr_v6: 0x7faa1aed2a, sk_max_ack_backlog: 128, sk_ack_backlog: 129)

Example extracting the local port with bpftrace:

    $ sudo ~/projects/bpftrace/src/bpftrace -e 'rawtracepoint:tcp_listen_queue_drop { $sk = (struct sock *) arg0; $lport = $sk->__sk_common.skc_num; printf("drop on lport = %d\n", $lport); }'
    Attaching 1 probe...
    drop on lport = 12345

Signed-off-by: Ivan Babrou <[email protected]>

v6.4

Toggle v6.4's commit message
Linux 6.4

v6.4-rc7

Toggle v6.4-rc7's commit message
Linux 6.4-rc7

v6.4-rc6

Toggle v6.4-rc6's commit message
Linux 6.4-rc6

v6.4-rc5

Toggle v6.4-rc5's commit message
Linux 6.4-rc5

v6.4-rc4

Toggle v6.4-rc4's commit message
Linux 6.4-rc4

v6.4-rc3

Toggle v6.4-rc3's commit message
Linux 6.4-rc3

v6.4-rc2

Toggle v6.4-rc2's commit message
Linux 6.4-rc2

v6.4-rc1

Toggle v6.4-rc1's commit message
Linux 6.4-rc1

v6.3

Toggle v6.3's commit message
Linux 6.3