zfsonlinux/zfs — pull request #1617 by ryao (2013-07-30 11:47:56+00:00)
Title: Fix zil_commit() deadlock

If two threads concurrently enter zil_commit(), one will take the
zilog->zl_lock mutex (lets call this thread A) while the other will
block (lets call this thread B). Thread A will then set a flag saying
that there is a writer and free the mutex. Thread B will get the mutex,
see the flag and enter a condition wait for a signal from thread A that
it finished. Then before thead A sends the signal, it will attempt to
take the mutex. The two threads will then wait on each other ad
infinitum and forward progress on the pool will stop. We break the
deadlock by making thread A stop trying to retake the mutex. This is safe
because even though thread B has the mutex, it will not act until
signaled by thread A, giving thread A effective control over the mutex.

Signed-off-by: Richard Yao