next up previous
Next: Using strace Up: FUSD: A Linux Framework Previous: Performance of User-Space Devices

Subsections

FUSD Implementation Notes

In this section, we describe some of the details of how FUSD is implemented. It's not necessary to understand these details in order to use FUSD. However, these notes can be useful for people who are trying to understand the FUSD framework itself--hackers, debuggers, or the generally curious.


The situation with poll_diff

In-kernel device drivers support select by implementing a callback called poll. This driver's callback is supposed to do two things. First, it should return the current state of a file descriptor--a combination of being readable, writable, or having exceptions. Second, it should provide a pointer to one of the driver's internal wait queues that will be awakened whenever the state changes. The poll call itself should never block--it should just instantaneously report what the current state is.

FUSD's implementation of selectable devices is different, but attempts to maintain three properties that we thought to be most important from the point of view of a client using select. Specifically:

  1. The select(2) call itself should never become blocked. For example, if one file descriptor in its set isn't readable, that shouldn't prevent it from reporting other file descriptors that are.
  2. If select(2) indicates a file descriptor is readable (or writable), a read (or write) on that file descriptor shouldn't block.
  3. Clients should be allowed to seamlessly select on any set of file descriptors, even if that set contains a mix of both FUSD and non-FUSD devices.

The FUSD kernel module keeps a cache of the driver's most recent answer for each file descriptor, initially assumed to be 0. When the kernel module's internal poll callback is activated, it:

  1. Dispatches a non-blocking poll_diff to the associated user-space driver, asking for a cache update--if and only if there isn't already an outstanding poll diff request out that has the same value.
  2. Immediately returns the cached value to the kernel

In addition, the cached value's readable bit is cleared on every read; the writable bit is cleared on every write. This is necessary to prevent old poll state--which says ``device is readable''--from being returned out of the cache when it might be invalid. FUSD assumes that any read to a device can make it potentially unreadable. This mechanism is what causes an updated poll diff to be sent to a client before the previous one has been returned.

(this section isn't finished yet; fancy time diagrams coming someday)

Restartable System Calls

No time to write this section yet...


next up previous
Next: Using strace Up: FUSD: A Linux Framework Previous: Performance of User-Space Devices