| From 934f3072c17cc8886f4c043b47eeeb1b12f8de33 Mon Sep 17 00:00:00 2001 |
| From: Junxiao Bi <junxiao.bi@oracle.com> |
| Date: Thu, 9 Oct 2014 15:28:23 -0700 |
| Subject: mm: clear __GFP_FS when PF_MEMALLOC_NOIO is set |
| |
| From: Junxiao Bi <junxiao.bi@oracle.com> |
| |
| commit 934f3072c17cc8886f4c043b47eeeb1b12f8de33 upstream. |
| |
| commit 21caf2fc1931 ("mm: teach mm by current context info to not do I/O |
| during memory allocation") introduces PF_MEMALLOC_NOIO flag to avoid doing |
| I/O inside memory allocation, __GFP_IO is cleared when this flag is set, |
| but __GFP_FS implies __GFP_IO, it should also be cleared. Or it may still |
| run into I/O, like in superblock shrinker. And this will make the kernel |
| run into the deadlock case described in that commit. |
| |
| See Dave Chinner's comment about io in superblock shrinker: |
| |
| Filesystem shrinkers do indeed perform IO from the superblock shrinker and |
| have for years. Even clean inodes can require IO before they can be freed |
| - e.g. on an orphan list, need truncation of post-eof blocks, need to |
| wait for ordered operations to complete before it can be freed, etc. |
| |
| IOWs, Ext4, btrfs and XFS all can issue and/or block on arbitrary amounts |
| of IO in the superblock shrinker context. XFS, in particular, has been |
| doing transactions and IO from the VFS inode cache shrinker since it was |
| first introduced.... |
| |
| Fix this by clearing __GFP_FS in memalloc_noio_flags(), this function has |
| masked all the gfp_mask that will be passed into fs for the processes |
| setting PF_MEMALLOC_NOIO in the direct reclaim path. |
| |
| v1 thread at: https://lkml.org/lkml/2014/9/3/32 |
| |
| Signed-off-by: Junxiao Bi <junxiao.bi@oracle.com> |
| Cc: Dave Chinner <david@fromorbit.com> |
| Cc: joyce.xue <xuejiufei@huawei.com> |
| Cc: Ming Lei <ming.lei@canonical.com> |
| Cc: Trond Myklebust <trond.myklebust@primarydata.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| include/linux/sched.h | 6 ++++-- |
| 1 file changed, 4 insertions(+), 2 deletions(-) |
| |
| --- a/include/linux/sched.h |
| +++ b/include/linux/sched.h |
| @@ -1670,11 +1670,13 @@ extern void thread_group_cputime_adjuste |
| #define tsk_used_math(p) ((p)->flags & PF_USED_MATH) |
| #define used_math() tsk_used_math(current) |
| |
| -/* __GFP_IO isn't allowed if PF_MEMALLOC_NOIO is set in current->flags */ |
| +/* __GFP_IO isn't allowed if PF_MEMALLOC_NOIO is set in current->flags |
| + * __GFP_FS is also cleared as it implies __GFP_IO. |
| + */ |
| static inline gfp_t memalloc_noio_flags(gfp_t flags) |
| { |
| if (unlikely(current->flags & PF_MEMALLOC_NOIO)) |
| - flags &= ~__GFP_IO; |
| + flags &= ~(__GFP_IO | __GFP_FS); |
| return flags; |
| } |
| |