[PATCH 36/45] writeback: sync livelock - curb dirty speed for inodes to be synced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The inodes to be synced will be dirty throttled regardless of the dirty
threshold.  This stops sync() livelock by some fast dirtier.

CC: Jan Kara <jack@xxxxxxx> 
Signed-off-by: Wu Fengguang <fengguang.wu@xxxxxxxxx>
---
 fs/fs-writeback.c           |    4 ++++
 include/linux/backing-dev.h |    1 +
 mm/page-writeback.c         |   13 +++++++++++++
 3 files changed, 18 insertions(+)

--- linux.orig/mm/page-writeback.c	2009-10-07 10:47:09.000000000 +0800
+++ linux/mm/page-writeback.c	2009-10-07 14:32:43.000000000 +0800
@@ -478,6 +478,18 @@ static void balance_dirty_pages(struct a
 	global_dirty_thresh(&background_thresh, &dirty_thresh);
 
 	/*
+	 * If sync() is in progress, curb the to-be-synced inodes regardless
+	 * of dirty limits, so that a fast dirtier won't livelock the sync.
+	 */
+	if (unlikely(bdi->sync_time &&
+		     S_ISREG(mapping->host->i_mode) &&
+		     time_after_eq(bdi->sync_time,
+				   mapping->host->dirtied_when))) {
+		write_chunk *= 2;
+		goto throttle;
+	}
+
+	/*
 	 * Throttle it only when the background writeback cannot
 	 * catch-up. This skips the ramp up phase of bdi limits.
 	 */
@@ -510,6 +522,7 @@ static void balance_dirty_pages(struct a
 	if (!dirty_exceeded)
 		goto out;
 
+throttle:
 	if (!bdi->dirty_exceeded)
 		bdi->dirty_exceeded = 1;
 
--- linux.orig/fs/fs-writeback.c	2009-10-07 10:47:09.000000000 +0800
+++ linux/fs/fs-writeback.c	2009-10-07 14:31:47.000000000 +0800
@@ -796,6 +796,7 @@ static long wb_writeback(struct bdi_writ
 	if (wbc.for_sync) {
 		wbc.older_than_this = &oldest_jif;
 		oldest_jif = jiffies;
+		wbc.bdi->sync_time = oldest_jif | 1;
 	}
 	if (wbc.for_kupdate || wbc.for_background) {
 		wbc.older_than_this = &oldest_jif;
@@ -873,6 +874,9 @@ static long wb_writeback(struct bdi_writ
 		spin_unlock(&inode_lock);
 	}
 
+	if (args->for_sync)
+		wb->bdi->sync_time = 0;
+
 	if (args->for_background)
 		while (bdi_writeback_wakeup(wb->bdi))
 			;  /* unthrottle all tasks */
--- linux.orig/include/linux/backing-dev.h	2009-10-07 10:47:09.000000000 +0800
+++ linux/include/linux/backing-dev.h	2009-10-07 14:31:53.000000000 +0800
@@ -89,6 +89,7 @@ struct backing_dev_info {
 	 * to prevent livelocking the sync works
 	 */
 	unsigned int sync_works;
+	unsigned long sync_time;
 
 	struct list_head work_list;
 


--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux