vgone() calling VOP_CLOSE() -> blocked threads?

Ed Schouten ed at 80386.nl
Sat Mar 15 12:40:10 UTC 2008


Hello everyone,

The last couple of days I'm seeing some strange things in my mpsafetty
branch related to terminal revocation.

In my current TTY design, I hold a count (t_ldisccnt) of the amount of
threads that are sleeping in the line discipline. I need to store such a
count, because it's not possible to change line disciplines while some
threads are still blocked inside the discipline. This means that when
d_close() is called on a TTY, t_ldisccnt should always be 0. There
cannot be any threads stuck inside the line discipline when there aren't
any descriptors referencing it.

Unfortunately, this isn't entirely true with the current VFS/devfs
design. When vgone() is called, a VOP_CLOSE() is performed , which means
there could be a dozen threads still stuck inside a device driver, but
the close routine is already called to clean up stuff. There are a
*real* lot of drivers that blindly clean up their stuff in the d_close()
routine, expecting that the device is completely unused. This can
easily be demonstrated by revoking a bpf device, while running tcpdump.

To be honest, I'm not completely sure how to solve this issue, though I
know it should at least do something similar to this:

- The device driver should have a seperate routine (d_revoke) to wake
  up any blocked threads, to make sure they leave the device driver
  properly.

- Maybe vgonel() shouldn't call VOP_CLOSE(). It should probably move the
  vnode into deadfs, with the exception of the close() routine. Maybe
  it's better to add a new function to do this, vrevoke().

This means that when a revoke() call is performed, all blocked threads
are woken up, will leave the driver, to find out their terminal has been
revoked. Further system calls will fail, because the vnode is in deadfs,
but when the processes close the descriptor, the device driver can still
clean up everything.

In theory these changes would also make it easier for other filesystems
to support the revoke() call. A generic vop_revoke could just call
vrevoke(), which means the current system calls aren't interrupted, but
calls later on will fail. This will be sufficient for most filesystems.

I'm not a VFS guru, so it will probably take me some time and will
probably dogfood some of my filesystems. I could probably need some
help. ;-)

-- 
 Ed Schouten <ed at fxq.nl>
 WWW: http://g-rave.nl/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-arch/attachments/20080315/c3c4aa9d/attachment.pgp


More information about the freebsd-arch mailing list