From: Linus T. <tor...@li...> - 2009-06-01 20:39:16
|
On Mon, 1 Jun 2009, Krzysztof Helt wrote: > > I will fix it. Thanks. > If the revert to BKL is rejected this patch may wait till 2.6.31. Ahh, so this one helps clean up locking, but doesn't fix any actual regressions? I was going to ask you about that. Btw - one thing you could try on the whole lockdep front - and I realize that this is a _total_ hack - is to try the patch below. The _only_ thing it does is to hide the sysfs_mutex -> mm_lock chain from lockdep, by using the (incorrect) __copy_to_user_inatomic() instead of the (correct) copy_to_user(). But I'd like to hear if that sysfs_mutex in readdir is the only way you can get a chain. So this is in _no_ way meant to be a serious patch, and is literally just a test to see if "ok, readdir and sysfs_mutex is really the only real deadlock case" is true. Or are there possibly other cases that trigger this? Because if it's really just this chain through sysfs_mutex, then the deadlock scenario should boil down to just the "two different fbcon's and really unlucky activity just as you register the second of them". Which is still a bug, of course - it's just not ever going to bite anybody in practice. Linus --- fs/readdir.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/readdir.c b/fs/readdir.c index 7723401..431f647 100644 --- a/fs/readdir.c +++ b/fs/readdir.c @@ -172,7 +172,7 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset, goto efault; if (__put_user(reclen, &dirent->d_reclen)) goto efault; - if (copy_to_user(dirent->d_name, name, namlen)) + if (__copy_to_user_inatomic(dirent->d_name, name, namlen)) goto efault; if (__put_user(0, dirent->d_name + namlen)) goto efault; @@ -256,7 +256,7 @@ static int filldir64(void * __buf, const char * name, int namlen, loff_t offset, goto efault; if (__put_user(d_type, &dirent->d_type)) goto efault; - if (copy_to_user(dirent->d_name, name, namlen)) + if (__copy_to_user_inatomic(dirent->d_name, name, namlen)) goto efault; if (__put_user(0, dirent->d_name + namlen)) goto efault; |