On Thu, 2013-04-04 at 15:31 +0200, Daniel Vetter wrote:
We do add some form of owner tracking by storing the reservation ticket of the current holder into every ww_mutex. So when task-Y in your above example tries to acquire lock A it notices that it's behind in the global queue and immedieately returns -EAGAIN to indicate the deadlock.
Aside, there's a bit of fun in that ttm uses -EDEADLCK for when you try to reserve the same buffer twice - it can easily detect that by comparing the lock owner ticket with the provided one and if it matches bail out.
Sure, but this should bear no influence on the design of the mutex primitive. At most we should ensure this situation is recognizable.
Hence we've kept the special -EDEADLCK semantics even for the ww_mutex stuff.
There's EDEADLK and EDEADLOCK, EDEADLCK does alas not exist :-)
Now this gets a little more interesting if we change the scenario a little:
task-O task-Y A B B <-- blocks on Y * <-- could be A
The current code at least simple blocks task-O on B until task-Y unlocks B. Deadlocks cannot happen since if task-Y ever tries to acquire a lock which is held by an older task (e.g. lock A) it will bail out with -EAGAIN.
Agreed, O would have to wait until Y unlocks B. It was a 'detail' I skimped over for the sake of brevity. I was merely trying to illustrate the ways in which we must bring Y to return -EDEADLK (or -EAGAIN in your version).