Message ID | 1331154095.3105.25.camel@pasglop (mailing list archive) |
---|---|
State | Accepted, archived |
Delegated to: | Benjamin Herrenschmidt |
Headers | show |
> No it's not, it all goes together. spufs_create_context() always > unlocked & dropped the dentry before returning, so I assumed the > lock had to be dropped before fsnotify. > > Note that if the problem is that the lock has to be dropped before > spu_forget(), then we should indeed move it back into the leaf functions > and just remove all the unlock path from the top ones. It's a bit nasty > how we drop the mutex first, then do spu_forget, then drop the dentry > but we could go back to doing that. > > What I want is consistent semantics. It's just silly to have 3 different > stacking levels which all 3 may or may not be responsible to dropping > the lock & dentry depending on circumstances. Why not leave unlock/dput to the caller? Details of deadlocks caused by that approach, please...
On Wednesday 07 March 2012, Al Viro wrote: > > No it's not, it all goes together. spufs_create_context() always > > unlocked & dropped the dentry before returning, so I assumed the > > lock had to be dropped before fsnotify. > > > > Note that if the problem is that the lock has to be dropped before > > spu_forget(), then we should indeed move it back into the leaf functions > > and just remove all the unlock path from the top ones. It's a bit nasty > > how we drop the mutex first, then do spu_forget, then drop the dentry > > but we could go back to doing that. > > > > What I want is consistent semantics. It's just silly to have 3 different > > stacking levels which all 3 may or may not be responsible to dropping > > the lock & dentry depending on circumstances. > > Why not leave unlock/dput to the caller? Details of deadlocks caused > by that approach, please... If only I could remember that part exactly. I think I was remembering 0309f02d8 "spufs: fix deadlock in spu_create error path", which had a double lock problem in this path. Please bear with me here because it's been six years since I debugged that particular problem. A lot of the nastyness of spu_forget() is about the problem of having to give up a reference on current->mm that is held by an spu context, while the mm contains a vma that maps this context and holds a refence on the inode, in particular in case of calling exit(). However, I don't see now how either of these two issues requires that we call spu_forget without the i_mutex held during a context creation failure. Arnd
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index d4a094c..114ab14 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -646,6 +646,7 @@ long spufs_create(struct path *path, struct dentry *dentry, out: mutex_unlock(&path->dentry->d_inode->i_mutex); + dput(dentry); return ret; } diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c index 8591bb6..5665dcc 100644 --- a/arch/powerpc/platforms/cell/spufs/syscalls.c +++ b/arch/powerpc/platforms/cell/spufs/syscalls.c @@ -70,8 +70,6 @@ static long do_spu_create(const char __user *pathname, unsigned int flags, ret = PTR_ERR(dentry); if (!IS_ERR(dentry)) { ret = spufs_create(&path, dentry, flags, mode, neighbor); - mutex_unlock(&path.dentry->d_inode->i_mutex); - dput(dentry); path_put(&path); }