Open nyh opened 10 years ago
While the mutex might have this bug, it will not cause a crash unless we actually have code where successful lock() causes the destruction of the object containing the mutex. Linux has (see the above link) mutex-protected reference counts inside objects. But as Avi pointed out in private email, in OSv:
"files are safe - they use atomics dentries are safe - they use an external lock vnodes are safe - they use an external lock"
I think one fix for this rare case would be to protect mutexes using, e.g., Maged Michael's Safe Memory Reclamation/Hazard Pointers approach (across processors) to ensure that a mutex object is not reclaimed/destroyed until the last unlock operation referencing it is gone. However, this would not be without cost as any unlock operation would have to publish a hazard pointer before touching a mutex object.
http://lwn.net/Articles/575460/ talks about a bug (which still exists) in Linux, where a mutex unlock(), after telling a concurrent lock() that it has gotten the lock, may continue to operate on the mutex. If the other thread's taking the lock eventually results in destruction of the mutex (e.g., when a mutex inside the object was used to protect its reference count), this can lead to a crash.
Unfortunately, we seem to have the same bug in the rare (but important) RHO case in our lock-free mutex:
unlock() stores "handoff", at which point a concurrent lock() or try_lock() may take the lock for itself and return. But after storing the handoff, unlock() does not return, and goes on to check if the handoff was accepted or rather a new thread appeared on the queue. These checks involve reading from the mutex - after the concurrent lock() has already succeeded, which is the same sort of bug as reported for Linux.
This bug should be extremely rare (a rare between the already-rare RHO case and the destruction of the object containing the mutex), but definitely needs to be fixed.