Re: vgone() calling VOP_CLOSE() -> blocked threads?
- From: Bruce Evans <brde@xxxxxxxxxxxxxxx>
- Date: Thu, 20 Mar 2008 02:23:24 +1100 (EST)
On Mon, 17 Mar 2008, Ed Schouten wrote:
* Bruce Evans <brde@xxxxxxxxxxxxxxx> 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
_______________________________________________
freebsd-arch@xxxxxxxxxxx mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-arch
To unsubscribe, send any mail to "freebsd-arch-unsubscribe@xxxxxxxxxxx"
- References:
- vgone() calling VOP_CLOSE() -> blocked threads?
- From: Ed Schouten
- Re: vgone() calling VOP_CLOSE() -> blocked threads?
- From: Bruce Evans
- Re: vgone() calling VOP_CLOSE() -> blocked threads?
- From: Ed Schouten
- vgone() calling VOP_CLOSE() -> blocked threads?
- Prev by Date: Re: Power-Mgt
- Next by Date: Re: vgone() calling VOP_CLOSE() -> blocked threads?
- Previous by thread: Re: vgone() calling VOP_CLOSE() -> blocked threads?
- Next by thread: Re: vgone() calling VOP_CLOSE() -> blocked threads?
- Index(es):
Relevant Pages
|
|