From owner-svn-src-all@FreeBSD.ORG Fri Oct 10 17:49:47 2008 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 810171065687; Fri, 10 Oct 2008 17:49:47 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 7411B8FC12; Fri, 10 Oct 2008 17:49:47 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id m9AHnlIM097238; Fri, 10 Oct 2008 17:49:47 GMT (envelope-from imp@svn.freebsd.org) Received: (from imp@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id m9AHnlCh097237; Fri, 10 Oct 2008 17:49:47 GMT (envelope-from imp@svn.freebsd.org) Message-Id: <200810101749.m9AHnlCh097237@svn.freebsd.org> From: Warner Losh Date: Fri, 10 Oct 2008 17:49:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r183750 - head/sys/kern X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 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: Fri, 10 Oct 2008 17:49:47 -0000 Author: imp Date: Fri Oct 10 17:49:47 2008 New Revision: 183750 URL: http://svn.freebsd.org/changeset/base/183750 Log: Close, but not eliminate, a race condition. It is one that properly designed drivers would never hit, but was exposed in diving into another problem... When expanding the devclass array, free the old memory after updating the pointer to the new memory. For the following single race case, this helps: allocate new memory copy to new memory free old memory read pointer to freed memory update pointer to new memory Now we do allocate new memory copy to new memory update pointer to new memory free old memory Which closes this problem, but doesn't even begin to address the multicpu races, which all should be covered by Giant at the moment, but likely aren't completely. Note: reviewers were ok with this fix, but suggested the use case wasn't one we wanted to encourage. Reviewed by: jhb, scottl. Modified: head/sys/kern/subr_bus.c Modified: head/sys/kern/subr_bus.c ============================================================================== --- head/sys/kern/subr_bus.c Fri Oct 10 17:48:39 2008 (r183749) +++ head/sys/kern/subr_bus.c Fri Oct 10 17:49:47 2008 (r183750) @@ -1344,20 +1344,22 @@ devclass_alloc_unit(devclass_t dc, int * * this one. */ if (unit >= dc->maxunit) { - device_t *newlist; + device_t *newlist, *oldlist; int newsize; + oldlist = dc->devices; newsize = roundup((unit + 1), MINALLOCSIZE / sizeof(device_t)); newlist = malloc(sizeof(device_t) * newsize, M_BUS, M_NOWAIT); if (!newlist) return (ENOMEM); - bcopy(dc->devices, newlist, sizeof(device_t) * dc->maxunit); + if (oldlist != NULL) + bcopy(oldlist, newlist, sizeof(device_t) * dc->maxunit); bzero(newlist + dc->maxunit, sizeof(device_t) * (newsize - dc->maxunit)); - if (dc->devices) - free(dc->devices, M_BUS); dc->devices = newlist; dc->maxunit = newsize; + if (oldlist != NULL) + free(oldlist, M_BUS); } PDEBUG(("now: unit %d in devclass %s", unit, DEVCLANAME(dc)));