svn commit: r195655 - head/sys/netinet

Lawrence Stewart lstewart at FreeBSD.org
Mon Jul 13 11:59:39 UTC 2009


Author: lstewart
Date: Mon Jul 13 11:59:38 2009
New Revision: 195655
URL: http://svn.freebsd.org/changeset/base/195655

Log:
  Fix a race in the manipulation of the V_tcp_sack_globalholes global variable,
  which is currently not protected by any type of lock. When triggered, the bug
  would sometimes cause a panic when the TCP activity to an affected machine
  eventually slowed during a lull. The panic only occurs if INVARIANTS is compiled
  into the kernel, and has laid dormant for some time as a result of INVARIANTS
  being off by default except in FreeBSD-CURRENT.
  
  Switch to atomic operations in the locations where the variable is changed.
  Reads have not been updated to be protected by atomics, so there is a
  possibility of accounting errors in any given calculation where the variable is
  read. This is considered unlikely to occur in the wild, and will not cause
  serious harm on rare occasions where it does.
  
  Thanks to Robert Watson for debugging help.
  
  Reported by:	Kamigishi Rei <spambox at haruhiism dot net>
  Tested by:	Kamigishi Rei <spambox at haruhiism dot net>
  Reviewed by:	silby
  Approved by:	re (rwatson), kensmith (mentor temporarily unavailable)

Modified:
  head/sys/netinet/tcp_sack.c

Modified: head/sys/netinet/tcp_sack.c
==============================================================================
--- head/sys/netinet/tcp_sack.c	Mon Jul 13 11:51:02 2009	(r195654)
+++ head/sys/netinet/tcp_sack.c	Mon Jul 13 11:59:38 2009	(r195655)
@@ -273,7 +273,7 @@ tcp_sackhole_alloc(struct tcpcb *tp, tcp
 	hole->rxmit = start;
 
 	tp->snd_numholes++;
-	V_tcp_sack_globalholes++;
+	atomic_add_int(&V_tcp_sack_globalholes, 1);
 
 	return hole;
 }
@@ -289,7 +289,7 @@ tcp_sackhole_free(struct tcpcb *tp, stru
 	uma_zfree(V_sack_hole_zone, hole);
 
 	tp->snd_numholes--;
-	V_tcp_sack_globalholes--;
+	atomic_subtract_int(&V_tcp_sack_globalholes, 1);
 
 	KASSERT(tp->snd_numholes >= 0, ("tp->snd_numholes >= 0"));
 	KASSERT(V_tcp_sack_globalholes >= 0, ("tcp_sack_globalholes >= 0"));


More information about the svn-src-all mailing list