From owner-freebsd-net@FreeBSD.ORG Sun Jul 1 15:26:26 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 34732106566B; Sun, 1 Jul 2012 15:26:26 +0000 (UTC) (envelope-from to.my.trociny@gmail.com) Received: from mail-lb0-f182.google.com (mail-lb0-f182.google.com [209.85.217.182]) by mx1.freebsd.org (Postfix) with ESMTP id 743188FC1A; Sun, 1 Jul 2012 15:26:25 +0000 (UTC) Received: by lbon10 with SMTP id n10so8159390lbo.13 for ; Sun, 01 Jul 2012 08:26:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:sender:date:message-id:user-agent:mime-version :content-type; bh=6inmDXgiQmwS0tOzGH82n5l1xZFH+370nEKd+GksHO8=; b=qhxiGoOjcBoEbDlTHg3i8SJozqny4rewS03X0Uno16ohukxMCGwQS/IwCEYtVEYnTj rkGJnFVIXEqKLYw1FoX38UD86xRedgUqdPNAobE2AJuCvEr6LgcpPuG67JckGI6zHSF5 LmLdcpdSOUYBcGSK24N9/0Ibpeiq7B0Wmgkgb9LqMJ3DgIifUwEfwVpL4ZwbU/giLXwc Oq4nA3yWMaxASTzJAluq+DxOC+3agewVaNxJSDjC5yVG1P+Te4680e3J5+rR5Zc7bI23 a2qkAKcXHgXyWNb6Q+nXIexGKazGvN0qA1vWHuwZpG3gTRgFpjdya7QflsN/znElFKt9 8vpQ== Received: by 10.112.27.226 with SMTP id w2mr4673510lbg.57.1341156384326; Sun, 01 Jul 2012 08:26:24 -0700 (PDT) Received: from localhost ([95.69.173.122]) by mx.google.com with ESMTPS id h9sm8555460lbi.9.2012.07.01.08.26.21 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 01 Jul 2012 08:26:23 -0700 (PDT) From: Mikolaj Golub To: freebsd-net@FreeBSD.org Sender: Mikolaj Golub Date: Sun, 01 Jul 2012 18:26:20 +0300 Message-ID: <8662a7pko3.fsf@kopusha.home.net> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.4 (berkeley-unix) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Cc: Robert Watson Subject: netstat(1): negative tcp timer counters X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 01 Jul 2012 15:26:26 -0000 --=-=-= Hi, 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 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=tcp_timer.c.INP_DROPPED.1.patch 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 --=-=-=--