From owner-freebsd-drivers@freebsd.org Wed Aug 19 02:31:25 2015 Return-Path: Delivered-To: freebsd-drivers@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 C83BF9BD5CC for ; Wed, 19 Aug 2015 02:31:25 +0000 (UTC) (envelope-from john@araratriver.co) Received: from bigwig.baldwin.cx (bigwig.baldwin.cx [IPv6:2001:470:1f11:75::1]) (using TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A4B4B123B; Wed, 19 Aug 2015 02:31:25 +0000 (UTC) (envelope-from john@araratriver.co) Received: from ralph.baldwin.cx (75-48-78-19.lightspeed.cncrca.sbcglobal.net [75.48.78.19]) by bigwig.baldwin.cx (Postfix) with ESMTPSA id E8474B91E; Tue, 18 Aug 2015 22:31:23 -0400 (EDT) From: John Baldwin To: freebsd-drivers@freebsd.org Cc: Leonardo Fogel , 'Konstantin Belousov' Subject: Re: Race conditions Date: Tue, 18 Aug 2015 19:30:48 -0700 Message-ID: <10064388.a9lbzVPoX7@ralph.baldwin.cx> Organization: Ararat River Consulting, LLC User-Agent: KMail/4.14.3 (FreeBSD/10.2-PRERELEASE; KDE/4.14.3; amd64; ; ) In-Reply-To: <1439923294.98963.YahooMailBasic@web120801.mail.ne1.yahoo.com> References: <1439923294.98963.YahooMailBasic@web120801.mail.ne1.yahoo.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.2.7 (bigwig.baldwin.cx); Tue, 18 Aug 2015 22:31:24 -0400 (EDT) X-BeenThere: freebsd-drivers@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Writing device drivers for FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 19 Aug 2015 02:31:25 -0000 On Tuesday, August 18, 2015 11:41:34 AM Leonardo Fogel wrote: > Hi. > The following code is an exerpt from the FreeBSD Architecture Handbook, chapter 11.1.1. Sample Driver Source. I've included labels i1, i2, i3. > > int > mypci_open(struct cdev *dev, int oflags, int devtype, struct thread *td) > { > struct mypci_softc *sc; > > /* Look up our softc. */ > i1: sc = dev->si_drv1; > device_printf(sc->my_dev, "Opened successfully.\n"); > return (0); > } > > static int > mypci_attach(device_t dev) > { > struct mypci_softc *sc; > ... > i2: sc->my_cdev = make_dev(&mypci_cdevsw, device_get_unit(dev), > UID_ROOT, GID_WHEEL, 0600, "mypci%u", device_get_unit(dev)); > i3: sc->my_cdev->si_drv1 = sc; > printf("Mypci device loaded.\n"); > return (0); > } > > > As I understand it, as soon as instruction at label i2 completes, there is a rare possibility that another thread opens the device file and executes the instruction at i1, before the instruction at i3 is executed. Is it correct? How could one fix it? It is a race, yes. I know there is a MAKEDEV_REF flag that can be passed to make_dev_p() and make_dev_credf() that can hold a reference on the returned cdev (so it can't be immediately deleted), but I don't know that that helps close the race you reference. I think I would probably prefer we add some sort of wrapper for make_dev that accepts the si_drv1 value (and possibly other values) as an argument to close this. I'm cc'ing kib@ to see if he has any suggestions or better ideas. -- John Baldwin