kernel - Fix rare lockmgr() state transition (2)
* Fix two lock timeout cases for LK_EXCLUPGRADE and LK_UPGRADE, and
fix a bug in undo_upreq().
* A tsleep failure (such as the LK_TIMELOCK case via
vm_map_lock_read_to()) was not properly backing-out a LKC_UPREQ,
resulting in a situation where the lock becomes exclusively owned
by nobody and deadlocks against all-comers. Fix by properly
calling undo_upreq().
* Fix a bug in undo_upreq() itself. When undoing a granted UPREQ,
the lockholder must be set prior to releasing the now-granted
exclusive lock in order to avoid an assertion panic.
* While we are at it, replace a weird cmpset count,count with a
fetchadd(count, 0).