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



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@xxxxxx>
WWW: http://g-rave.nl/

Attachment: pgp0QULYpyg8d.pgp
Description: PGP signature



Relevant Pages

  • Re: Kernel mode programming in VC++
    ... There is no "easy solution" of the kind you are hoping ... code to open the device driver. ... I have an asm routine which uses privileged instructions like in, out, ... I can't execute the same under User ...
    (microsoft.public.vc.mfc)
  • Re: [Linux-ATM-General] Kernel 2.6.10 and 2.4.29 Oops fore200e (fwd)
    ... to the fact that device driver send routines ... At any rate someone who has access to the golden code ... > its calling a routine that might sleep while in the transmit routine. ... send the line "unsubscribe linux-kernel" in ...
    (Linux-Kernel)