svn commit: r309372 - head/sys/sys

Ryan Stone rstone at FreeBSD.org
Thu Dec 1 21:08:43 UTC 2016


Author: rstone
Date: Thu Dec  1 21:08:42 2016
New Revision: 309372
URL: https://svnweb.freebsd.org/changeset/base/309372

Log:
  Fix a false positive in a buf_ring assert
  
  buf_ring contains an assert that checks whether an item being
  enqueued already exists on the ring.  There is a subtle bug in
  this assert.  An item can be returned by a peek() function and
  freed, and then the consumer thread can be preempted before
  calling advance().  If this happens the item appears to still be
  on the queue, but another thread may allocate the item from the
  free pool and wind up trying to enqueue it again, causing the
  assert to trigger incorrectly.
  
  Fix this by skipping the head of the consumer's portion of the
  ring, as this index is what will be returned by peek().
  
  Sponsored by:	Dell EMC Isilon
  MFC After:	1 week
  Differential Revision:	https://reviews.freebsd.org/D8685
  Reviewed by:	hselasky

Modified:
  head/sys/sys/buf_ring.h

Modified: head/sys/sys/buf_ring.h
==============================================================================
--- head/sys/sys/buf_ring.h	Thu Dec  1 20:36:48 2016	(r309371)
+++ head/sys/sys/buf_ring.h	Thu Dec  1 21:08:42 2016	(r309372)
@@ -67,11 +67,13 @@ buf_ring_enqueue(struct buf_ring *br, vo
 	uint32_t prod_head, prod_next, cons_tail;
 #ifdef DEBUG_BUFRING
 	int i;
-	for (i = br->br_cons_head; i != br->br_prod_head;
-	     i = ((i + 1) & br->br_cons_mask))
-		if(br->br_ring[i] == buf)
-			panic("buf=%p already enqueue at %d prod=%d cons=%d",
-			    buf, i, br->br_prod_tail, br->br_cons_tail);
+	if (br->br_cons_head != br->br_prod_head) {
+		for (i = (br->br_cons_head + 1) & br->br_cons_mask; i != br->br_prod_head;
+		    i = ((i + 1) & br->br_cons_mask))
+			if(br->br_ring[i] == buf)
+				panic("buf=%p already enqueue at %d prod=%d cons=%d",
+				    buf, i, br->br_prod_tail, br->br_cons_tail);
+	}
 #endif	
 	critical_enter();
 	do {


More information about the svn-src-head mailing list