aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2011-02-04 14:38:11 -0800
committerBrian Behlendorf <[email protected]>2011-02-10 09:27:21 -0800
commit8926ab7a50d60d855e4d49d2ed7bdef49dd56149 (patch)
treed87a6ca7624381f1a8c500ba7be772a3ba0499ca /lib
parentc0d35759c5ab1abaa6b72062cc4ecd0d86628de8 (diff)
Move cv_destroy() outside zp->z_range_lock()
With the recent SPL change (d599e4fa) that forces cv_destroy() to block until all waiters have been woken. It is now unsafe to call cv_destroy() under the zp->z_range_lock() because it is used as the condition variable mutex. If there are waiters cv_destroy() will block until they wake up and aquire the mutex. However, they will never aquire the mutex because cv_destroy() will not return allowing it's caller to drop the lock. Deadlock. To avoid this cv_destroy() is now run asynchronously in a taskq. This solves two problems: 1) It is no longer run under the zp->z_range_lock so no deadlock. 2) Since cv_destroy() may now block we don't want this slowing down zfs_range_unlock() and throttling the system. This was not as much of an issue under OpenSolaris because their cv_destroy() implementation does not do anything. They do however risk a bad paging request if cv_destroy() returns, the memory holding the condition variable is free'd, and then the waiters wake up and try to reference it. It's a very small unlikely race, but it is possible.
Diffstat (limited to 'lib')
0 files changed, 0 insertions, 0 deletions