From owner-svn-src-all@freebsd.org Thu Dec 1 21:08:43 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 6127EC61266; Thu, 1 Dec 2016 21:08:43 +0000 (UTC) (envelope-from rstone@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 309E313D1; Thu, 1 Dec 2016 21:08:43 +0000 (UTC) (envelope-from rstone@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id uB1L8gBs026076; Thu, 1 Dec 2016 21:08:42 GMT (envelope-from rstone@FreeBSD.org) Received: (from rstone@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uB1L8g19026075; Thu, 1 Dec 2016 21:08:42 GMT (envelope-from rstone@FreeBSD.org) Message-Id: <201612012108.uB1L8g19026075@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: rstone set sender to rstone@FreeBSD.org using -f From: Ryan Stone Date: Thu, 1 Dec 2016 21:08:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r309372 - head/sys/sys X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 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: Thu, 01 Dec 2016 21:08:43 -0000 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 {