Message ID | 4946.1582339996@jrobl (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | ext2, possible circular locking dependency detected | expand |
Hello! On Sat 22-02-20 11:53:16, J. R. Okajima wrote: > Hello ext2 maintainers, > > During my local fs stress test, I've encounter this. > Is it false positive? > Otherwise, I've made a small patch to stop reclaming recursively into FS > from ext2_xattr_set(). Please consider taking this. > > Once I've considered about whether it should be done in VFS layer or > not. I mean, every i_op->brabra() calls in VFS should be surrounded by > memalloc_nofs_{save,restore}(), by a macro or something. But I am > afraid it may introduce unnecesary overheads, especially when FS code > doesn't allocate memory. So it is better to do it in real FS > operations. Thanks for debugging this and for the patch. One comment below: ... > @@ -532,7 +534,9 @@ ext2_xattr_set(struct inode *inode, int name_index, const char *name, > > unlock_buffer(bh); > ea_bdebug(bh, "cloning"); > + nofs_flag = memalloc_nofs_save(); > header = kmemdup(HDR(bh), bh->b_size, GFP_KERNEL); > + memalloc_nofs_restore(nofs_flag); > error = -ENOMEM; > if (header == NULL) > goto cleanup; > @@ -545,7 +549,9 @@ ext2_xattr_set(struct inode *inode, int name_index, const char *name, > } > } else { > /* Allocate a buffer where we construct the new block. */ > + nofs_flag = memalloc_nofs_save(); > header = kzalloc(sb->s_blocksize, GFP_KERNEL); > + memalloc_nofs_restore(nofs_flag); > error = -ENOMEM; > if (header == NULL) > goto cleanup; This is not the right way how memalloc_nofs_save() should be used (you could just use GFP_NOFS instead of GFP_KERNEL instead of wrapping the allocation inside memalloc_nofs_save/restore()). The memalloc_nofs_save/restore() API is created so that you can change the allocation context at the place which mandates the new context - i.e., in this case when acquiring / dropping xattr_sem. That way you don't have to propagate the context information down to function calls and the code is also future-proof - if you add new allocation, they will use correct allocation context. Honza
Jan Kara: > This is not the right way how memalloc_nofs_save() should be used (you > could just use GFP_NOFS instead of GFP_KERNEL instead of wrapping the > allocation inside memalloc_nofs_save/restore()). The > memalloc_nofs_save/restore() API is created so that you can change the > allocation context at the place which mandates the new context - i.e., in > this case when acquiring / dropping xattr_sem. That way you don't have to > propagate the context information down to function calls and the code is > also future-proof - if you add new allocation, they will use correct > allocation context. Thanks for the lecture about memalloc_nofs_save/restore(). Honestly speaking, I didn't know these APIs and I always use GFP_NOFS flag. Investigating this lockdep warning, I read the comments in gfp.h. * %GFP_NOFS will use direct reclaim but will not use any filesystem interfaces. * Please try to avoid using this flag directly and instead use * memalloc_nofs_{save,restore} to mark the whole scope which cannot/shouldn't * recurse into the FS layer with a short explanation why. All allocation * requests will inherit GFP_NOFS implicitly. Actually grep-ping the whole kernel source tree told me there are several "one-liners" like ...nofs_save(); kmalloc(); ...nofs_restore sequence. But re-reading the comments and your mail, I understand these APIs are for much wider region than such one-liner. I don't think it a good idea that I send you another patch replaced by GFP_NOFS. You can fix it simply and you know much more than me about this matter, and I will be satisfied when this problem is fixed by you. J. R. Okajima
On Mon 24-02-20 19:02:16, J. R. Okajima wrote: > Jan Kara: > > This is not the right way how memalloc_nofs_save() should be used (you > > could just use GFP_NOFS instead of GFP_KERNEL instead of wrapping the > > allocation inside memalloc_nofs_save/restore()). The > > memalloc_nofs_save/restore() API is created so that you can change the > > allocation context at the place which mandates the new context - i.e., in > > this case when acquiring / dropping xattr_sem. That way you don't have to > > propagate the context information down to function calls and the code is > > also future-proof - if you add new allocation, they will use correct > > allocation context. > > Thanks for the lecture about memalloc_nofs_save/restore(). > Honestly speaking, I didn't know these APIs and I always use GFP_NOFS > flag. Investigating this lockdep warning, I read the comments in gfp.h. > > * %GFP_NOFS will use direct reclaim but will not use any filesystem interfaces. > * Please try to avoid using this flag directly and instead use > * memalloc_nofs_{save,restore} to mark the whole scope which cannot/shouldn't > * recurse into the FS layer with a short explanation why. All allocation > * requests will inherit GFP_NOFS implicitly. > > Actually grep-ping the whole kernel source tree told me there are > several "one-liners" like ...nofs_save(); kmalloc(); ...nofs_restore > sequence. But re-reading the comments and your mail, I understand these > APIs are for much wider region than such one-liner. > > I don't think it a good idea that I send you another patch replaced by > GFP_NOFS. You can fix it simply and you know much more than me about > this matter, and I will be satisfied when this problem is fixed by you. OK, in the end I've decided to go with a different solution because I realized the warning is a false positive one. The patch has passed a fstests run but I'd be grateful if you could verify whether you can no longer trigger the lockdep warning. Thanks! Honza PS: I've posted the patch separately to the list.
Jan Kara: > OK, in the end I've decided to go with a different solution because I > realized the warning is a false positive one. The patch has passed a > fstests run but I'd be grateful if you could verify whether you can no longer > trigger the lockdep warning. Thanks! I will. But it may take very long time, a month or two I am afraid. If you don't receive any mail about this matter in next few months, then it means everything is fine. Thnak you J. R. Okajima
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index 0456bc990b5e..85463fddbc17 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c @@ -61,6 +61,7 @@ #include <linux/quotaops.h> #include <linux/rwsem.h> #include <linux/security.h> +#include <linux/sched/mm.h> #include "ext2.h" #include "xattr.h" #include "acl.h" @@ -413,6 +414,7 @@ ext2_xattr_set(struct inode *inode, int name_index, const char *name, size_t name_len, free, min_offs = sb->s_blocksize; int not_found = 1, error; char *end; + unsigned int nofs_flag; /* * header -- Points either into bh, or to a temporarily @@ -532,7 +534,9 @@ ext2_xattr_set(struct inode *inode, int name_index, const char *name, unlock_buffer(bh); ea_bdebug(bh, "cloning"); + nofs_flag = memalloc_nofs_save(); header = kmemdup(HDR(bh), bh->b_size, GFP_KERNEL); + memalloc_nofs_restore(nofs_flag); error = -ENOMEM; if (header == NULL) goto cleanup; @@ -545,7 +549,9 @@ ext2_xattr_set(struct inode *inode, int name_index, const char *name, } } else { /* Allocate a buffer where we construct the new block. */ + nofs_flag = memalloc_nofs_save(); header = kzalloc(sb->s_blocksize, GFP_KERNEL); + memalloc_nofs_restore(nofs_flag); error = -ENOMEM; if (header == NULL) goto cleanup;