Tags: bobrik/linux
Tags
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]>
PreviousNext