[PATCH 34/45] writeback: sync livelock - kick background writeback

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

 



The periodic/background writeback can run forever. So when any
sync work is enqueued, increase bdi->sync_works to notify the
active non-sync works to exit. Non-sync works queued after all sync
works won't be affected.

Signed-off-by: Wu Fengguang <fengguang.wu@xxxxxxxxx>
---
 fs/fs-writeback.c           |   11 +++++++++++
 include/linux/backing-dev.h |    5 +++++
 mm/backing-dev.c            |    1 +
 3 files changed, 17 insertions(+)

--- linux.orig/fs/fs-writeback.c	2009-10-06 23:39:33.000000000 +0800
+++ linux/fs/fs-writeback.c	2009-10-06 23:39:33.000000000 +0800
@@ -139,6 +139,8 @@ static void wb_clear_pending(struct bdi_
 		list_del_rcu(&work->list);
 		if (work->args.for_background)
 			clear_bit(WB_FLAG_BACKGROUND_WORK, &bdi->wb_mask);
+		if (work->args.for_sync)
+			bdi->sync_works--;
 		spin_unlock(&bdi->wb_lock);
 
 		wb_work_complete(work);
@@ -159,6 +161,8 @@ static void bdi_queue_work(struct backin
 	 */
 	spin_lock(&bdi->wb_lock);
 	list_add_tail_rcu(&work->list, &bdi->work_list);
+	if (work->args.for_sync)
+		bdi->sync_works++;
 	spin_unlock(&bdi->wb_lock);
 
 	/*
@@ -811,6 +815,13 @@ static long wb_writeback(struct bdi_writ
 			break;
 
 		/*
+		 * background/periodic works can run forever, need to abort
+		 * on seeing any pending sync work, to prevent livelock it.
+		 */
+		if (!args->for_sync && wb->bdi->sync_works > 0)
+			break;
+
+		/*
 		 * For background writeout, stop when we are below the
 		 * background dirty threshold
 		 */
--- linux.orig/include/linux/backing-dev.h	2009-10-06 23:39:33.000000000 +0800
+++ linux/include/linux/backing-dev.h	2009-10-06 23:39:33.000000000 +0800
@@ -84,6 +84,11 @@ struct backing_dev_info {
 	struct list_head wb_list; /* the flusher threads hanging off this bdi */
 	unsigned long wb_mask;	  /* bitmask of registered tasks */
 	unsigned int wb_cnt;	  /* number of registered tasks */
+	/*
+	 * sync works queued, background works shall abort on seeing this,
+	 * to prevent livelocking the sync works
+	 */
+	unsigned int sync_works;
 
 	struct list_head work_list;
 
--- linux.orig/mm/backing-dev.c	2009-10-06 23:38:52.000000000 +0800
+++ linux/mm/backing-dev.c	2009-10-06 23:39:33.000000000 +0800
@@ -647,6 +647,7 @@ int bdi_init(struct backing_dev_info *bd
 	 */
 	bdi->wb_mask = 1;
 	bdi->wb_cnt = 1;
+	bdi->sync_works = 0;
 
 	bdi->write_bandwidth = MAX_WRITEBACK_PAGES;
 


--
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