From: Wu Fengguang <fengguang.wu@intel.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Wu Fengguang <fengguang.wu@intel.com>,
LKML <linux-kernel@vger.kernel.org>,
Peter Zijlstra <a.p.zijlstra@chello.nl>,
Dave Chinner <david@fromorbit.com>,
Christoph Hellwig <hch@infradead.org>, Mel Gorman <mel@csn.ul.ie>,
Chris Mason <chris.mason@oracle.com>,
Jens Axboe <axboe@kernel.dk>, Jan Kara <jack@suse.cz>,
"linux-fsdevel@vger.kernel.org" <linux-fsdevel@vger.kernel.org>,
"linux-mm@kvack.org" <linux-mm@kvack.org>
Subject: [PATCH 02/13] writeback: avoid unnecessary calculation of bdi dirty thresholds
Date: Fri, 06 Aug 2010 00:10:53 +0800 [thread overview]
Message-ID: <20100805162432.963007535@intel.com> (raw)
In-Reply-To: 20100805161051.501816677@intel.com
[-- Attachment #1: writeback-less-bdi-calc.patch --]
[-- Type: text/plain, Size: 6308 bytes --]
Split get_dirty_limits() into global_dirty_limits()+bdi_dirty_limit(),
so that the latter can be avoided when under global dirty background
threshold (which is the normal state for most systems).
CC: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
fs/fs-writeback.c | 2
include/linux/writeback.h | 5 +-
mm/backing-dev.c | 3 -
mm/page-writeback.c | 75 ++++++++++++++++++------------------
4 files changed, 44 insertions(+), 41 deletions(-)
--- linux-next.orig/mm/page-writeback.c 2010-07-29 14:34:34.000000000 +0800
+++ linux-next/mm/page-writeback.c 2010-08-03 23:14:19.000000000 +0800
@@ -267,10 +267,11 @@ static inline void task_dirties_fraction
*
* dirty -= (dirty/8) * p_{t}
*/
-static void task_dirty_limit(struct task_struct *tsk, unsigned long *pdirty)
+static unsigned long task_dirty_limit(struct task_struct *tsk,
+ unsigned long bdi_dirty)
{
long numerator, denominator;
- unsigned long dirty = *pdirty;
+ unsigned long dirty = bdi_dirty;
u64 inv = dirty >> 3;
task_dirties_fraction(tsk, &numerator, &denominator);
@@ -278,10 +279,8 @@ static void task_dirty_limit(struct task
do_div(inv, denominator);
dirty -= inv;
- if (dirty < *pdirty/2)
- dirty = *pdirty/2;
- *pdirty = dirty;
+ return max(dirty, bdi_dirty/2);
}
/*
@@ -391,9 +390,7 @@ unsigned long determine_dirtyable_memory
return x + 1; /* Ensure that we never return 0 */
}
-void
-get_dirty_limits(unsigned long *pbackground, unsigned long *pdirty,
- unsigned long *pbdi_dirty, struct backing_dev_info *bdi)
+void global_dirty_limits(unsigned long *pbackground, unsigned long *pdirty)
{
unsigned long background;
unsigned long dirty;
@@ -425,26 +422,28 @@ get_dirty_limits(unsigned long *pbackgro
}
*pbackground = background;
*pdirty = dirty;
+}
- if (bdi) {
- u64 bdi_dirty;
- long numerator, denominator;
+unsigned long bdi_dirty_limit(struct backing_dev_info *bdi,
+ unsigned long dirty)
+{
+ u64 bdi_dirty;
+ long numerator, denominator;
- /*
- * Calculate this BDI's share of the dirty ratio.
- */
- bdi_writeout_fraction(bdi, &numerator, &denominator);
+ /*
+ * Calculate this BDI's share of the dirty ratio.
+ */
+ bdi_writeout_fraction(bdi, &numerator, &denominator);
- bdi_dirty = (dirty * (100 - bdi_min_ratio)) / 100;
- bdi_dirty *= numerator;
- do_div(bdi_dirty, denominator);
- bdi_dirty += (dirty * bdi->min_ratio) / 100;
- if (bdi_dirty > (dirty * bdi->max_ratio) / 100)
- bdi_dirty = dirty * bdi->max_ratio / 100;
+ bdi_dirty = (dirty * (100 - bdi_min_ratio)) / 100;
+ bdi_dirty *= numerator;
+ do_div(bdi_dirty, denominator);
- *pbdi_dirty = bdi_dirty;
- task_dirty_limit(current, pbdi_dirty);
- }
+ bdi_dirty += (dirty * bdi->min_ratio) / 100;
+ if (bdi_dirty > (dirty * bdi->max_ratio) / 100)
+ bdi_dirty = dirty * bdi->max_ratio / 100;
+
+ return bdi_dirty;
}
/*
@@ -475,13 +474,24 @@ static void balance_dirty_pages(struct a
.range_cyclic = 1,
};
- get_dirty_limits(&background_thresh, &dirty_thresh,
- &bdi_thresh, bdi);
-
nr_reclaimable = global_page_state(NR_FILE_DIRTY) +
global_page_state(NR_UNSTABLE_NFS);
nr_writeback = global_page_state(NR_WRITEBACK);
+ global_dirty_limits(&background_thresh, &dirty_thresh);
+
+ /*
+ * Throttle it only when the background writeback cannot
+ * catch-up. This avoids (excessively) small writeouts
+ * when the bdi limits are ramping up.
+ */
+ if (nr_reclaimable + nr_writeback <
+ (background_thresh + dirty_thresh) / 2)
+ break;
+
+ bdi_thresh = bdi_dirty_limit(bdi, dirty_thresh);
+ bdi_thresh = task_dirty_limit(current, bdi_thresh);
+
/*
* In order to avoid the stacked BDI deadlock we need
* to ensure we accurately count the 'dirty' pages when
@@ -513,15 +523,6 @@ static void balance_dirty_pages(struct a
if (!dirty_exceeded)
break;
- /*
- * Throttle it only when the background writeback cannot
- * catch-up. This avoids (excessively) small writeouts
- * when the bdi limits are ramping up.
- */
- if (nr_reclaimable + nr_writeback <
- (background_thresh + dirty_thresh) / 2)
- break;
-
if (!bdi->dirty_exceeded)
bdi->dirty_exceeded = 1;
@@ -634,7 +635,7 @@ void throttle_vm_writeout(gfp_t gfp_mask
unsigned long dirty_thresh;
for ( ; ; ) {
- get_dirty_limits(&background_thresh, &dirty_thresh, NULL, NULL);
+ global_dirty_limits(&background_thresh, &dirty_thresh);
/*
* Boost the allowable dirty threshold a bit for page
--- linux-next.orig/fs/fs-writeback.c 2010-07-29 14:34:34.000000000 +0800
+++ linux-next/fs/fs-writeback.c 2010-08-03 23:11:12.000000000 +0800
@@ -594,7 +594,7 @@ static inline bool over_bground_thresh(v
{
unsigned long background_thresh, dirty_thresh;
- get_dirty_limits(&background_thresh, &dirty_thresh, NULL, NULL);
+ global_dirty_limits(&background_thresh, &dirty_thresh);
return (global_page_state(NR_FILE_DIRTY) +
global_page_state(NR_UNSTABLE_NFS) >= background_thresh);
--- linux-next.orig/mm/backing-dev.c 2010-07-29 14:34:34.000000000 +0800
+++ linux-next/mm/backing-dev.c 2010-08-03 23:11:10.000000000 +0800
@@ -83,7 +83,8 @@ static int bdi_debug_stats_show(struct s
nr_more_io++;
spin_unlock(&inode_lock);
- get_dirty_limits(&background_thresh, &dirty_thresh, &bdi_thresh, bdi);
+ global_dirty_limits(&background_thresh, &dirty_thresh);
+ bdi_thresh = bdi_dirty_limit(bdi, dirty_thresh);
#define K(x) ((x) << (PAGE_SHIFT - 10))
seq_printf(m,
--- linux-next.orig/include/linux/writeback.h 2010-07-29 14:34:34.000000000 +0800
+++ linux-next/include/linux/writeback.h 2010-08-03 23:11:10.000000000 +0800
@@ -124,8 +124,9 @@ struct ctl_table;
int dirty_writeback_centisecs_handler(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
-void get_dirty_limits(unsigned long *pbackground, unsigned long *pdirty,
- unsigned long *pbdi_dirty, struct backing_dev_info *bdi);
+void global_dirty_limits(unsigned long *pbackground, unsigned long *pdirty);
+unsigned long bdi_dirty_limit(struct backing_dev_info *bdi,
+ unsigned long dirty);
void page_writeback_init(void);
void balance_dirty_pages_ratelimited_nr(struct address_space *mapping,
next prev parent reply other threads:[~2010-08-05 16:10 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-05 16:10 [PATCH 00/13] writeback patches for 2.6.36 Wu Fengguang
2010-08-05 16:10 ` [PATCH 01/13] writeback: reduce calls to global_page_state in balance_dirty_pages() Wu Fengguang
2010-08-05 16:10 ` Wu Fengguang [this message]
2010-08-06 10:14 ` [PATCH 02/13] writeback: avoid unnecessary calculation of bdi dirty thresholds Peter Zijlstra
2010-08-05 16:10 ` [PATCH 03/13] writeback: add comment to the dirty limits functions Wu Fengguang
2010-08-06 10:17 ` Peter Zijlstra
2010-08-07 16:47 ` Wu Fengguang
2010-08-05 16:10 ` [PATCH 04/13] writeback: dont redirty tail an inode with dirty pages Wu Fengguang
2010-08-05 16:10 ` [PATCH 05/13] writeback: fix queue_io() ordering Wu Fengguang
2010-08-05 16:10 ` [PATCH 06/13] writeback: merge for_kupdate and !for_kupdate cases Wu Fengguang
2010-08-05 16:10 ` [PATCH 07/13] writeback: explicit low bound for vm.dirty_ratio Wu Fengguang
2010-08-05 23:34 ` Andrew Morton
2010-08-06 12:44 ` Wu Fengguang
2010-08-10 3:12 ` KOSAKI Motohiro
2010-08-10 3:57 ` Neil Brown
2010-08-10 13:29 ` Jan Kara
2010-08-10 18:12 ` Wu Fengguang
2010-08-10 18:06 ` Wu Fengguang
2010-08-05 16:10 ` [PATCH 08/13] writeback: pass writeback_control down to move_expired_inodes() Wu Fengguang
2010-08-05 16:11 ` [PATCH 09/13] writeback: the kupdate expire timestamp should be a moving target Wu Fengguang
2010-08-05 16:11 ` [PATCH 10/13] writeback: kill writeback_control.more_io Wu Fengguang
2010-08-05 16:11 ` [PATCH 11/13] writeback: sync expired inodes first in background writeback Wu Fengguang
2010-08-05 16:11 ` [PATCH 12/13] writeback: try more writeback as long as something was written Wu Fengguang
2010-08-05 17:00 ` Jan Kara
2010-08-05 22:39 ` Wu Fengguang
2010-08-05 22:50 ` Jan Kara
2010-08-05 16:11 ` [PATCH 13/13] writeback: introduce writeback_control.inodes_written Wu Fengguang
2010-08-05 23:08 ` [PATCH 00/13] writeback patches for 2.6.36 Andrew Morton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100805162432.963007535@intel.com \
--to=fengguang.wu@intel.com \
--cc=a.p.zijlstra@chello.nl \
--cc=akpm@linux-foundation.org \
--cc=axboe@kernel.dk \
--cc=chris.mason@oracle.com \
--cc=david@fromorbit.com \
--cc=hch@infradead.org \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mel@csn.ul.ie \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).