From owner-freebsd-arch@FreeBSD.ORG Wed Mar 19 15:23:32 2008 Return-Path: Delivered-To: arch@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 82F0F106564A for ; Wed, 19 Mar 2008 15:23:32 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from mail03.syd.optusnet.com.au (mail03.syd.optusnet.com.au [211.29.132.184]) by mx1.freebsd.org (Postfix) with ESMTP id 2216D8FC21 for ; Wed, 19 Mar 2008 15:23:31 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from besplex.bde.org (c220-239-252-11.carlnfd3.nsw.optusnet.com.au [220.239.252.11]) by mail03.syd.optusnet.com.au (8.13.1/8.13.1) with ESMTP id m2JFNPIp028750 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 20 Mar 2008 02:23:26 +1100 Date: Thu, 20 Mar 2008 02:23:24 +1100 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: Ed Schouten In-Reply-To: <20080317140039.GJ80576@hoeg.nl> Message-ID: <20080320014118.I10895@besplex.bde.org> References: <20080315124008.GF80576@hoeg.nl> <20080316015903.N39516@delplex.bde.org> <20080317140039.GJ80576@hoeg.nl> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: FreeBSD Arch Subject: Re: vgone() calling VOP_CLOSE() -> blocked threads? X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 19 Mar 2008 15:23:32 -0000 On Mon, 17 Mar 2008, Ed Schouten wrote: > * Bruce Evans wrote: >> ... >> I don't think it would work well to move everything except d_close to >> deadfs. > > It wasn't my idea to make revoke() wait for all threads to leave. It > should just inform the device driver that a revoke() has been performed, > to wake up sleeping threads, and change the vnode to prevent further > access. OK... Keep the move of d_close to deadfs too. The driver might need to call d_close to complete the effects of the revoke, but userland and vfs shouldn't. > The problem with the current implementation is that the device driver > cannot sanely determine whether a revoke() or a real close() is called. > Especially in my new TTY design, where a TTY could even be deallocated > when a close() is performed - when the device driver has abandoned the > TTY device - it would even destroy the TTY object that's being used by > the sleeping threads. > > This is why I chose an approach that would allow threads to just leave > the device driver as they normally would, which reduces complexity a > lot. Yes, kib's reply gives the rule that device close cannot destroy all device structs. It doesn't seem useful to destroy some structs earlier and then have to check all over not to access them while the synchronization is in progress. Some drivers (mainly rp?) get into trouble in another way, by calling dev_unbusy() in device close. Last-close doesn't work well enough for an unconditional dev_unbusy() to work there. vfs refcounts don't work well enough for a conditional dev_unbusy() (conditional on vfs counts alone) to work there either. Just checking si_threadcount in d_close() and providing d_purge() to call dev_unbusy() if d_close() missed doing it seems to be insufficient, since (I think) d_purge() and destroy_devl() designed to destroy the whole device but not to synchronize when last-close is performed out of order. > My question is: what approach would you take in such a situation? > Thanks for your input so far. Something like the old tty approach (a generation count) with more wakeups and more checking of the generation count. It should be possible to check a generation count more efficiently than si_*. For si_*, some device locking is needed. Locking for si_* seems to be undocumented, but seems to be simply mtx_lock() on the global devmtx mutex. A generation count in struct tty would be automatically locked by a tty mutex. Bruce