Commit 232ea4d69d81169453344b7d05203425c88d973b
Committed by
Linus Torvalds
1 parent
b1a316f6f9
Exists in
master
and in
20 other branches
[PATCH] throttle_vm_writeout(): don't loop on GFP_NOFS and GFP_NOIO allocations
throttle_vm_writeout() is designed to wait for the dirty levels to subside. But if the caller holds IO or FS locks, we might be holding up that writeout. So change it to take a single nap to give other devices a chance to clean some memory, then return. Cc: Nick Piggin <nickpiggin@yahoo.com.au> Cc: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> Cc: Kumar Gala <galak@kernel.crashing.org> Cc: Pete Zaitcev <zaitcev@redhat.com> Cc: <stable@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 3 changed files with 13 additions and 4 deletions Side-by-side Diff
include/linux/writeback.h
... | ... | @@ -84,7 +84,7 @@ |
84 | 84 | int wakeup_pdflush(long nr_pages); |
85 | 85 | void laptop_io_completion(void); |
86 | 86 | void laptop_sync_completion(void); |
87 | -void throttle_vm_writeout(void); | |
87 | +void throttle_vm_writeout(gfp_t gfp_mask); | |
88 | 88 | |
89 | 89 | /* These are exported to sysctl. */ |
90 | 90 | extern int dirty_background_ratio; |
mm/page-writeback.c
... | ... | @@ -296,11 +296,21 @@ |
296 | 296 | } |
297 | 297 | EXPORT_SYMBOL(balance_dirty_pages_ratelimited_nr); |
298 | 298 | |
299 | -void throttle_vm_writeout(void) | |
299 | +void throttle_vm_writeout(gfp_t gfp_mask) | |
300 | 300 | { |
301 | 301 | long background_thresh; |
302 | 302 | long dirty_thresh; |
303 | 303 | |
304 | + if ((gfp_mask & (__GFP_FS|__GFP_IO)) != (__GFP_FS|__GFP_IO)) { | |
305 | + /* | |
306 | + * The caller might hold locks which can prevent IO completion | |
307 | + * or progress in the filesystem. So we cannot just sit here | |
308 | + * waiting for IO to complete. | |
309 | + */ | |
310 | + congestion_wait(WRITE, HZ/10); | |
311 | + return; | |
312 | + } | |
313 | + | |
304 | 314 | for ( ; ; ) { |
305 | 315 | get_dirty_limits(&background_thresh, &dirty_thresh, NULL); |
306 | 316 | |
... | ... | @@ -316,7 +326,6 @@ |
316 | 326 | congestion_wait(WRITE, HZ/10); |
317 | 327 | } |
318 | 328 | } |
319 | - | |
320 | 329 | |
321 | 330 | /* |
322 | 331 | * writeback at least _min_pages, and keep writing until the amount of dirty |