From: Andrey Borzenkov I finally hit a painfully trivial way to reproduce another long standing devfs problem - deadlock between devfs_lookup and devfs_d_revalidate_wait. When devfs_lookup releases directory i_sem devfs_d_revalidate_wait grabs it (it happens not for every path) and goes to wait to be waked up. Unfortunately, devfs_lookup attempts to acquire directory i_sem before ever waking it up ... To reproduce (2.5.74 UP or SMP - does not matter, single CPU system) ls /dev/foo & rm -f /dev/foo & or possibly in a loop but then it easily fills up process table. In my case it hangs 100% reliably - on 2.5 OR 2.4. The current fix is to move re-acquire of i_sem after all devfs_d_revalidate_wait waiters have been waked up. Much better fix would be to ensure that ->d_revalidate either is always called under i_sem or always without. But that means the very heart of VFS and I do not dare to touch it. The fix has been tested on 2.4 (and is part of unofficial Mandrake Club kernel); I expected the same bug is in 2.5; I just was stupid not seeing the way to reproduce it before. 25-akpm/fs/devfs/base.c | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) diff -puN fs/devfs/base.c~devfs-deadlock-fix fs/devfs/base.c --- 25/fs/devfs/base.c~devfs-deadlock-fix Mon Jul 7 13:40:47 2003 +++ 25-akpm/fs/devfs/base.c Mon Jul 7 13:40:47 2003 @@ -2350,7 +2350,6 @@ static struct dentry *devfs_lookup (stru revalidation */ up (&dir->i_sem); wait_for_devfsd_finished (fs_info); /* If I'm not devfsd, must wait */ - down (&dir->i_sem); /* Grab it again because them's the rules */ de = lookup_info->de; /* If someone else has been so kind as to make the inode, we go home early */ @@ -2381,6 +2380,7 @@ out: wake_up (&lookup_info->wait_queue); put_devfs_lookup_struct(lookup_info); write_unlock (&parent->u.dir.lock); + down (&dir->i_sem); /* Grab it again because them's the rules */ devfs_put (de); return retval; } /* End Function devfs_lookup */ _