From owner-svn-src-all@FreeBSD.ORG Mon May 9 07:37:48 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 33B35106566B; Mon, 9 May 2011 07:37:48 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 19DE48FC12; Mon, 9 May 2011 07:37:48 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p497bltH081939; Mon, 9 May 2011 07:37:47 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p497blVE081937; Mon, 9 May 2011 07:37:47 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201105090737.p497blVE081937@svn.freebsd.org> From: Alexander Motin Date: Mon, 9 May 2011 07:37:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r221690 - head/sys/netinet X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 May 2011 07:37:48 -0000 Author: mav Date: Mon May 9 07:37:47 2011 New Revision: 221690 URL: http://svn.freebsd.org/changeset/base/221690 Log: Refactor TCP ISN increment logic. Instead of firing callout at 100Hz to keep constant ISN growth rate, do the same directly inside tcp_new_isn(), taking into account how much time (ticks) passed since the last call. On my test systems this decreases idle interrupt rate from 140Hz to 70Hz. Modified: head/sys/netinet/tcp_subr.c Modified: head/sys/netinet/tcp_subr.c ============================================================================== --- head/sys/netinet/tcp_subr.c Mon May 9 07:15:15 2011 (r221689) +++ head/sys/netinet/tcp_subr.c Mon May 9 07:37:47 2011 (r221690) @@ -224,7 +224,6 @@ VNET_DEFINE(uma_zone_t, sack_hole_zone); VNET_DEFINE(struct hhook_head *, tcp_hhh[HHOOK_TCP_LAST+1]); static struct inpcb *tcp_notify(struct inpcb *, int); -static void tcp_isn_tick(void *); static char * tcp_log_addr(struct in_conninfo *inc, struct tcphdr *th, void *ip4hdr, const void *ip6hdr); @@ -255,7 +254,6 @@ static VNET_DEFINE(uma_zone_t, tcpcb_zon #define V_tcpcb_zone VNET(tcpcb_zone) MALLOC_DEFINE(M_TCPLOG, "tcplog", "TCP address and flags print buffers"); -struct callout isn_callout; static struct mtx isn_mtx; #define ISN_LOCK_INIT() mtx_init(&isn_mtx, "isn_mtx", NULL, MTX_DEF) @@ -358,8 +356,6 @@ tcp_init(void) #undef TCP_MINPROTOHDR ISN_LOCK_INIT(); - callout_init(&isn_callout, CALLOUT_MPSAFE); - callout_reset(&isn_callout, hz/100, tcp_isn_tick, NULL); EVENTHANDLER_REGISTER(shutdown_pre_sync, tcp_fini, NULL, SHUTDOWN_PRI_DEFAULT); EVENTHANDLER_REGISTER(maxsockets_change, tcp_zone_change, NULL, @@ -385,7 +381,6 @@ void tcp_fini(void *xtp) { - callout_stop(&isn_callout); } /* @@ -1571,11 +1566,13 @@ tcp6_ctlinput(int cmd, struct sockaddr * #define ISN_RANDOM_INCREMENT (4096 - 1) static VNET_DEFINE(u_char, isn_secret[32]); +static VNET_DEFINE(int, isn_last); static VNET_DEFINE(int, isn_last_reseed); static VNET_DEFINE(u_int32_t, isn_offset); static VNET_DEFINE(u_int32_t, isn_offset_old); #define V_isn_secret VNET(isn_secret) +#define V_isn_last VNET(isn_last) #define V_isn_last_reseed VNET(isn_last_reseed) #define V_isn_offset VNET(isn_offset) #define V_isn_offset_old VNET(isn_offset_old) @@ -1586,6 +1583,7 @@ tcp_new_isn(struct tcpcb *tp) MD5_CTX isn_ctx; u_int32_t md5_buffer[4]; tcp_seq new_isn; + u_int32_t projected_offset; INP_WLOCK_ASSERT(tp->t_inpcb); @@ -1621,38 +1619,17 @@ tcp_new_isn(struct tcpcb *tp) new_isn = (tcp_seq) md5_buffer[0]; V_isn_offset += ISN_STATIC_INCREMENT + (arc4random() & ISN_RANDOM_INCREMENT); - new_isn += V_isn_offset; - ISN_UNLOCK(); - return (new_isn); -} - -/* - * Increment the offset to the next ISN_BYTES_PER_SECOND / 100 boundary - * to keep time flowing at a relatively constant rate. If the random - * increments have already pushed us past the projected offset, do nothing. - */ -static void -tcp_isn_tick(void *xtp) -{ - VNET_ITERATOR_DECL(vnet_iter); - u_int32_t projected_offset; - - VNET_LIST_RLOCK_NOSLEEP(); - ISN_LOCK(); - VNET_FOREACH(vnet_iter) { - CURVNET_SET(vnet_iter); /* XXX appease INVARIANTS */ - projected_offset = - V_isn_offset_old + ISN_BYTES_PER_SECOND / 100; - + if (ticks != V_isn_last) { + projected_offset = V_isn_offset_old + + ISN_BYTES_PER_SECOND / hz * (ticks - V_isn_last); if (SEQ_GT(projected_offset, V_isn_offset)) V_isn_offset = projected_offset; - V_isn_offset_old = V_isn_offset; - CURVNET_RESTORE(); + V_isn_last = ticks; } + new_isn += V_isn_offset; ISN_UNLOCK(); - VNET_LIST_RUNLOCK_NOSLEEP(); - callout_reset(&isn_callout, hz/100, tcp_isn_tick, NULL); + return (new_isn); } /*