mirror of
https://github.com/brendangregg/perf-tools.git
synced 2025-11-30 23:16:03 +07:00
Merge pull request #7 from csfrancis/tcpretrans_tlp
Add support for TCP tail loss probes
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
tcpretrans \- show TCP retransmits, with address and other details. Uses Linux ftrace.
|
||||
.SH SYNOPSIS
|
||||
.B tcpretrans
|
||||
[\-hs]
|
||||
[\-hsp]
|
||||
.SH DESCRIPTION
|
||||
This traces TCP retransmits that are sent by the system tcpretrans is executed
|
||||
from, showing address, port, and TCP state information,
|
||||
@@ -25,6 +25,7 @@ Since this uses ftrace, only the root user can use this tool.
|
||||
.SH REQUIREMENTS
|
||||
FTRACE and KPROBE CONFIG, tcp_retransmit_skb() kernel function.
|
||||
You may have these already have these on recent kernels. And Perl.
|
||||
TCP tail loss probes were added in Linux 3.10.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\-h
|
||||
@@ -32,6 +33,9 @@ Print usage message.
|
||||
.TP
|
||||
\-s
|
||||
Include kernel stack traces.
|
||||
.TP
|
||||
\-p
|
||||
Include TCP tail loss probes.
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
Trace TCP retransmits
|
||||
@@ -62,6 +66,9 @@ Remote port.
|
||||
.TP
|
||||
STATE
|
||||
TCP session state.
|
||||
.TP
|
||||
TLP
|
||||
Tail loss probe: "Y/N".
|
||||
.SH OVERHEAD
|
||||
The CPU overhead is relative to the rate of TCP retransmits, and is
|
||||
designed to be low as this does not examine every packet. Once per second the
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
# sent by the kernel on timeouts). To keep overhead low, only
|
||||
# tcp_retransmit_skb() calls are traced (this does not trace every packet).
|
||||
#
|
||||
# USAGE: ./tcpretrans [-hs]
|
||||
# USAGE: ./tcpretrans [-hsp]
|
||||
#
|
||||
# REQUIREMENTS: FTRACE and KPROBE CONFIG, tcp_retransmit_skb() kernel function.
|
||||
# You may have these already have these on recent kernels. And Perl.
|
||||
@@ -67,16 +67,18 @@ local $SIG{HUP} = \&cleanup;
|
||||
$| = 1;
|
||||
|
||||
### options
|
||||
my ($help, $stacks);
|
||||
my ($help, $stacks, $tlp);
|
||||
GetOptions("help|h" => \$help,
|
||||
"stacks|s" => \$stacks)
|
||||
"stacks|s" => \$stacks,
|
||||
"tlp|p" => \$tlp)
|
||||
or usage();
|
||||
usage() if $help;
|
||||
|
||||
sub usage {
|
||||
print STDERR "USAGE: tcpretrans [-hs]\n";
|
||||
print STDERR "USAGE: tcpretrans [-hsp]\n";
|
||||
print STDERR " -h # help message\n";
|
||||
print STDERR " -s # print stack traces\n";
|
||||
print STDERR " -p # trace TCP tail loss probes\n";
|
||||
print STDERR " eg,\n";
|
||||
print STDERR " tcpretrans # trace TCP retransmits\n";
|
||||
exit;
|
||||
@@ -140,6 +142,27 @@ sub inet_h2a {
|
||||
return join(".", @addr);
|
||||
}
|
||||
|
||||
sub create_kprobe {
|
||||
my ($kname, $kval) = @_;
|
||||
appendto "p:$kname $kval", "kprobe_events"
|
||||
or ldie "ERROR: creating kprobe for $kname.";
|
||||
}
|
||||
|
||||
sub enable_kprobe {
|
||||
my ($kname) = @_;
|
||||
unless (writeto "1", "events/kprobes/$kname/enable") {
|
||||
appendto "-:$kname", "kprobe_events";
|
||||
ldie "ERROR: enabling kprobe.";
|
||||
}
|
||||
}
|
||||
|
||||
sub remove_kprobe {
|
||||
my ($kname) = @_;
|
||||
writeto "0", "events/kprobes/$kname/enable"
|
||||
or ldie "ERROR: disabling kprobe $kname";
|
||||
appendto "-:$kname", "kprobe_events";
|
||||
}
|
||||
|
||||
### check permissions
|
||||
chdir "$tracing" or die "ERROR: accessing tracing. Root? Kernel has FTRACE?" .
|
||||
"\ndebugfs mounted? (mount -t debugfs debugfs /sys/kernel/debug)";
|
||||
@@ -153,20 +176,18 @@ writeto "$$", $flock or die "ERROR: unable to write $flock.";
|
||||
|
||||
### setup and begin tracing
|
||||
writeto "nop", "current_tracer" or ldie "ERROR: disabling current_tracer.";
|
||||
my $kname = "tcpretrans_tcp_retransmit_skb";
|
||||
appendto "p:$kname tcp_retransmit_skb sk=%di", "kprobe_events"
|
||||
or ldie "ERROR: creating kprobe for inet_csk_accept().";
|
||||
my ($kname, $kname_tlp) = ("tcpretrans_tcp_retransmit_skb", "tcpretrans_tcp_send_loss_probe");
|
||||
create_kprobe $kname, "tcp_retransmit_skb sk=%di";
|
||||
create_kprobe $kname_tlp, "tcp_send_loss_probe sk=%di" if $tlp;
|
||||
if ($stacks) {
|
||||
writeto "1", "options/stacktrace" or print STDERR "WARNING: " .
|
||||
"unable to enable stacktraces.";
|
||||
}
|
||||
unless (writeto "1", "events/kprobes/$kname/enable") {
|
||||
appendto "-:$kname", "kprobe_events";
|
||||
ldie "ERROR: enabling kprobe.";
|
||||
}
|
||||
enable_kprobe $kname;
|
||||
enable_kprobe $kname_tlp if $tlp;
|
||||
map_tcp_states();
|
||||
printf "%-8s %-6s %-20s -- %-20s %s\n", "TIME", "PID",
|
||||
"LADDR:LPORT", "RADDR:RPORT", "STATE";
|
||||
printf "%-8s %-6s %-20s -- %-20s %-12s %s\n", "TIME", "PID",
|
||||
"LADDR:LPORT", "RADDR:RPORT", "STATE", "TLP";
|
||||
|
||||
#
|
||||
# Read and print event data. This loop waits one second then reads the buffered
|
||||
@@ -225,8 +246,8 @@ while (1) {
|
||||
}
|
||||
|
||||
my $now = strftime "%H:%M:%S", localtime;
|
||||
printf "%-8s %-6s %-20s R> %-20s %s\n", $now, $pid,
|
||||
"$laddr:$lport", "$raddr:$rport", $state;
|
||||
printf "%-8s %-6s %-20s R> %-20s %-12s %s\n", $now, $pid,
|
||||
"$laddr:$lport", "$raddr:$rport", $state, $rest =~ /$kname_tlp/ ? "Y" : "N";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,9 +261,8 @@ sub cleanup {
|
||||
writeto "0", "options/stacktrace" or print STDERR "WARNING: " .
|
||||
"unable to disable stacktraces.";
|
||||
}
|
||||
writeto "0", "events/kprobes/$kname/enable"
|
||||
or ldie "ERROR: disabling kprobe";
|
||||
appendto "-:$kname", "kprobe_events";
|
||||
remove_kprobe $kname;
|
||||
remove_kprobe $kname_tlp if $tlp;
|
||||
writeto "", "trace";
|
||||
unlink $flock;
|
||||
exit;
|
||||
|
||||
Reference in New Issue
Block a user