On 2018-02-16, Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> wrote: > On Fri, Feb 16, 2018 at 7:09 AM, John Ogness <john.ogness@xxxxxxxxxxxxx> wrote: >> dentry_kill() holds dentry->d_lock and needs to acquire both >> dentry->d_inode->i_lock and dentry->d_parent->d_lock. This cannot be >> done with spin_lock() operations because it's the reverse of the >> regular lock order. To avoid ABBA deadlocks it is done with two >> trylock loops. >> >> Trylock loops are problematic in two scenarios: > > I don't mind this patch series per se (although I would really like Al > to ack it), but this particular patch I hate. > > Why? > >> Avoid the trylock loops by using dentry_lock_inode() and lock_parent() >> which take the locks in the appropriate order. As both functions drop >> dentry->lock briefly, this requires rechecking of the dentry content >> as it might have changed after dropping the lock. > > I think the trylock should be done first, and then you don't need that > recheck for the common case. > > I realize that the recheck itself isn't expensive, but it's mostly > about the code flow and the comment: > >> + * Recheck refcount as it might have been incremented while >> + * d_lock was dropped. > > the thing is, 99.9% of the time the d_lock wasn't dropped, so that > "while d_lock was dropped" comment is misleading. > > Re-organizing it to do the trylock fastpath explicitly here and not > bothering with the re-check etc crid for the common case is the rioght > thing to do. > > And the old code was actually organized exactly that way, with a > > if (inode && unlikely(!spin_trylock(&inode->i_lock))) > goto failed; > > at the top. > > But instead of having that unlikely "failed" case do the complex > thing, you made the *normal* case do the complex thing. > > So NAK on this. lock_parent() already has the problem you are referring to. Callers are required to recheck the dentry contents and check the returned parent because they do not know if the trylock succeeded. See d_prune_aliases(), for example. Would you like my v2 to fixup lock_parent() semantics to address your concerns there as well? John Ogness