* [Bug 3.4.5] reiserfs: mutex_destroy called with locked mutex @ 2012-07-18 5:26 Knut Petersen 2012-07-18 16:26 ` Linus Torvalds 0 siblings, 1 reply; 7+ messages in thread From: Knut Petersen @ 2012-07-18 5:26 UTC (permalink / raw) To: linux-kernel; +Cc: reiserfs-devel, Linus Torvalds I hit the following problem during a heavy compile job on kernel 3.4.5: Jul 17 20:29:59 golem kernel: [27408.140718] ------------[ cut here ]------------ Jul 17 20:29:59 golem kernel: [27408.140739] WARNING: at kernel/mutex-debug.c:106 mutex_destroy+0x35/0x3f() Jul 17 20:29:59 golem kernel: [27408.140748] Hardware name: Jul 17 20:29:59 golem kernel: [27408.140753] Modules linked in: ipt_MASQUERADE xt_pkttype xt_TCPMSS xt_tcpudp xt_LOG xt_limit iptable_nat nf_nat pppoe pppox af_packet ppp_generic s lhc ir_kbd_i2c snd_pcm_oss snd_mixer_oss snd_seq snd_seq_device ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_raw xt_NOTRACK ipt_REJECT iptable_raw iptable_filter ip6table_ mangle nf_conntrack_netbios_ns nf_conntrack_broadcast nf_conntrack_ipv4 nf_defrag_ipv4 ip_tables xt_conntrack nf_conntrack ip6table_filter ip6_tables x_tables ipv6 isl6421 ir_lirc_ codec cx24116 lirc_dev ir_mce_kbd_decoder ir_sanyo_decoder cx88_dvb ir_sony_decoder ir_jvc_decoder ir_rc6_decoder videobuf_dvb snd_hda_codec_realtek dvb_core ir_rc5_decoder ir_nec_ decoder snd_hda_intel rc_hauppauge snd_hda_codec tuner snd_rme96 snd_hwdep snd_pcm cx8800 cx8802 cx88xx snd_timer snd rc_core tveeprom v4l2_common soundcore videodev btcx_risc vide obuf_dma_sg videobuf_core snd_page_alloc Jul 17 20:29:59 golem kernel: [27408.140933] Pid: 17424, comm: mkdir Not tainted 3.4.5-main #49 Jul 17 20:29:59 golem kernel: [27408.140940] Call Trace: Jul 17 20:29:59 golem kernel: [27408.140950] [<c01218bb>] ? console_unlock+0x1bc/0x1e2 Jul 17 20:29:59 golem kernel: [27408.140960] [<c0120dfc>] warn_slowpath_common+0x68/0x7d Jul 17 20:29:59 golem kernel: [27408.140969] [<c01505a5>] ? mutex_destroy+0x35/0x3f Jul 17 20:29:59 golem kernel: [27408.140978] [<c0120e25>] warn_slowpath_null+0x14/0x18 Jul 17 20:29:59 golem kernel: [27408.140987] [<c01505a5>] mutex_destroy+0x35/0x3f Jul 17 20:29:59 golem kernel: [27408.140998] [<c01cad96>] lockdep_annotate_inode_mutex_key+0x3a/0x69 Jul 17 20:29:59 golem kernel: [27408.141008] [<c01cadd6>] unlock_new_inode+0x11/0x55 Jul 17 20:29:59 golem kernel: [27408.141018] [<c020914c>] reiserfs_mkdir+0x274/0x29b Jul 17 20:29:59 golem kernel: [27408.141030] [<c01c153c>] vfs_mkdir+0x8f/0xdd Jul 17 20:29:59 golem kernel: [27408.141039] [<c029a9a2>] ? apparmor_path_mkdir+0x1b/0x1d Jul 17 20:29:59 golem kernel: [27408.141049] [<c01c388b>] sys_mkdirat+0x76/0xa9 Jul 17 20:29:59 golem kernel: [27408.141058] [<c01c38d5>] sys_mkdir+0x17/0x19 Jul 17 20:29:59 golem kernel: [27408.141069] [<c049f1dd>] syscall_call+0x7/0xb Jul 17 20:29:59 golem kernel: [27408.141077] ---[ end trace ea73962172137cb3 ]--- cu, Knut ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Bug 3.4.5] reiserfs: mutex_destroy called with locked mutex 2012-07-18 5:26 [Bug 3.4.5] reiserfs: mutex_destroy called with locked mutex Knut Petersen @ 2012-07-18 16:26 ` Linus Torvalds 2012-07-18 21:20 ` Al Viro 0 siblings, 1 reply; 7+ messages in thread From: Linus Torvalds @ 2012-07-18 16:26 UTC (permalink / raw) To: Knut Petersen, Al Viro; +Cc: linux-kernel, reiserfs-devel On Tue, Jul 17, 2012 at 10:26 PM, Knut Petersen <Knut_Petersen@t-online.de> wrote: > I hit the following problem during a heavy compile job on kernel 3.4.5: I think it's triggered by the fact that reiserfs does d_instantiate(dentry, inode); unlock_new_inode(inode); ie it does the "unlock_new_inode()" *after* it has already made the inode visible to others in the filesystem. So you can now have a concurrent lookup of that dentry that finds the (locked) inode before "unlock_new_inode()" has had the chance to set the lockdep class. Also, since it's been instantiated, the only *valid* inode pointer is in the dentry, so the code really really shouldn't use the "inode" pointer any more because the refcount has been transferred to the dentry. So maybe memory pressure could turn the dentry negative (and free the inode) while the unlock_new_inode() code runs. fs/ext[23]/namei.c has the same pattern, though, and I think it should be harmless (the inode is marked I_NEW and we get the i_lock for unlock_new_inode, so the freeing code should know to keep away from it). So I don't think the freeing code could trigger, but a concurrent lookup then trying to look up the new directory (and taking the new directory i_semaphore lock) could happen, afaik. So I think we should re-order the d_instantiate/unlock_new_inode calls. Al? Linus ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Bug 3.4.5] reiserfs: mutex_destroy called with locked mutex 2012-07-18 16:26 ` Linus Torvalds @ 2012-07-18 21:20 ` Al Viro 2012-07-18 21:25 ` Linus Torvalds 0 siblings, 1 reply; 7+ messages in thread From: Al Viro @ 2012-07-18 21:20 UTC (permalink / raw) To: Linus Torvalds; +Cc: Knut Petersen, linux-kernel, reiserfs-devel On Wed, Jul 18, 2012 at 09:26:57AM -0700, Linus Torvalds wrote: > On Tue, Jul 17, 2012 at 10:26 PM, Knut Petersen > <Knut_Petersen@t-online.de> wrote: > > I hit the following problem during a heavy compile job on kernel 3.4.5: > > I think it's triggered by the fact that reiserfs does > > d_instantiate(dentry, inode); > unlock_new_inode(inode); > > ie it does the "unlock_new_inode()" *after* it has already made the > inode visible to others in the filesystem. So you can now have a > concurrent lookup of that dentry that finds the (locked) inode before > "unlock_new_inode()" has had the chance to set the lockdep class. > Also, since it's been instantiated, the only *valid* inode pointer is > in the dentry, so the code really really shouldn't use the "inode" > pointer any more because the refcount has been transferred to the > dentry. So maybe memory pressure could turn the dentry negative (and > free the inode) while the unlock_new_inode() code runs. > > fs/ext[23]/namei.c has the same pattern, though, and I think it should > be harmless (the inode is marked I_NEW and we get the i_lock for > unlock_new_inode, so the freeing code should know to keep away from > it). So I don't think the freeing code could trigger, but a concurrent > lookup then trying to look up the new directory (and taking the new > directory i_semaphore lock) could happen, afaik. > > So I think we should re-order the d_instantiate/unlock_new_inode calls. Al? Umm... The thing is, we'd get WARN_ON() in iput_final() triggering in that scenario before lockdep could complain. Note that dentry is pinned by reference we are holding, so no matter who comes and finds it in dcache, no amount of memory pressure is going to evict it or its inode. Busy dentries do _not_ become negative under us. So no, I don't believe that this is what the original poster had been seeing. OTOH, you are right and it's better to reorder these pairs on the general principle; it's just that we are seeing something else here. Below is the obvious patch reordering such guys; it's a lot more than just ext[23] and reiserfs, BTW. I don't believe that this should go in this cycle, though, and it won't change the situation for the original poster. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> --- diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index da52cdb..ffa2be5 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -269,8 +269,8 @@ ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry, iput(ecryptfs_inode); goto out; } - d_instantiate(ecryptfs_dentry, ecryptfs_inode); unlock_new_inode(ecryptfs_inode); + d_instantiate(ecryptfs_dentry, ecryptfs_inode); out: return rc; } diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 9ba7de0..73b0d95 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -41,8 +41,8 @@ static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode) { int err = ext2_add_link(dentry, inode); if (!err) { - d_instantiate(dentry, inode); unlock_new_inode(inode); + d_instantiate(dentry, inode); return 0; } inode_dec_link_count(inode); @@ -242,8 +242,8 @@ static int ext2_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) if (err) goto out_fail; - d_instantiate(dentry, inode); unlock_new_inode(inode); + d_instantiate(dentry, inode); out: return err; diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 85286db..8f4fdda 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -1671,8 +1671,8 @@ static int ext3_add_nondir(handle_t *handle, int err = ext3_add_entry(handle, dentry, inode); if (!err) { ext3_mark_inode_dirty(handle, inode); - d_instantiate(dentry, inode); unlock_new_inode(inode); + d_instantiate(dentry, inode); return 0; } drop_nlink(inode); @@ -1836,8 +1836,8 @@ out_clear_inode: if (err) goto out_clear_inode; - d_instantiate(dentry, inode); unlock_new_inode(inode); + d_instantiate(dentry, inode); out_stop: brelse(dir_block); ext3_journal_stop(handle); diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index eca3e48..d0d3f0e 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -2072,8 +2072,8 @@ static int ext4_add_nondir(handle_t *handle, int err = ext4_add_entry(handle, dentry, inode); if (!err) { ext4_mark_inode_dirty(handle, inode); - d_instantiate(dentry, inode); unlock_new_inode(inode); + d_instantiate(dentry, inode); return 0; } drop_nlink(inode); @@ -2249,8 +2249,8 @@ out_clear_inode: err = ext4_mark_inode_dirty(handle, dir); if (err) goto out_clear_inode; - d_instantiate(dentry, inode); unlock_new_inode(inode); + d_instantiate(dentry, inode); out_stop: brelse(dir_block); ext4_journal_stop(handle); diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 2324519..ad7774d 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c @@ -226,8 +226,8 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, __func__, inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->pino_nlink, inode->i_mapping->nrpages); - d_instantiate(dentry, inode); unlock_new_inode(inode); + d_instantiate(dentry, inode); return 0; fail: @@ -446,8 +446,8 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char mutex_unlock(&dir_f->sem); jffs2_complete_reservation(c); - d_instantiate(dentry, inode); unlock_new_inode(inode); + d_instantiate(dentry, inode); return 0; fail: @@ -591,8 +591,8 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, umode_t mode mutex_unlock(&dir_f->sem); jffs2_complete_reservation(c); - d_instantiate(dentry, inode); unlock_new_inode(inode); + d_instantiate(dentry, inode); return 0; fail: @@ -766,8 +766,8 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, umode_t mode mutex_unlock(&dir_f->sem); jffs2_complete_reservation(c); - d_instantiate(dentry, inode); unlock_new_inode(inode); + d_instantiate(dentry, inode); return 0; fail: diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index c426293..3b91a7a 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -176,8 +176,8 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, umode_t mode, unlock_new_inode(ip); iput(ip); } else { - d_instantiate(dentry, ip); unlock_new_inode(ip); + d_instantiate(dentry, ip); } out2: @@ -309,8 +309,8 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode) unlock_new_inode(ip); iput(ip); } else { - d_instantiate(dentry, ip); unlock_new_inode(ip); + d_instantiate(dentry, ip); } out2: @@ -1043,8 +1043,8 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, unlock_new_inode(ip); iput(ip); } else { - d_instantiate(dentry, ip); unlock_new_inode(ip); + d_instantiate(dentry, ip); } out2: @@ -1424,8 +1424,8 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, unlock_new_inode(ip); iput(ip); } else { - d_instantiate(dentry, ip); unlock_new_inode(ip); + d_instantiate(dentry, ip); } out1: diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 3916be1..8567fb8 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -634,8 +634,8 @@ static int reiserfs_create(struct inode *dir, struct dentry *dentry, umode_t mod reiserfs_update_inode_transaction(inode); reiserfs_update_inode_transaction(dir); - d_instantiate(dentry, inode); unlock_new_inode(inode); + d_instantiate(dentry, inode); retval = journal_end(&th, dir->i_sb, jbegin_count); out_failed: @@ -712,8 +712,8 @@ static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode goto out_failed; } - d_instantiate(dentry, inode); unlock_new_inode(inode); + d_instantiate(dentry, inode); retval = journal_end(&th, dir->i_sb, jbegin_count); out_failed: @@ -800,8 +800,8 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode // the above add_entry did not update dir's stat data reiserfs_update_sd(&th, dir); - d_instantiate(dentry, inode); unlock_new_inode(inode); + d_instantiate(dentry, inode); retval = journal_end(&th, dir->i_sb, jbegin_count); out_failed: reiserfs_write_unlock_once(dir->i_sb, lock_depth); @@ -1096,8 +1096,8 @@ static int reiserfs_symlink(struct inode *parent_dir, goto out_failed; } - d_instantiate(dentry, inode); unlock_new_inode(inode); + d_instantiate(dentry, inode); retval = journal_end(&th, parent_dir->i_sb, jbegin_count); out_failed: reiserfs_write_unlock(parent_dir->i_sb); ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [Bug 3.4.5] reiserfs: mutex_destroy called with locked mutex 2012-07-18 21:20 ` Al Viro @ 2012-07-18 21:25 ` Linus Torvalds 2012-07-18 21:33 ` Al Viro 0 siblings, 1 reply; 7+ messages in thread From: Linus Torvalds @ 2012-07-18 21:25 UTC (permalink / raw) To: Al Viro; +Cc: Knut Petersen, linux-kernel, reiserfs-devel On Wed, Jul 18, 2012 at 2:20 PM, Al Viro <viro@zeniv.linux.org.uk> wrote: > On Wed, Jul 18, 2012 at 09:26:57AM -0700, Linus Torvalds wrote: >> >> So I don't think the freeing code could trigger, but a concurrent >> lookup then trying to look up the new directory (and taking the new >> directory i_semaphore lock) could happen, afaik. > > Umm... The thing is, we'd get WARN_ON() in iput_final() triggering in > that scenario before lockdep could complain. Not for the "look up directory in the dcache, and then lock that inode" case, afaik. You'd get the lock before iput_final(), no? So then "unlock_new_inode()" would run with the inode mutex held, which could explain the lockdep warning, no? Linus ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Bug 3.4.5] reiserfs: mutex_destroy called with locked mutex 2012-07-18 21:25 ` Linus Torvalds @ 2012-07-18 21:33 ` Al Viro 2012-07-18 22:37 ` Linus Torvalds 0 siblings, 1 reply; 7+ messages in thread From: Al Viro @ 2012-07-18 21:33 UTC (permalink / raw) To: Linus Torvalds; +Cc: Knut Petersen, linux-kernel, reiserfs-devel On Wed, Jul 18, 2012 at 02:25:02PM -0700, Linus Torvalds wrote: > On Wed, Jul 18, 2012 at 2:20 PM, Al Viro <viro@zeniv.linux.org.uk> wrote: > > On Wed, Jul 18, 2012 at 09:26:57AM -0700, Linus Torvalds wrote: > >> > >> So I don't think the freeing code could trigger, but a concurrent > >> lookup then trying to look up the new directory (and taking the new > >> directory i_semaphore lock) could happen, afaik. > > > > Umm... The thing is, we'd get WARN_ON() in iput_final() triggering in > > that scenario before lockdep could complain. > > Not for the "look up directory in the dcache, and then lock that > inode" case, afaik. You'd get the lock before iput_final(), no? > > So then "unlock_new_inode()" would run with the inode mutex held, > which could explain the lockdep warning, no? Umm.. Right you are, I was thinking about the "can the freeing code actually trigger". OK; I'm still not sure this should go in before -final, but it could be the reason behind those (false positive) warnings from lockdep. Could probably step into something nasty around e.g. writeback or quota, so maybe it's worth doing just in case... It's definitely the right thing to do wrt not giving the rest of the VFS/VM nasty surprises - everything might work correctly with IO coming on such still-I_NEW-and-locked inode, but that's not a case that will be often considered when modifying code. The only questions are "is this the WARN_ON() Knut had stepped on" (and I agree with your scenario now) and "is it critical enough to shove it into the tree less than a week before -final". Up to you... ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Bug 3.4.5] reiserfs: mutex_destroy called with locked mutex 2012-07-18 21:33 ` Al Viro @ 2012-07-18 22:37 ` Linus Torvalds 2012-07-19 4:28 ` Al Viro 0 siblings, 1 reply; 7+ messages in thread From: Linus Torvalds @ 2012-07-18 22:37 UTC (permalink / raw) To: Al Viro; +Cc: Knut Petersen, linux-kernel, reiserfs-devel On Wed, Jul 18, 2012 at 2:33 PM, Al Viro <viro@zeniv.linux.org.uk> wrote: > > The only questions > are "is this the WARN_ON() Knut had stepped on" (and I agree with your > scenario now) and "is it critical enough to shove it into the tree > less than a week before -final". Up to you... I agree that it isn't critical. Even the lockdep thing is just a warning, and is apparently quite hard to trigger. Will you hold on to the patch in your VFS tree, and we can just merge it for 3.6? Linus ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Bug 3.4.5] reiserfs: mutex_destroy called with locked mutex 2012-07-18 22:37 ` Linus Torvalds @ 2012-07-19 4:28 ` Al Viro 0 siblings, 0 replies; 7+ messages in thread From: Al Viro @ 2012-07-19 4:28 UTC (permalink / raw) To: Linus Torvalds; +Cc: Knut Petersen, linux-kernel, reiserfs-devel On Wed, Jul 18, 2012 at 03:37:52PM -0700, Linus Torvalds wrote: > On Wed, Jul 18, 2012 at 2:33 PM, Al Viro <viro@zeniv.linux.org.uk> wrote: > > > > The only questions > > are "is this the WARN_ON() Knut had stepped on" (and I agree with your > > scenario now) and "is it critical enough to shove it into the tree > > less than a week before -final". Up to you... > > > I agree that it isn't critical. Even the lockdep thing is just a > warning, and is apparently quite hard to trigger. > > Will you hold on to the patch in your VFS tree, and we can just merge > it for 3.6? Sure, no problem... ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-07-19 4:28 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-07-18 5:26 [Bug 3.4.5] reiserfs: mutex_destroy called with locked mutex Knut Petersen 2012-07-18 16:26 ` Linus Torvalds 2012-07-18 21:20 ` Al Viro 2012-07-18 21:25 ` Linus Torvalds 2012-07-18 21:33 ` Al Viro 2012-07-18 22:37 ` Linus Torvalds 2012-07-19 4:28 ` Al Viro
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).