diff options
author | Matthew Wilcox (Oracle) <[email protected]> | 2020-06-01 21:46:58 -0700 |
---|---|---|
committer | Linus Torvalds <[email protected]> | 2020-06-02 10:59:07 -0700 |
commit | f2c817bed58d9be2051fad1d18e167e173c0c227 (patch) | |
tree | 445bd1c5a8a3639aa596ef6d4137ae44619a78c4 | |
parent | 2d8163e4899dad92175eedd1c2326c875eaa74fa (diff) |
mm: use memalloc_nofs_save in readahead path
Ensure that memory allocations in the readahead path do not attempt to
reclaim file-backed pages, which could lead to a deadlock. It is
possible, though unlikely this is the root cause of a problem observed
by Cong Wang.
Reported-by: Cong Wang <[email protected]>
Suggested-by: Michal Hocko <[email protected]>
Signed-off-by: Matthew Wilcox (Oracle) <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Reviewed-by: William Kucharski <[email protected]>
Cc: Chao Yu <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Darrick J. Wong <[email protected]>
Cc: Dave Chinner <[email protected]>
Cc: Eric Biggers <[email protected]>
Cc: Gao Xiang <[email protected]>
Cc: Jaegeuk Kim <[email protected]>
Cc: John Hubbard <[email protected]>
Cc: Joseph Qi <[email protected]>
Cc: Junxiao Bi <[email protected]>
Cc: Zi Yan <[email protected]>
Cc: Johannes Thumshirn <[email protected]>
Cc: Miklos Szeredi <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Linus Torvalds <[email protected]>
-rw-r--r-- | mm/readahead.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/mm/readahead.c b/mm/readahead.c index 73cb59ed5cff..3c9a8dd7c56c 100644 --- a/mm/readahead.c +++ b/mm/readahead.c @@ -22,6 +22,7 @@ #include <linux/mm_inline.h> #include <linux/blk-cgroup.h> #include <linux/fadvise.h> +#include <linux/sched/mm.h> #include "internal.h" @@ -186,6 +187,18 @@ void page_cache_readahead_unbounded(struct address_space *mapping, unsigned long i; /* + * Partway through the readahead operation, we will have added + * locked pages to the page cache, but will not yet have submitted + * them for I/O. Adding another page may need to allocate memory, + * which can trigger memory reclaim. Telling the VM we're in + * the middle of a filesystem operation will cause it to not + * touch file-backed pages, preventing a deadlock. Most (all?) + * filesystems already specify __GFP_NOFS in their mapping's + * gfp_mask, but let's be explicit here. + */ + unsigned int nofs = memalloc_nofs_save(); + + /* * Preallocate as many pages as we will need. */ for (i = 0; i < nr_to_read; i++) { @@ -229,6 +242,7 @@ void page_cache_readahead_unbounded(struct address_space *mapping, * will then handle the error. */ read_pages(&rac, &page_pool, false); + memalloc_nofs_restore(nofs); } EXPORT_SYMBOL_GPL(page_cache_readahead_unbounded); |