Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 13 Jul 2009 11:59:38 +0000 (UTC)
From:      Lawrence Stewart <lstewart@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r195655 - head/sys/netinet
Message-ID:  <200907131159.n6DBxcF8024363@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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"));



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907131159.n6DBxcF8024363>