From mboxrd@z Thu Jan 1 00:00:00 1970 From: Wu Fengguang Subject: [PATCH 2/2] writeback: stop background/kupdate works from livelocking other works Date: Mon, 1 Nov 2010 20:22:52 +0800 Message-ID: <20101101122252.GA10637@localhost> References: <20100913123110.372291929@intel.com> <20100913130149.994322762@intel.com> <20100914124033.GA4874@quack.suse.cz> <20101101121408.GB9006@localhost> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: "linux-mm@kvack.org" , Mel Gorman , Rik van Riel , Johannes Weiner , Minchan Kim , KAMEZAWA Hiroyuki , KOSAKI Motohiro , Dave Chinner , Christoph Hellwig , linux-fsdevel@vger.kernel.org To: Andrew Morton , Jan Kara Return-path: Received: from mga09.intel.com ([134.134.136.24]:31218 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756124Ab0KANPo (ORCPT ); Mon, 1 Nov 2010 09:15:44 -0400 Content-Disposition: inline In-Reply-To: <20101101121408.GB9006@localhost> Sender: linux-fsdevel-owner@vger.kernel.org List-ID: From: Jan Kara Background writeback are easily livelockable (from a definition of their target). This is inconvenient because it can make sync(1) stall forever waiting on its queued work to be finished. Generally, when a flusher thread has some work queued, someone submitted the work to achieve a goal more specific than what background writeback does. So it makes sense to give it a priority over a generic page cleaning. Thus we interrupt background writeback if there is some other work to do. We return to the background writeback after completing all the queued work. Signed-off-by: Jan Kara Signed-off-by: Wu Fengguang --- fs/fs-writeback.c | 9 +++++++++ 1 file changed, 9 insertions(+) --- linux-next.orig/fs/fs-writeback.c 2010-11-01 19:50:22.000000000 +0800 +++ linux-next/fs/fs-writeback.c 2010-11-01 19:56:54.000000000 +0800 @@ -664,6 +664,15 @@ static long wb_writeback(struct bdi_writ break; /* + * Background writeout and kupdate-style writeback are + * easily livelockable. Stop them if there is other work + * to do so that e.g. sync can proceed. + */ + if ((work->for_background || work->for_kupdate) && + !list_empty(&wb->bdi->work_list)) + break; + + /* * For background writeout, stop when we are below the * background dirty threshold */