Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mm: avoid resetting wb_start after each writeback round

WB_SYNC_NONE writeback is done in rounds of 1024 pages so that we don't
write out some huge inode for too long while starving writeout of other
inodes. To avoid livelocks, we record time we started writeback in
wbc->wb_start and do not write out inodes which were dirtied after this
time. But currently, writeback_inodes_wb() resets wb_start each time it
is called thus effectively invalidating this logic and making any
WB_SYNC_NONE writeback prone to livelocks.

This patch makes sure wb_start is set only once when we start writeback.

Signed-off-by: Jan Kara <jack@suse.cz>
Reviewed-by: Wu Fengguang <fengguang.wu@intel.com>
Cc: Christoph Hellwig <hch@lst.de>
Acked-by: Jens Axboe <jaxboe@fusionio.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Jan Kara and committed by
Linus Torvalds
7624ee72 d9f8984c

+3 -2
+3 -2
fs/fs-writeback.c
··· 530 530 { 531 531 int ret = 0; 532 532 533 - wbc->wb_start = jiffies; /* livelock avoidance */ 533 + if (!wbc->wb_start) 534 + wbc->wb_start = jiffies; /* livelock avoidance */ 534 535 spin_lock(&inode_lock); 535 536 if (!wbc->for_kupdate || list_empty(&wb->b_io)) 536 537 queue_io(wb, wbc->older_than_this); ··· 560 559 { 561 560 WARN_ON(!rwsem_is_locked(&sb->s_umount)); 562 561 563 - wbc->wb_start = jiffies; /* livelock avoidance */ 564 562 spin_lock(&inode_lock); 565 563 if (!wbc->for_kupdate || list_empty(&wb->b_io)) 566 564 queue_io(wb, wbc->older_than_this); ··· 625 625 wbc.range_end = LLONG_MAX; 626 626 } 627 627 628 + wbc.wb_start = jiffies; /* livelock avoidance */ 628 629 for (;;) { 629 630 /* 630 631 * Stop writeback when nr_pages has been consumed