Date: Sun, 01 Jul 2012 18:26:20 +0300 From: Mikolaj Golub <trociny@freebsd.org> To: freebsd-net@FreeBSD.org Cc: Robert Watson <rwatson@FreeBSD.org> Subject: netstat(1): negative tcp timer counters Message-ID: <8662a7pko3.fsf@kopusha.home.net>
index | next in thread | raw e-mail
[-- Attachment #1 --]
I have noticed that `netstat -x' shows negative values for keep timer. In my
case this is for connections in CLOSE state.
Reviewing the timer code it looks like there is an issue in tcp_timer_*
functions, when inp is checked for INP_DROPPED. If the flag is set the
function returns and callout_deactivate() is never called. Adding some prints
I made sure that observed negative counters in my case were due to this check.
The attached patch (check for INP_DROPPED after callout_deactivate) fixes the
issue for me. I would like to commit it if there are no objections.
--
Mikolaj Golub
[-- Attachment #2 --]
Index: sys/netinet/tcp_timer.c
===================================================================
--- sys/netinet/tcp_timer.c (revision 237918)
+++ sys/netinet/tcp_timer.c (working copy)
@@ -183,13 +183,18 @@ tcp_timer_delack(void *xtp)
return;
}
INP_WLOCK(inp);
- if ((inp->inp_flags & INP_DROPPED) || callout_pending(&tp->t_timers->tt_delack)
- || !callout_active(&tp->t_timers->tt_delack)) {
+ if (callout_pending(&tp->t_timers->tt_delack) ||
+ !callout_active(&tp->t_timers->tt_delack)) {
INP_WUNLOCK(inp);
CURVNET_RESTORE();
return;
}
callout_deactivate(&tp->t_timers->tt_delack);
+ if ((inp->inp_flags & INP_DROPPED) != 0) {
+ INP_WUNLOCK(inp);
+ CURVNET_RESTORE();
+ return;
+ }
tp->t_flags |= TF_ACKNOW;
TCPSTAT_INC(tcps_delack);
@@ -229,7 +234,7 @@ tcp_timer_2msl(void *xtp)
}
INP_WLOCK(inp);
tcp_free_sackholes(tp);
- if ((inp->inp_flags & INP_DROPPED) || callout_pending(&tp->t_timers->tt_2msl) ||
+ if (callout_pending(&tp->t_timers->tt_2msl) ||
!callout_active(&tp->t_timers->tt_2msl)) {
INP_WUNLOCK(tp->t_inpcb);
INP_INFO_WUNLOCK(&V_tcbinfo);
@@ -237,6 +242,12 @@ tcp_timer_2msl(void *xtp)
return;
}
callout_deactivate(&tp->t_timers->tt_2msl);
+ if ((inp->inp_flags & INP_DROPPED) != 0) {
+ INP_WUNLOCK(inp);
+ INP_INFO_WUNLOCK(&V_tcbinfo);
+ CURVNET_RESTORE();
+ return;
+ }
/*
* 2 MSL timeout in shutdown went off. If we're closed but
* still waiting for peer to close and connection has been idle
@@ -300,14 +311,20 @@ tcp_timer_keep(void *xtp)
return;
}
INP_WLOCK(inp);
- if ((inp->inp_flags & INP_DROPPED) || callout_pending(&tp->t_timers->tt_keep)
- || !callout_active(&tp->t_timers->tt_keep)) {
+ if (callout_pending(&tp->t_timers->tt_keep) ||
+ !callout_active(&tp->t_timers->tt_keep)) {
INP_WUNLOCK(inp);
INP_INFO_WUNLOCK(&V_tcbinfo);
CURVNET_RESTORE();
return;
}
callout_deactivate(&tp->t_timers->tt_keep);
+ if ((inp->inp_flags & INP_DROPPED) != 0) {
+ INP_WUNLOCK(inp);
+ INP_INFO_WUNLOCK(&V_tcbinfo);
+ CURVNET_RESTORE();
+ return;
+ }
/*
* Keep-alive timer went off; send something
* or drop connection if idle for too long.
@@ -397,14 +414,20 @@ tcp_timer_persist(void *xtp)
return;
}
INP_WLOCK(inp);
- if ((inp->inp_flags & INP_DROPPED) || callout_pending(&tp->t_timers->tt_persist)
- || !callout_active(&tp->t_timers->tt_persist)) {
+ if (callout_pending(&tp->t_timers->tt_persist) ||
+ !callout_active(&tp->t_timers->tt_persist)) {
INP_WUNLOCK(inp);
INP_INFO_WUNLOCK(&V_tcbinfo);
CURVNET_RESTORE();
return;
}
callout_deactivate(&tp->t_timers->tt_persist);
+ if ((inp->inp_flags & INP_DROPPED) != 0) {
+ INP_WUNLOCK(inp);
+ INP_INFO_WUNLOCK(&V_tcbinfo);
+ CURVNET_RESTORE();
+ return;
+ }
/*
* Persistance timer into zero window.
* Force a byte to be output, if possible.
@@ -469,14 +492,20 @@ tcp_timer_rexmt(void * xtp)
return;
}
INP_WLOCK(inp);
- if ((inp->inp_flags & INP_DROPPED) || callout_pending(&tp->t_timers->tt_rexmt)
- || !callout_active(&tp->t_timers->tt_rexmt)) {
+ if (callout_pending(&tp->t_timers->tt_rexmt) ||
+ !callout_active(&tp->t_timers->tt_rexmt)) {
INP_WUNLOCK(inp);
INP_INFO_RUNLOCK(&V_tcbinfo);
CURVNET_RESTORE();
return;
}
callout_deactivate(&tp->t_timers->tt_rexmt);
+ if ((inp->inp_flags & INP_DROPPED) != 0) {
+ INP_WUNLOCK(inp);
+ INP_INFO_RUNLOCK(&V_tcbinfo);
+ CURVNET_RESTORE();
+ return;
+ }
tcp_free_sackholes(tp);
/*
* Retransmission timer went off. Message has not
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?8662a7pko3.fsf>
