svn commit: r192329 - user/kmacy/releng_7_2_fcs/sys/netinet

Kip Macy kmacy at FreeBSD.org
Mon May 18 19:08:01 UTC 2009


Author: kmacy
Date: Mon May 18 19:07:58 2009
New Revision: 192329
URL: http://svn.freebsd.org/changeset/base/192329

Log:
  use per-cpu callouts for tcp timers

Modified:
  user/kmacy/releng_7_2_fcs/sys/netinet/tcp_timer.c

Modified: user/kmacy/releng_7_2_fcs/sys/netinet/tcp_timer.c
==============================================================================
--- user/kmacy/releng_7_2_fcs/sys/netinet/tcp_timer.c	Mon May 18 19:02:55 2009	(r192328)
+++ user/kmacy/releng_7_2_fcs/sys/netinet/tcp_timer.c	Mon May 18 19:07:58 2009	(r192329)
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/mbuf.h>
 #include <sys/mutex.h>
 #include <sys/protosw.h>
+#include <sys/smp.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/sysctl.h>
@@ -119,6 +120,8 @@ int	tcp_maxpersistidle;
 	/* max idle time in persist */
 int	tcp_maxidle;
 
+#define	INP_CPU(inp)	min(curcpu, ((inp)->inp_flowid % mp_maxid))
+
 /*
  * Tcp protocol timeout routine called every 500 ms.
  * Updates timestamps used for TCP
@@ -256,8 +259,8 @@ tcp_timer_2msl(void *xtp)
 	} else {
 		if (tp->t_state != TCPS_TIME_WAIT &&
 		   (ticks - tp->t_rcvtime) <= tcp_maxidle)
-		       callout_reset(&tp->t_timers->tt_2msl, tcp_keepintvl,
-				     tcp_timer_2msl, tp);
+		       callout_reset_on(&tp->t_timers->tt_2msl, tcp_keepintvl,
+			   tcp_timer_2msl, tp, INP_CPU(inp));
 	       else
 		       tp = tcp_close(tp);
        }
@@ -341,9 +344,9 @@ tcp_timer_keep(void *xtp)
 				    tp->rcv_nxt, tp->snd_una - 1, 0);
 			free(t_template, M_TEMP);
 		}
-		callout_reset(&tp->t_timers->tt_keep, tcp_keepintvl, tcp_timer_keep, tp);
+		callout_reset_on(&tp->t_timers->tt_keep, tcp_keepintvl, tcp_timer_keep, tp, INP_CPU(inp));
 	} else
-		callout_reset(&tp->t_timers->tt_keep, tcp_keepidle, tcp_timer_keep, tp);
+		callout_reset_on(&tp->t_timers->tt_keep, tcp_keepidle, tcp_timer_keep, tp, INP_CPU(inp));
 
 #ifdef TCPDEBUG
 	if (inp->inp_socket->so_options & SO_DEBUG)
@@ -448,15 +451,13 @@ tcp_timer_rexmt(void * xtp)
 	CURVNET_SET(tp->t_vnet);
 	INIT_VNET_INET(tp->t_vnet);
 	int rexmt;
-	int headlocked;
 	struct inpcb *inp;
 #ifdef TCPDEBUG
 	int ostate;
 
 	ostate = tp->t_state;
 #endif
-	INP_INFO_WLOCK(&V_tcbinfo);
-	headlocked = 1;
+	INP_INFO_RLOCK(&V_tcbinfo);
 	inp = tp->t_inpcb;
 	/*
 	 * XXXRW: While this assert is in fact correct, bugs in the tcpcb
@@ -467,7 +468,7 @@ tcp_timer_rexmt(void * xtp)
 	 */
 	if (inp == NULL) {
 		tcp_timer_race++;
-		INP_INFO_WUNLOCK(&V_tcbinfo);
+		INP_INFO_RUNLOCK(&V_tcbinfo);
 		CURVNET_RESTORE();
 		return;
 	}
@@ -475,7 +476,7 @@ tcp_timer_rexmt(void * xtp)
 	if ((inp->inp_flags & INP_DROPPED) || callout_pending(&tp->t_timers->tt_rexmt)
 	    || !callout_active(&tp->t_timers->tt_rexmt)) {
 		INP_WUNLOCK(inp);
-		INP_INFO_WUNLOCK(&V_tcbinfo);
+		INP_INFO_RUNLOCK(&V_tcbinfo);
 		CURVNET_RESTORE();
 		return;
 	}
@@ -489,12 +490,22 @@ tcp_timer_rexmt(void * xtp)
 	if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) {
 		tp->t_rxtshift = TCP_MAXRXTSHIFT;
 		V_tcpstat.tcps_timeoutdrop++;
+		in_pcbref(inp);
+		INP_INFO_RUNLOCK(&V_tcbinfo);
+		INP_WUNLOCK(inp);
+		INP_INFO_WLOCK(&V_tcbinfo);
+		INP_WLOCK(inp);
+		if (in_pcbrele(inp)) {
+			INP_INFO_WUNLOCK(&V_tcbinfo);
+			CURVNET_RESTORE();
+			return;
+		}
 		tp = tcp_drop(tp, tp->t_softerror ?
 			      tp->t_softerror : ETIMEDOUT);
+		INP_INFO_WUNLOCK(&V_tcbinfo);
 		goto out;
 	}
-	INP_INFO_WUNLOCK(&V_tcbinfo);
-	headlocked = 0;
+	INP_INFO_RUNLOCK(&V_tcbinfo);
 	if (tp->t_rxtshift == 1) {
 		/*
 		 * first retransmit; record ssthresh and cwnd so they can
@@ -599,8 +610,6 @@ out:
 #endif
 	if (tp != NULL)
 		INP_WUNLOCK(inp);
-	if (headlocked)
-		INP_INFO_WUNLOCK(&V_tcbinfo);
 	CURVNET_RESTORE();
 }
 
@@ -609,6 +618,8 @@ tcp_timer_activate(struct tcpcb *tp, int
 {
 	struct callout *t_callout;
 	void *f_callout;
+	struct inpcb *inp = tp->t_inpcb;
+	int cpu = INP_CPU(inp);
 
 	switch (timer_type) {
 		case TT_DELACK:
@@ -637,7 +648,7 @@ tcp_timer_activate(struct tcpcb *tp, int
 	if (delta == 0) {
 		callout_stop(t_callout);
 	} else {
-		callout_reset(t_callout, delta, f_callout, tp);
+		callout_reset_on(t_callout, delta, f_callout, tp, cpu);
 	}
 }
 


More information about the svn-src-user mailing list