When GFS2's async lock completes on an inode, it reads the inode block. This
makes it rather slow:
In the lock_nolock case the read is done (sync) in the context of the lock
requesting function making it rather slow.
In the lock_dlm case, the read is done in the dlm's callback context (i.e. one
of the two threads in lock_dlm) and this blocks further lock callbacks.
By making the reads async, there is a good chance that they'll be merged, thus
resulting in more efficient I/O. In addition other lock completions will not be
blocked up against this I/O.
The way to fix this one is to add a set of list heads (possibly duplicated per
cpu to avoid locking problems) one of which is the "immediate" queue and the
others of which represent some delayed action. This is the classic way to
implement timers for example.
The idea is that we have a daemon which will run the immediate queue whenever it
has any entries on it and that the daemon will wake periodically to move the
other entries in the delayed lists up the queue.
This can take care of a number of other tasks too:
- reclaim (can make this delayed now - v. useful)
- a replacement for the scanning that we do for expired locks
- plus the async disk I/O required for this bug (need to make lists irq proof)
The latest glock patch has fixed this upstream.