2005-04-16 15:20:36 -07:00
|
|
|
/*
|
2006-10-03 23:01:26 +02:00
|
|
|
* mm/page-writeback.c
|
2005-04-16 15:20:36 -07:00
|
|
|
*
|
|
|
|
* Copyright (C) 2002, Linus Torvalds.
|
2007-10-16 23:25:50 -07:00
|
|
|
* Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
|
2005-04-16 15:20:36 -07:00
|
|
|
*
|
|
|
|
* Contains functions related to writing back dirty pages at the
|
|
|
|
* address_space level.
|
|
|
|
*
|
2008-10-15 22:01:59 -07:00
|
|
|
* 10Apr2002 Andrew Morton
|
2005-04-16 15:20:36 -07:00
|
|
|
* Initial version
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/spinlock.h>
|
|
|
|
#include <linux/fs.h>
|
|
|
|
#include <linux/mm.h>
|
|
|
|
#include <linux/swap.h>
|
|
|
|
#include <linux/slab.h>
|
|
|
|
#include <linux/pagemap.h>
|
|
|
|
#include <linux/writeback.h>
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/backing-dev.h>
|
2006-12-10 02:19:27 -08:00
|
|
|
#include <linux/task_io_accounting_ops.h>
|
2005-04-16 15:20:36 -07:00
|
|
|
#include <linux/blkdev.h>
|
|
|
|
#include <linux/mpage.h>
|
2006-09-25 23:30:57 -07:00
|
|
|
#include <linux/rmap.h>
|
2005-04-16 15:20:36 -07:00
|
|
|
#include <linux/percpu.h>
|
|
|
|
#include <linux/notifier.h>
|
|
|
|
#include <linux/smp.h>
|
|
|
|
#include <linux/sysctl.h>
|
|
|
|
#include <linux/cpu.h>
|
|
|
|
#include <linux/syscalls.h>
|
2006-08-29 19:05:54 +01:00
|
|
|
#include <linux/buffer_head.h>
|
2006-08-29 19:06:09 +01:00
|
|
|
#include <linux/pagevec.h>
|
2005-04-16 15:20:36 -07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* After a CPU has dirtied this many pages, balance_dirty_pages_ratelimited
|
|
|
|
* will look to see if it needs to force writeback or throttling.
|
|
|
|
*/
|
|
|
|
static long ratelimit_pages = 32;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* When balance_dirty_pages decides that the caller needs to perform some
|
|
|
|
* non-background writeback, this is how many pages it will attempt to write.
|
2009-09-23 21:56:00 +08:00
|
|
|
* It should be somewhat larger than dirtied pages to ensure that reasonably
|
2005-04-16 15:20:36 -07:00
|
|
|
* large amounts of I/O are submitted.
|
|
|
|
*/
|
2009-09-23 21:56:00 +08:00
|
|
|
static inline long sync_writeback_pages(unsigned long dirtied)
|
2005-04-16 15:20:36 -07:00
|
|
|
{
|
2009-09-23 21:56:00 +08:00
|
|
|
if (dirtied < ratelimit_pages)
|
|
|
|
dirtied = ratelimit_pages;
|
|
|
|
|
|
|
|
return dirtied + dirtied / 2;
|
2005-04-16 15:20:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* The following parameters are exported via /proc/sys/vm */
|
|
|
|
|
|
|
|
/*
|
2009-09-23 19:37:09 +02:00
|
|
|
* Start background writeback (via writeback threads) at this percentage
|
2005-04-16 15:20:36 -07:00
|
|
|
*/
|
2009-03-23 08:57:38 +08:00
|
|
|
int dirty_background_ratio = 10;
|
2005-04-16 15:20:36 -07:00
|
|
|
|
mm: add dirty_background_bytes and dirty_bytes sysctls
This change introduces two new sysctls to /proc/sys/vm:
dirty_background_bytes and dirty_bytes.
dirty_background_bytes is the counterpart to dirty_background_ratio and
dirty_bytes is the counterpart to dirty_ratio.
With growing memory capacities of individual machines, it's no longer
sufficient to specify dirty thresholds as a percentage of the amount of
dirtyable memory over the entire system.
dirty_background_bytes and dirty_bytes specify quantities of memory, in
bytes, that represent the dirty limits for the entire system. If either
of these values is set, its value represents the amount of dirty memory
that is needed to commence either background or direct writeback.
When a `bytes' or `ratio' file is written, its counterpart becomes a
function of the written value. For example, if dirty_bytes is written to
be 8096, 8K of memory is required to commence direct writeback.
dirty_ratio is then functionally equivalent to 8K / the amount of
dirtyable memory:
dirtyable_memory = free pages + mapped pages + file cache
dirty_background_bytes = dirty_background_ratio * dirtyable_memory
-or-
dirty_background_ratio = dirty_background_bytes / dirtyable_memory
AND
dirty_bytes = dirty_ratio * dirtyable_memory
-or-
dirty_ratio = dirty_bytes / dirtyable_memory
Only one of dirty_background_bytes and dirty_background_ratio may be
specified at a time, and only one of dirty_bytes and dirty_ratio may be
specified. When one sysctl is written, the other appears as 0 when read.
The `bytes' files operate on a page size granularity since dirty limits
are compared with ZVC values, which are in page units.
Prior to this change, the minimum dirty_ratio was 5 as implemented by
get_dirty_limits() although /proc/sys/vm/dirty_ratio would show any user
written value between 0 and 100. This restriction is maintained, but
dirty_bytes has a lower limit of only one page.
Also prior to this change, the dirty_background_ratio could not equal or
exceed dirty_ratio. This restriction is maintained in addition to
restricting dirty_background_bytes. If either background threshold equals
or exceeds that of the dirty threshold, it is implicitly set to half the
dirty threshold.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: David Rientjes <rientjes@google.com>
Cc: Andrea Righi <righi.andrea@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-01-06 14:39:31 -08:00
|
|
|
/*
|
|
|
|
* dirty_background_bytes starts at 0 (disabled) so that it is a function of
|
|
|
|
* dirty_background_ratio * the amount of dirtyable memory
|
|
|
|
*/
|
|
|
|
unsigned long dirty_background_bytes;
|
|
|
|
|
2008-02-04 22:29:20 -08:00
|
|
|
/*
|
|
|
|
* free highmem will not be subtracted from the total free memory
|
|
|
|
* for calculating free ratios if vm_highmem_is_dirtyable is true
|
|
|
|
*/
|
|
|
|
int vm_highmem_is_dirtyable;
|
|
|
|
|
2005-04-16 15:20:36 -07:00
|
|
|
/*
|
|
|
|
* The generator of dirty data starts writeback at this percentage
|
|
|
|
*/
|
2009-03-23 08:57:38 +08:00
|
|
|
int vm_dirty_ratio = 20;
|
2005-04-16 15:20:36 -07:00
|
|
|
|
mm: add dirty_background_bytes and dirty_bytes sysctls
This change introduces two new sysctls to /proc/sys/vm:
dirty_background_bytes and dirty_bytes.
dirty_background_bytes is the counterpart to dirty_background_ratio and
dirty_bytes is the counterpart to dirty_ratio.
With growing memory capacities of individual machines, it's no longer
sufficient to specify dirty thresholds as a percentage of the amount of
dirtyable memory over the entire system.
dirty_background_bytes and dirty_bytes specify quantities of memory, in
bytes, that represent the dirty limits for the entire system. If either
of these values is set, its value represents the amount of dirty memory
that is needed to commence either background or direct writeback.
When a `bytes' or `ratio' file is written, its counterpart becomes a
function of the written value. For example, if dirty_bytes is written to
be 8096, 8K of memory is required to commence direct writeback.
dirty_ratio is then functionally equivalent to 8K / the amount of
dirtyable memory:
dirtyable_memory = free pages + mapped pages + file cache
dirty_background_bytes = dirty_background_ratio * dirtyable_memory
-or-
dirty_background_ratio = dirty_background_bytes / dirtyable_memory
AND
dirty_bytes = dirty_ratio * dirtyable_memory
-or-
dirty_ratio = dirty_bytes / dirtyable_memory
Only one of dirty_background_bytes and dirty_background_ratio may be
specified at a time, and only one of dirty_bytes and dirty_ratio may be
specified. When one sysctl is written, the other appears as 0 when read.
The `bytes' files operate on a page size granularity since dirty limits
are compared with ZVC values, which are in page units.
Prior to this change, the minimum dirty_ratio was 5 as implemented by
get_dirty_limits() although /proc/sys/vm/dirty_ratio would show any user
written value between 0 and 100. This restriction is maintained, but
dirty_bytes has a lower limit of only one page.
Also prior to this change, the dirty_background_ratio could not equal or
exceed dirty_ratio. This restriction is maintained in addition to
restricting dirty_background_bytes. If either background threshold equals
or exceeds that of the dirty threshold, it is implicitly set to half the
dirty threshold.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: David Rientjes <rientjes@google.com>
Cc: Andrea Righi <righi.andrea@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-01-06 14:39:31 -08:00
|
|
|
/*
|
|
|
|
* vm_dirty_bytes starts at 0 (disabled) so that it is a function of
|
|
|
|
* vm_dirty_ratio * the amount of dirtyable memory
|
|
|
|
*/
|
|
|
|
unsigned long vm_dirty_bytes;
|
|
|
|
|
2005-04-16 15:20:36 -07:00
|
|
|
/*
|
2009-03-31 15:23:18 -07:00
|
|
|
* The interval between `kupdate'-style writebacks
|
2005-04-16 15:20:36 -07:00
|
|
|
*/
|
2009-05-16 22:56:28 -07:00
|
|
|
unsigned int dirty_writeback_interval = 5 * 100; /* centiseconds */
|
2005-04-16 15:20:36 -07:00
|
|
|
|
|
|
|
/*
|
2009-03-31 15:23:18 -07:00
|
|
|
* The longest time for which data is allowed to remain dirty
|
2005-04-16 15:20:36 -07:00
|
|
|
*/
|
2009-05-16 22:56:28 -07:00
|
|
|
unsigned int dirty_expire_interval = 30 * 100; /* centiseconds */
|
2005-04-16 15:20:36 -07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Flag that makes the machine dump writes/reads and block dirtyings.
|
|
|
|
*/
|
|
|
|
int block_dump;
|
|
|
|
|
|
|
|
/*
|
2006-03-24 03:15:49 -08:00
|
|
|
* Flag that puts the machine in "laptop mode". Doubles as a timeout in jiffies:
|
|
|
|
* a full sync is triggered after this time elapses without any disk activity.
|
2005-04-16 15:20:36 -07:00
|
|
|
*/
|
|
|
|
int laptop_mode;
|
|
|
|
|
|
|
|
EXPORT_SYMBOL(laptop_mode);
|
|
|
|
|
|
|
|
/* End of sysctl-exported parameters */
|
|
|
|
|
|
|
|
|
2007-10-16 23:25:50 -07:00
|
|
|
/*
|
|
|
|
* Scale the writeback cache size proportional to the relative writeout speeds.
|
|
|
|
*
|
|
|
|
* We do this by keeping a floating proportion between BDIs, based on page
|
|
|
|
* writeback completions [end_page_writeback()]. Those devices that write out
|
|
|
|
* pages fastest will get the larger share, while the slower will get a smaller
|
|
|
|
* share.
|
|
|
|
*
|
|
|
|
* We use page writeout completions because we are interested in getting rid of
|
|
|
|
* dirty pages. Having them written out is the primary goal.
|
|
|
|
*
|
|
|
|
* We introduce a concept of time, a period over which we measure these events,
|
|
|
|
* because demand can/will vary over time. The length of this period itself is
|
|
|
|
* measured in page writeback completions.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static struct prop_descriptor vm_completions;
|
2007-10-16 23:25:50 -07:00
|
|
|
static struct prop_descriptor vm_dirties;
|
2007-10-16 23:25:50 -07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* couple the period to the dirty_ratio:
|
|
|
|
*
|
|
|
|
* period/2 ~ roundup_pow_of_two(dirty limit)
|
|
|
|
*/
|
|
|
|
static int calc_period_shift(void)
|
|
|
|
{
|
|
|
|
unsigned long dirty_total;
|
|
|
|
|
mm: add dirty_background_bytes and dirty_bytes sysctls
This change introduces two new sysctls to /proc/sys/vm:
dirty_background_bytes and dirty_bytes.
dirty_background_bytes is the counterpart to dirty_background_ratio and
dirty_bytes is the counterpart to dirty_ratio.
With growing memory capacities of individual machines, it's no longer
sufficient to specify dirty thresholds as a percentage of the amount of
dirtyable memory over the entire system.
dirty_background_bytes and dirty_bytes specify quantities of memory, in
bytes, that represent the dirty limits for the entire system. If either
of these values is set, its value represents the amount of dirty memory
that is needed to commence either background or direct writeback.
When a `bytes' or `ratio' file is written, its counterpart becomes a
function of the written value. For example, if dirty_bytes is written to
be 8096, 8K of memory is required to commence direct writeback.
dirty_ratio is then functionally equivalent to 8K / the amount of
dirtyable memory:
dirtyable_memory = free pages + mapped pages + file cache
dirty_background_bytes = dirty_background_ratio * dirtyable_memory
-or-
dirty_background_ratio = dirty_background_bytes / dirtyable_memory
AND
dirty_bytes = dirty_ratio * dirtyable_memory
-or-
dirty_ratio = dirty_bytes / dirtyable_memory
Only one of dirty_background_bytes and dirty_background_ratio may be
specified at a time, and only one of dirty_bytes and dirty_ratio may be
specified. When one sysctl is written, the other appears as 0 when read.
The `bytes' files operate on a page size granularity since dirty limits
are compared with ZVC values, which are in page units.
Prior to this change, the minimum dirty_ratio was 5 as implemented by
get_dirty_limits() although /proc/sys/vm/dirty_ratio would show any user
written value between 0 and 100. This restriction is maintained, but
dirty_bytes has a lower limit of only one page.
Also prior to this change, the dirty_background_ratio could not equal or
exceed dirty_ratio. This restriction is maintained in addition to
restricting dirty_background_bytes. If either background threshold equals
or exceeds that of the dirty threshold, it is implicitly set to half the
dirty threshold.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: David Rientjes <rientjes@google.com>
Cc: Andrea Righi <righi.andrea@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-01-06 14:39:31 -08:00
|
|
|
if (vm_dirty_bytes)
|
|
|
|
dirty_total = vm_dirty_bytes / PAGE_SIZE;
|
|
|
|
else
|
|
|
|
dirty_total = (vm_dirty_ratio * determine_dirtyable_memory()) /
|
|
|
|
100;
|
2007-10-16 23:25:50 -07:00
|
|
|
return 2 + ilog2(dirty_total - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
mm: add dirty_background_bytes and dirty_bytes sysctls
This change introduces two new sysctls to /proc/sys/vm:
dirty_background_bytes and dirty_bytes.
dirty_background_bytes is the counterpart to dirty_background_ratio and
dirty_bytes is the counterpart to dirty_ratio.
With growing memory capacities of individual machines, it's no longer
sufficient to specify dirty thresholds as a percentage of the amount of
dirtyable memory over the entire system.
dirty_background_bytes and dirty_bytes specify quantities of memory, in
bytes, that represent the dirty limits for the entire system. If either
of these values is set, its value represents the amount of dirty memory
that is needed to commence either background or direct writeback.
When a `bytes' or `ratio' file is written, its counterpart becomes a
function of the written value. For example, if dirty_bytes is written to
be 8096, 8K of memory is required to commence direct writeback.
dirty_ratio is then functionally equivalent to 8K / the amount of
dirtyable memory:
dirtyable_memory = free pages + mapped pages + file cache
dirty_background_bytes = dirty_background_ratio * dirtyable_memory
-or-
dirty_background_ratio = dirty_background_bytes / dirtyable_memory
AND
dirty_bytes = dirty_ratio * dirtyable_memory
-or-
dirty_ratio = dirty_bytes / dirtyable_memory
Only one of dirty_background_bytes and dirty_background_ratio may be
specified at a time, and only one of dirty_bytes and dirty_ratio may be
specified. When one sysctl is written, the other appears as 0 when read.
The `bytes' files operate on a page size granularity since dirty limits
are compared with ZVC values, which are in page units.
Prior to this change, the minimum dirty_ratio was 5 as implemented by
get_dirty_limits() although /proc/sys/vm/dirty_ratio would show any user
written value between 0 and 100. This restriction is maintained, but
dirty_bytes has a lower limit of only one page.
Also prior to this change, the dirty_background_ratio could not equal or
exceed dirty_ratio. This restriction is maintained in addition to
restricting dirty_background_bytes. If either background threshold equals
or exceeds that of the dirty threshold, it is implicitly set to half the
dirty threshold.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: David Rientjes <rientjes@google.com>
Cc: Andrea Righi <righi.andrea@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-01-06 14:39:31 -08:00
|
|
|
* update the period when the dirty threshold changes.
|
2007-10-16 23:25:50 -07:00
|
|
|
*/
|
mm: add dirty_background_bytes and dirty_bytes sysctls
This change introduces two new sysctls to /proc/sys/vm:
dirty_background_bytes and dirty_bytes.
dirty_background_bytes is the counterpart to dirty_background_ratio and
dirty_bytes is the counterpart to dirty_ratio.
With growing memory capacities of individual machines, it's no longer
sufficient to specify dirty thresholds as a percentage of the amount of
dirtyable memory over the entire system.
dirty_background_bytes and dirty_bytes specify quantities of memory, in
bytes, that represent the dirty limits for the entire system. If either
of these values is set, its value represents the amount of dirty memory
that is needed to commence either background or direct writeback.
When a `bytes' or `ratio' file is written, its counterpart becomes a
function of the written value. For example, if dirty_bytes is written to
be 8096, 8K of memory is required to commence direct writeback.
dirty_ratio is then functionally equivalent to 8K / the amount of
dirtyable memory:
dirtyable_memory = free pages + mapped pages + file cache
dirty_background_bytes = dirty_background_ratio * dirtyable_memory
-or-
dirty_background_ratio = dirty_background_bytes / dirtyable_memory
AND
dirty_bytes = dirty_ratio * dirtyable_memory
-or-
dirty_ratio = dirty_bytes / dirtyable_memory
Only one of dirty_background_bytes and dirty_background_ratio may be
specified at a time, and only one of dirty_bytes and dirty_ratio may be
specified. When one sysctl is written, the other appears as 0 when read.
The `bytes' files operate on a page size granularity since dirty limits
are compared with ZVC values, which are in page units.
Prior to this change, the minimum dirty_ratio was 5 as implemented by
get_dirty_limits() although /proc/sys/vm/dirty_ratio would show any user
written value between 0 and 100. This restriction is maintained, but
dirty_bytes has a lower limit of only one page.
Also prior to this change, the dirty_background_ratio could not equal or
exceed dirty_ratio. This restriction is maintained in addition to
restricting dirty_background_bytes. If either background threshold equals
or exceeds that of the dirty threshold, it is implicitly set to half the
dirty threshold.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: David Rientjes <rientjes@google.com>
Cc: Andrea Righi <righi.andrea@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-01-06 14:39:31 -08:00
|
|
|
static void update_completion_period(void)
|
|
|
|
{
|
|
|
|
int shift = calc_period_shift();
|
|
|
|
prop_change_shift(&vm_completions, shift);
|
|
|
|
prop_change_shift(&vm_dirties, shift);
|
|
|
|
}
|
|
|
|
|
|
|
|
int dirty_background_ratio_handler(struct ctl_table *table, int write,
|
2009-09-23 15:57:19 -07:00
|
|
|
void __user *buffer, size_t *lenp,
|
mm: add dirty_background_bytes and dirty_bytes sysctls
This change introduces two new sysctls to /proc/sys/vm:
dirty_background_bytes and dirty_bytes.
dirty_background_bytes is the counterpart to dirty_background_ratio and
dirty_bytes is the counterpart to dirty_ratio.
With growing memory capacities of individual machines, it's no longer
sufficient to specify dirty thresholds as a percentage of the amount of
dirtyable memory over the entire system.
dirty_background_bytes and dirty_bytes specify quantities of memory, in
bytes, that represent the dirty limits for the entire system. If either
of these values is set, its value represents the amount of dirty memory
that is needed to commence either background or direct writeback.
When a `bytes' or `ratio' file is written, its counterpart becomes a
function of the written value. For example, if dirty_bytes is written to
be 8096, 8K of memory is required to commence direct writeback.
dirty_ratio is then functionally equivalent to 8K / the amount of
dirtyable memory:
dirtyable_memory = free pages + mapped pages + file cache
dirty_background_bytes = dirty_background_ratio * dirtyable_memory
-or-
dirty_background_ratio = dirty_background_bytes / dirtyable_memory
AND
dirty_bytes = dirty_ratio * dirtyable_memory
-or-
dirty_ratio = dirty_bytes / dirtyable_memory
Only one of dirty_background_bytes and dirty_background_ratio may be
specified at a time, and only one of dirty_bytes and dirty_ratio may be
specified. When one sysctl is written, the other appears as 0 when read.
The `bytes' files operate on a page size granularity since dirty limits
are compared with ZVC values, which are in page units.
Prior to this change, the minimum dirty_ratio was 5 as implemented by
get_dirty_limits() although /proc/sys/vm/dirty_ratio would show any user
written value between 0 and 100. This restriction is maintained, but
dirty_bytes has a lower limit of only one page.
Also prior to this change, the dirty_background_ratio could not equal or
exceed dirty_ratio. This restriction is maintained in addition to
restricting dirty_background_bytes. If either background threshold equals
or exceeds that of the dirty threshold, it is implicitly set to half the
dirty threshold.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: David Rientjes <rientjes@google.com>
Cc: Andrea Righi <righi.andrea@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-01-06 14:39:31 -08:00
|
|
|
loff_t *ppos)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2009-09-23 15:57:19 -07:00
|
|
|
ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
|
mm: add dirty_background_bytes and dirty_bytes sysctls
This change introduces two new sysctls to /proc/sys/vm:
dirty_background_bytes and dirty_bytes.
dirty_background_bytes is the counterpart to dirty_background_ratio and
dirty_bytes is the counterpart to dirty_ratio.
With growing memory capacities of individual machines, it's no longer
sufficient to specify dirty thresholds as a percentage of the amount of
dirtyable memory over the entire system.
dirty_background_bytes and dirty_bytes specify quantities of memory, in
bytes, that represent the dirty limits for the entire system. If either
of these values is set, its value represents the amount of dirty memory
that is needed to commence either background or direct writeback.
When a `bytes' or `ratio' file is written, its counterpart becomes a
function of the written value. For example, if dirty_bytes is written to
be 8096, 8K of memory is required to commence direct writeback.
dirty_ratio is then functionally equivalent to 8K / the amount of
dirtyable memory:
dirtyable_memory = free pages + mapped pages + file cache
dirty_background_bytes = dirty_background_ratio * dirtyable_memory
-or-
dirty_background_ratio = dirty_background_bytes / dirtyable_memory
AND
dirty_bytes = dirty_ratio * dirtyable_memory
-or-
dirty_ratio = dirty_bytes / dirtyable_memory
Only one of dirty_background_bytes and dirty_background_ratio may be
specified at a time, and only one of dirty_bytes and dirty_ratio may be
specified. When one sysctl is written, the other appears as 0 when read.
The `bytes' files operate on a page size granularity since dirty limits
are compared with ZVC values, which are in page units.
Prior to this change, the minimum dirty_ratio was 5 as implemented by
get_dirty_limits() although /proc/sys/vm/dirty_ratio would show any user
written value between 0 and 100. This restriction is maintained, but
dirty_bytes has a lower limit of only one page.
Also prior to this change, the dirty_background_ratio could not equal or
exceed dirty_ratio. This restriction is maintained in addition to
restricting dirty_background_bytes. If either background threshold equals
or exceeds that of the dirty threshold, it is implicitly set to half the
dirty threshold.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: David Rientjes <rientjes@google.com>
Cc: Andrea Righi <righi.andrea@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-01-06 14:39:31 -08:00
|
|
|
if (ret == 0 && write)
|
|
|
|
dirty_background_bytes = 0;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int dirty_background_bytes_handler(struct ctl_table *table, int write,
|
2009-09-23 15:57:19 -07:00
|
|
|
void __user *buffer, size_t *lenp,
|
mm: add dirty_background_bytes and dirty_bytes sysctls
This change introduces two new sysctls to /proc/sys/vm:
dirty_background_bytes and dirty_bytes.
dirty_background_bytes is the counterpart to dirty_background_ratio and
dirty_bytes is the counterpart to dirty_ratio.
With growing memory capacities of individual machines, it's no longer
sufficient to specify dirty thresholds as a percentage of the amount of
dirtyable memory over the entire system.
dirty_background_bytes and dirty_bytes specify quantities of memory, in
bytes, that represent the dirty limits for the entire system. If either
of these values is set, its value represents the amount of dirty memory
that is needed to commence either background or direct writeback.
When a `bytes' or `ratio' file is written, its counterpart becomes a
function of the written value. For example, if dirty_bytes is written to
be 8096, 8K of memory is required to commence direct writeback.
dirty_ratio is then functionally equivalent to 8K / the amount of
dirtyable memory:
dirtyable_memory = free pages + mapped pages + file cache
dirty_background_bytes = dirty_background_ratio * dirtyable_memory
-or-
dirty_background_ratio = dirty_background_bytes / dirtyable_memory
AND
dirty_bytes = dirty_ratio * dirtyable_memory
-or-
dirty_ratio = dirty_bytes / dirtyable_memory
Only one of dirty_background_bytes and dirty_background_ratio may be
specified at a time, and only one of dirty_bytes and dirty_ratio may be
specified. When one sysctl is written, the other appears as 0 when read.
The `bytes' files operate on a page size granularity since dirty limits
are compared with ZVC values, which are in page units.
Prior to this change, the minimum dirty_ratio was 5 as implemented by
get_dirty_limits() although /proc/sys/vm/dirty_ratio would show any user
written value between 0 and 100. This restriction is maintained, but
dirty_bytes has a lower limit of only one page.
Also prior to this change, the dirty_background_ratio could not equal or
exceed dirty_ratio. This restriction is maintained in addition to
restricting dirty_background_bytes. If either background threshold equals
or exceeds that of the dirty threshold, it is implicitly set to half the
dirty threshold.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: David Rientjes <rientjes@google.com>
Cc: Andrea Righi <righi.andrea@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-01-06 14:39:31 -08:00
|
|
|
loff_t *ppos)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2009-09-23 15:57:19 -07:00
|
|
|
ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
|
mm: add dirty_background_bytes and dirty_bytes sysctls
This change introduces two new sysctls to /proc/sys/vm:
dirty_background_bytes and dirty_bytes.
dirty_background_bytes is the counterpart to dirty_background_ratio and
dirty_bytes is the counterpart to dirty_ratio.
With growing memory capacities of individual machines, it's no longer
sufficient to specify dirty thresholds as a percentage of the amount of
dirtyable memory over the entire system.
dirty_background_bytes and dirty_bytes specify quantities of memory, in
bytes, that represent the dirty limits for the entire system. If either
of these values is set, its value represents the amount of dirty memory
that is needed to commence either background or direct writeback.
When a `bytes' or `ratio' file is written, its counterpart becomes a
function of the written value. For example, if dirty_bytes is written to
be 8096, 8K of memory is required to commence direct writeback.
dirty_ratio is then functionally equivalent to 8K / the amount of
dirtyable memory:
dirtyable_memory = free pages + mapped pages + file cache
dirty_background_bytes = dirty_background_ratio * dirtyable_memory
-or-
dirty_background_ratio = dirty_background_bytes / dirtyable_memory
AND
dirty_bytes = dirty_ratio * dirtyable_memory
-or-
dirty_ratio = dirty_bytes / dirtyable_memory
Only one of dirty_background_bytes and dirty_background_ratio may be
specified at a time, and only one of dirty_bytes and dirty_ratio may be
specified. When one sysctl is written, the other appears as 0 when read.
The `bytes' files operate on a page size granularity since dirty limits
are compared with ZVC values, which are in page units.
Prior to this change, the minimum dirty_ratio was 5 as implemented by
get_dirty_limits() although /proc/sys/vm/dirty_ratio would show any user
written value between 0 and 100. This restriction is maintained, but
dirty_bytes has a lower limit of only one page.
Also prior to this change, the dirty_background_ratio could not equal or
exceed dirty_ratio. This restriction is maintained in addition to
restricting dirty_background_bytes. If either background threshold equals
or exceeds that of the dirty threshold, it is implicitly set to half the
dirty threshold.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: David Rientjes <rientjes@google.com>
Cc: Andrea Righi <righi.andrea@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-01-06 14:39:31 -08:00
|
|
|
if (ret == 0 && write)
|
|
|
|
dirty_background_ratio = 0;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2007-10-16 23:25:50 -07:00
|
|
|
int dirty_ratio_handler(struct ctl_table *table, int write,
|
2009-09-23 15:57:19 -07:00
|
|
|
void __user *buffer, size_t *lenp,
|
2007-10-16 23:25:50 -07:00
|
|
|
loff_t *ppos)
|
|
|
|
{
|
|
|
|
int old_ratio = vm_dirty_ratio;
|
mm: add dirty_background_bytes and dirty_bytes sysctls
This change introduces two new sysctls to /proc/sys/vm:
dirty_background_bytes and dirty_bytes.
dirty_background_bytes is the counterpart to dirty_background_ratio and
dirty_bytes is the counterpart to dirty_ratio.
With growing memory capacities of individual machines, it's no longer
sufficient to specify dirty thresholds as a percentage of the amount of
dirtyable memory over the entire system.
dirty_background_bytes and dirty_bytes specify quantities of memory, in
bytes, that represent the dirty limits for the entire system. If either
of these values is set, its value represents the amount of dirty memory
that is needed to commence either background or direct writeback.
When a `bytes' or `ratio' file is written, its counterpart becomes a
function of the written value. For example, if dirty_bytes is written to
be 8096, 8K of memory is required to commence direct writeback.
dirty_ratio is then functionally equivalent to 8K / the amount of
dirtyable memory:
dirtyable_memory = free pages + mapped pages + file cache
dirty_background_bytes = dirty_background_ratio * dirtyable_memory
-or-
dirty_background_ratio = dirty_background_bytes / dirtyable_memory
AND
dirty_bytes = dirty_ratio * dirtyable_memory
-or-
dirty_ratio = dirty_bytes / dirtyable_memory
Only one of dirty_background_bytes and dirty_background_ratio may be
specified at a time, and only one of dirty_bytes and dirty_ratio may be
specified. When one sysctl is written, the other appears as 0 when read.
The `bytes' files operate on a page size granularity since dirty limits
are compared with ZVC values, which are in page units.
Prior to this change, the minimum dirty_ratio was 5 as implemented by
get_dirty_limits() although /proc/sys/vm/dirty_ratio would show any user
written value between 0 and 100. This restriction is maintained, but
dirty_bytes has a lower limit of only one page.
Also prior to this change, the dirty_background_ratio could not equal or
exceed dirty_ratio. This restriction is maintained in addition to
restricting dirty_background_bytes. If either background threshold equals
or exceeds that of the dirty threshold, it is implicitly set to half the
dirty threshold.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: David Rientjes <rientjes@google.com>
Cc: Andrea Righi <righi.andrea@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-01-06 14:39:31 -08:00
|
|
|
int ret;
|
|
|
|
|
2009-09-23 15:57:19 -07:00
|
|
|
ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
|
2007-10-16 23:25:50 -07:00
|
|
|
if (ret == 0 && write && vm_dirty_ratio != old_ratio) {
|
mm: add dirty_background_bytes and dirty_bytes sysctls
This change introduces two new sysctls to /proc/sys/vm:
dirty_background_bytes and dirty_bytes.
dirty_background_bytes is the counterpart to dirty_background_ratio and
dirty_bytes is the counterpart to dirty_ratio.
With growing memory capacities of individual machines, it's no longer
sufficient to specify dirty thresholds as a percentage of the amount of
dirtyable memory over the entire system.
dirty_background_bytes and dirty_bytes specify quantities of memory, in
bytes, that represent the dirty limits for the entire system. If either
of these values is set, its value represents the amount of dirty memory
that is needed to commence either background or direct writeback.
When a `bytes' or `ratio' file is written, its counterpart becomes a
function of the written value. For example, if dirty_bytes is written to
be 8096, 8K of memory is required to commence direct writeback.
dirty_ratio is then functionally equivalent to 8K / the amount of
dirtyable memory:
dirtyable_memory = free pages + mapped pages + file cache
dirty_background_bytes = dirty_background_ratio * dirtyable_memory
-or-
dirty_background_ratio = dirty_background_bytes / dirtyable_memory
AND
dirty_bytes = dirty_ratio * dirtyable_memory
-or-
dirty_ratio = dirty_bytes / dirtyable_memory
Only one of dirty_background_bytes and dirty_background_ratio may be
specified at a time, and only one of dirty_bytes and dirty_ratio may be
specified. When one sysctl is written, the other appears as 0 when read.
The `bytes' files operate on a page size granularity since dirty limits
are compared with ZVC values, which are in page units.
Prior to this change, the minimum dirty_ratio was 5 as implemented by
get_dirty_limits() although /proc/sys/vm/dirty_ratio would show any user
written value between 0 and 100. This restriction is maintained, but
dirty_bytes has a lower limit of only one page.
Also prior to this change, the dirty_background_ratio could not equal or
exceed dirty_ratio. This restriction is maintained in addition to
restricting dirty_background_bytes. If either background threshold equals
or exceeds that of the dirty threshold, it is implicitly set to half the
dirty threshold.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: David Rientjes <rientjes@google.com>
Cc: Andrea Righi <righi.andrea@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-01-06 14:39:31 -08:00
|
|
|
update_completion_period();
|
|
|
|
vm_dirty_bytes = 0;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int dirty_bytes_handler(struct ctl_table *table, int write,
|
2009-09-23 15:57:19 -07:00
|
|
|
void __user *buffer, size_t *lenp,
|
mm: add dirty_background_bytes and dirty_bytes sysctls
This change introduces two new sysctls to /proc/sys/vm:
dirty_background_bytes and dirty_bytes.
dirty_background_bytes is the counterpart to dirty_background_ratio and
dirty_bytes is the counterpart to dirty_ratio.
With growing memory capacities of individual machines, it's no longer
sufficient to specify dirty thresholds as a percentage of the amount of
dirtyable memory over the entire system.
dirty_background_bytes and dirty_bytes specify quantities of memory, in
bytes, that represent the dirty limits for the entire system. If either
of these values is set, its value represents the amount of dirty memory
that is needed to commence either background or direct writeback.
When a `bytes' or `ratio' file is written, its counterpart becomes a
function of the written value. For example, if dirty_bytes is written to
be 8096, 8K of memory is required to commence direct writeback.
dirty_ratio is then functionally equivalent to 8K / the amount of
dirtyable memory:
dirtyable_memory = free pages + mapped pages + file cache
dirty_background_bytes = dirty_background_ratio * dirtyable_memory
-or-
dirty_background_ratio = dirty_background_bytes / dirtyable_memory
AND
dirty_bytes = dirty_ratio * dirtyable_memory
-or-
dirty_ratio = dirty_bytes / dirtyable_memory
Only one of dirty_background_bytes and dirty_background_ratio may be
specified at a time, and only one of dirty_bytes and dirty_ratio may be
specified. When one sysctl is written, the other appears as 0 when read.
The `bytes' files operate on a page size granularity since dirty limits
are compared with ZVC values, which are in page units.
Prior to this change, the minimum dirty_ratio was 5 as implemented by
get_dirty_limits() although /proc/sys/vm/dirty_ratio would show any user
written value between 0 and 100. This restriction is maintained, but
dirty_bytes has a lower limit of only one page.
Also prior to this change, the dirty_background_ratio could not equal or
exceed dirty_ratio. This restriction is maintained in addition to
restricting dirty_background_bytes. If either background threshold equals
or exceeds that of the dirty threshold, it is implicitly set to half the
dirty threshold.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: David Rientjes <rientjes@google.com>
Cc: Andrea Righi <righi.andrea@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-01-06 14:39:31 -08:00
|
|
|
loff_t *ppos)
|
|
|
|
{
|
2009-02-11 13:04:23 -08:00
|
|
|
unsigned long old_bytes = vm_dirty_bytes;
|
mm: add dirty_background_bytes and dirty_bytes sysctls
This change introduces two new sysctls to /proc/sys/vm:
dirty_background_bytes and dirty_bytes.
dirty_background_bytes is the counterpart to dirty_background_ratio and
dirty_bytes is the counterpart to dirty_ratio.
With growing memory capacities of individual machines, it's no longer
sufficient to specify dirty thresholds as a percentage of the amount of
dirtyable memory over the entire system.
dirty_background_bytes and dirty_bytes specify quantities of memory, in
bytes, that represent the dirty limits for the entire system. If either
of these values is set, its value represents the amount of dirty memory
that is needed to commence either background or direct writeback.
When a `bytes' or `ratio' file is written, its counterpart becomes a
function of the written value. For example, if dirty_bytes is written to
be 8096, 8K of memory is required to commence direct writeback.
dirty_ratio is then functionally equivalent to 8K / the amount of
dirtyable memory:
dirtyable_memory = free pages + mapped pages + file cache
dirty_background_bytes = dirty_background_ratio * dirtyable_memory
-or-
dirty_background_ratio = dirty_background_bytes / dirtyable_memory
AND
dirty_bytes = dirty_ratio * dirtyable_memory
-or-
dirty_ratio = dirty_bytes / dirtyable_memory
Only one of dirty_background_bytes and dirty_background_ratio may be
specified at a time, and only one of dirty_bytes and dirty_ratio may be
specified. When one sysctl is written, the other appears as 0 when read.
The `bytes' files operate on a page size granularity since dirty limits
are compared with ZVC values, which are in page units.
Prior to this change, the minimum dirty_ratio was 5 as implemented by
get_dirty_limits() although /proc/sys/vm/dirty_ratio would show any user
written value between 0 and 100. This restriction is maintained, but
dirty_bytes has a lower limit of only one page.
Also prior to this change, the dirty_background_ratio could not equal or
exceed dirty_ratio. This restriction is maintained in addition to
restricting dirty_background_bytes. If either background threshold equals
or exceeds that of the dirty threshold, it is implicitly set to half the
dirty threshold.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: David Rientjes <rientjes@google.com>
Cc: Andrea Righi <righi.andrea@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-01-06 14:39:31 -08:00
|
|
|
int ret;
|
|
|
|
|
2009-09-23 15:57:19 -07:00
|
|
|
ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
|
mm: add dirty_background_bytes and dirty_bytes sysctls
This change introduces two new sysctls to /proc/sys/vm:
dirty_background_bytes and dirty_bytes.
dirty_background_bytes is the counterpart to dirty_background_ratio and
dirty_bytes is the counterpart to dirty_ratio.
With growing memory capacities of individual machines, it's no longer
sufficient to specify dirty thresholds as a percentage of the amount of
dirtyable memory over the entire system.
dirty_background_bytes and dirty_bytes specify quantities of memory, in
bytes, that represent the dirty limits for the entire system. If either
of these values is set, its value represents the amount of dirty memory
that is needed to commence either background or direct writeback.
When a `bytes' or `ratio' file is written, its counterpart becomes a
function of the written value. For example, if dirty_bytes is written to
be 8096, 8K of memory is required to commence direct writeback.
dirty_ratio is then functionally equivalent to 8K / the amount of
dirtyable memory:
dirtyable_memory = free pages + mapped pages + file cache
dirty_background_bytes = dirty_background_ratio * dirtyable_memory
-or-
dirty_background_ratio = dirty_background_bytes / dirtyable_memory
AND
dirty_bytes = dirty_ratio * dirtyable_memory
-or-
dirty_ratio = dirty_bytes / dirtyable_memory
Only one of dirty_background_bytes and dirty_background_ratio may be
specified at a time, and only one of dirty_bytes and dirty_ratio may be
specified. When one sysctl is written, the other appears as 0 when read.
The `bytes' files operate on a page size granularity since dirty limits
are compared with ZVC values, which are in page units.
Prior to this change, the minimum dirty_ratio was 5 as implemented by
get_dirty_limits() although /proc/sys/vm/dirty_ratio would show any user
written value between 0 and 100. This restriction is maintained, but
dirty_bytes has a lower limit of only one page.
Also prior to this change, the dirty_background_ratio could not equal or
exceed dirty_ratio. This restriction is maintained in addition to
restricting dirty_background_bytes. If either background threshold equals
or exceeds that of the dirty threshold, it is implicitly set to half the
dirty threshold.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: David Rientjes <rientjes@google.com>
Cc: Andrea Righi <righi.andrea@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-01-06 14:39:31 -08:00
|
|
|
if (ret == 0 && write && vm_dirty_bytes != old_bytes) {
|
|
|
|
update_completion_period();
|
|
|
|
vm_dirty_ratio = 0;
|
2007-10-16 23:25:50 -07:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Increment the BDI's writeout completion count and the global writeout
|
|
|
|
* completion count. Called from test_clear_page_writeback().
|
|
|
|
*/
|
|
|
|
static inline void __bdi_writeout_inc(struct backing_dev_info *bdi)
|
|
|
|
{
|
2008-04-30 00:54:36 -07:00
|
|
|
__prop_inc_percpu_max(&vm_completions, &bdi->completions,
|
|
|
|
bdi->max_prop_frac);
|
2007-10-16 23:25:50 -07:00
|
|
|
}
|
|
|
|
|
2008-04-30 00:54:37 -07:00
|
|
|
void bdi_writeout_inc(struct backing_dev_info *bdi)
|
|
|
|
{
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
local_irq_save(flags);
|
|
|
|
__bdi_writeout_inc(bdi);
|
|
|
|
local_irq_restore(flags);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(bdi_writeout_inc);
|
|
|
|
|
2009-02-18 14:48:18 -08:00
|
|
|
void task_dirty_inc(struct task_struct *tsk)
|
2007-10-16 23:25:50 -07:00
|
|
|
{
|
|
|
|
prop_inc_single(&vm_dirties, &tsk->dirties);
|
|
|
|
}
|
|
|
|
|
2007-10-16 23:25:50 -07:00
|
|
|
/*
|
|
|
|
* Obtain an accurate fraction of the BDI's portion.
|
|
|
|
*/
|
|
|
|
static void bdi_writeout_fraction(struct backing_dev_info *bdi,
|
|
|
|
long *numerator, long *denominator)
|
|
|
|
{
|
|
|
|
if (bdi_cap_writeback_dirty(bdi)) {
|
|
|
|
prop_fraction_percpu(&vm_completions, &bdi->completions,
|
|
|
|
numerator, denominator);
|
|
|
|
} else {
|
|
|
|
*numerator = 0;
|
|
|
|
*denominator = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Clip the earned share of dirty pages to that which is actually available.
|
|
|
|
* This avoids exceeding the total dirty_limit when the floating averages
|
|
|
|
* fluctuate too quickly.
|
|
|
|
*/
|
2009-06-16 15:31:44 -07:00
|
|
|
static void clip_bdi_dirty_limit(struct backing_dev_info *bdi,
|
|
|
|
unsigned long dirty, unsigned long *pbdi_dirty)
|
2007-10-16 23:25:50 -07:00
|
|
|
{
|
2009-06-16 15:31:44 -07:00
|
|
|
unsigned long avail_dirty;
|
2007-10-16 23:25:50 -07:00
|
|
|
|
2009-06-16 15:31:44 -07:00
|
|
|
avail_dirty = global_page_state(NR_FILE_DIRTY) +
|
2007-10-16 23:25:50 -07:00
|
|
|
global_page_state(NR_WRITEBACK) +
|
2008-04-30 00:54:38 -07:00
|
|
|
global_page_state(NR_UNSTABLE_NFS) +
|
2009-06-16 15:31:44 -07:00
|
|
|
global_page_state(NR_WRITEBACK_TEMP);
|
2007-10-16 23:25:50 -07:00
|
|
|
|
2009-06-16 15:31:44 -07:00
|
|
|
if (avail_dirty < dirty)
|
|
|
|
avail_dirty = dirty - avail_dirty;
|
|
|
|
else
|
2007-10-16 23:25:50 -07:00
|
|
|
avail_dirty = 0;
|
|
|
|
|
|
|
|
avail_dirty += bdi_stat(bdi, BDI_RECLAIMABLE) +
|
|
|
|
bdi_stat(bdi, BDI_WRITEBACK);
|
|
|
|
|
|
|
|
*pbdi_dirty = min(*pbdi_dirty, avail_dirty);
|
|
|
|
}
|
|
|
|
|
2007-10-16 23:25:50 -07:00
|
|
|
static inline void task_dirties_fraction(struct task_struct *tsk,
|
|
|
|
long *numerator, long *denominator)
|
|
|
|
{
|
|
|
|
prop_fraction_single(&vm_dirties, &tsk->dirties,
|
|
|
|
numerator, denominator);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* scale the dirty limit
|
|
|
|
*
|
|
|
|
* task specific dirty limit:
|
|
|
|
*
|
|
|
|
* dirty -= (dirty/8) * p_{t}
|
|
|
|
*/
|
2009-06-16 15:31:44 -07:00
|
|
|
static void task_dirty_limit(struct task_struct *tsk, unsigned long *pdirty)
|
2007-10-16 23:25:50 -07:00
|
|
|
{
|
|
|
|
long numerator, denominator;
|
2009-06-16 15:31:44 -07:00
|
|
|
unsigned long dirty = *pdirty;
|
2007-10-16 23:25:50 -07:00
|
|
|
u64 inv = dirty >> 3;
|
|
|
|
|
|
|
|
task_dirties_fraction(tsk, &numerator, &denominator);
|
|
|
|
inv *= numerator;
|
|
|
|
do_div(inv, denominator);
|
|
|
|
|
|
|
|
dirty -= inv;
|
|
|
|
if (dirty < *pdirty/2)
|
|
|
|
dirty = *pdirty/2;
|
|
|
|
|
|
|
|
*pdirty = dirty;
|
|
|
|
}
|
|
|
|
|
2008-04-30 00:54:35 -07:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static unsigned int bdi_min_ratio;
|
|
|
|
|
|
|
|
int bdi_set_min_ratio(struct backing_dev_info *bdi, unsigned int min_ratio)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
|
2009-09-14 13:12:40 +02:00
|
|
|
spin_lock_bh(&bdi_lock);
|
2008-04-30 00:54:36 -07:00
|
|
|
if (min_ratio > bdi->max_ratio) {
|
2008-04-30 00:54:35 -07:00
|
|
|
ret = -EINVAL;
|
2008-04-30 00:54:36 -07:00
|
|
|
} else {
|
|
|
|
min_ratio -= bdi->min_ratio;
|
|
|
|
if (bdi_min_ratio + min_ratio < 100) {
|
|
|
|
bdi_min_ratio += min_ratio;
|
|
|
|
bdi->min_ratio += min_ratio;
|
|
|
|
} else {
|
|
|
|
ret = -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
2009-09-14 13:12:40 +02:00
|
|
|
spin_unlock_bh(&bdi_lock);
|
2008-04-30 00:54:36 -07:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned max_ratio)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
if (max_ratio > 100)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2009-09-14 13:12:40 +02:00
|
|
|
spin_lock_bh(&bdi_lock);
|
2008-04-30 00:54:36 -07:00
|
|
|
if (bdi->min_ratio > max_ratio) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
} else {
|
|
|
|
bdi->max_ratio = max_ratio;
|
|
|
|
bdi->max_prop_frac = (PROP_FRAC_BASE * max_ratio) / 100;
|
|
|
|
}
|
2009-09-14 13:12:40 +02:00
|
|
|
spin_unlock_bh(&bdi_lock);
|
2008-04-30 00:54:35 -07:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2008-04-30 00:54:36 -07:00
|
|
|
EXPORT_SYMBOL(bdi_set_max_ratio);
|
2008-04-30 00:54:35 -07:00
|
|
|
|
2005-04-16 15:20:36 -07:00
|
|
|
/*
|
|
|
|
* Work out the current dirty-memory clamping and background writeout
|
|
|
|
* thresholds.
|
|
|
|
*
|
|
|
|
* The main aim here is to lower them aggressively if there is a lot of mapped
|
|
|
|
* memory around. To avoid stressing page reclaim with lots of unreclaimable
|
|
|
|
* pages. It is better to clamp down on writers than to start swapping, and
|
|
|
|
* performing lots of scanning.
|
|
|
|
*
|
|
|
|
* We only allow 1/2 of the currently-unmapped memory to be dirtied.
|
|
|
|
*
|
|
|
|
* We don't permit the clamping level to fall below 5% - that is getting rather
|
|
|
|
* excessive.
|
|
|
|
*
|
|
|
|
* We make sure that the background writeout level is below the adjusted
|
|
|
|
* clamping level.
|
|
|
|
*/
|
2007-05-06 14:48:59 -07:00
|
|
|
|
|
|
|
static unsigned long highmem_dirtyable_memory(unsigned long total)
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_HIGHMEM
|
|
|
|
int node;
|
|
|
|
unsigned long x = 0;
|
|
|
|
|
2007-10-16 01:25:39 -07:00
|
|
|
for_each_node_state(node, N_HIGH_MEMORY) {
|
2007-05-06 14:48:59 -07:00
|
|
|
struct zone *z =
|
|
|
|
&NODE_DATA(node)->node_zones[ZONE_HIGHMEM];
|
|
|
|
|
2009-09-21 17:01:42 -07:00
|
|
|
x += zone_page_state(z, NR_FREE_PAGES) +
|
|
|
|
zone_reclaimable_pages(z);
|
2007-05-06 14:48:59 -07:00
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Make sure that the number of highmem pages is never larger
|
|
|
|
* than the number of the total dirtyable memory. This can only
|
|
|
|
* occur in very strange VM situations but we want to make sure
|
|
|
|
* that this does not occur.
|
|
|
|
*/
|
|
|
|
return min(x, total);
|
|
|
|
#else
|
|
|
|
return 0;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2008-05-12 21:21:04 +02:00
|
|
|
/**
|
|
|
|
* determine_dirtyable_memory - amount of memory that may be used
|
|
|
|
*
|
|
|
|
* Returns the numebr of pages that can currently be freed and used
|
|
|
|
* by the kernel for direct mappings.
|
|
|
|
*/
|
|
|
|
unsigned long determine_dirtyable_memory(void)
|
2007-05-06 14:48:59 -07:00
|
|
|
{
|
|
|
|
unsigned long x;
|
|
|
|
|
2009-09-21 17:01:42 -07:00
|
|
|
x = global_page_state(NR_FREE_PAGES) + global_reclaimable_pages();
|
2008-02-04 22:29:20 -08:00
|
|
|
|
|
|
|
if (!vm_highmem_is_dirtyable)
|
|
|
|
x -= highmem_dirtyable_memory(x);
|
|
|
|
|
2007-05-06 14:48:59 -07:00
|
|
|
return x + 1; /* Ensure that we never return 0 */
|
|
|
|
}
|
|
|
|
|
2008-04-30 00:54:32 -07:00
|
|
|
void
|
2009-01-06 14:39:29 -08:00
|
|
|
get_dirty_limits(unsigned long *pbackground, unsigned long *pdirty,
|
|
|
|
unsigned long *pbdi_dirty, struct backing_dev_info *bdi)
|
2005-04-16 15:20:36 -07:00
|
|
|
{
|
2009-01-06 14:39:29 -08:00
|
|
|
unsigned long background;
|
|
|
|
unsigned long dirty;
|
2007-05-06 14:48:59 -07:00
|
|
|
unsigned long available_memory = determine_dirtyable_memory();
|
2005-04-16 15:20:36 -07:00
|
|
|
struct task_struct *tsk;
|
|
|
|
|
mm: add dirty_background_bytes and dirty_bytes sysctls
This change introduces two new sysctls to /proc/sys/vm:
dirty_background_bytes and dirty_bytes.
dirty_background_bytes is the counterpart to dirty_background_ratio and
dirty_bytes is the counterpart to dirty_ratio.
With growing memory capacities of individual machines, it's no longer
sufficient to specify dirty thresholds as a percentage of the amount of
dirtyable memory over the entire system.
dirty_background_bytes and dirty_bytes specify quantities of memory, in
bytes, that represent the dirty limits for the entire system. If either
of these values is set, its value represents the amount of dirty memory
that is needed to commence either background or direct writeback.
When a `bytes' or `ratio' file is written, its counterpart becomes a
function of the written value. For example, if dirty_bytes is written to
be 8096, 8K of memory is required to commence direct writeback.
dirty_ratio is then functionally equivalent to 8K / the amount of
dirtyable memory:
dirtyable_memory = free pages + mapped pages + file cache
dirty_background_bytes = dirty_background_ratio * dirtyable_memory
-or-
dirty_background_ratio = dirty_background_bytes / dirtyable_memory
AND
dirty_bytes = dirty_ratio * dirtyable_memory
-or-
dirty_ratio = dirty_bytes / dirtyable_memory
Only one of dirty_background_bytes and dirty_background_ratio may be
specified at a time, and only one of dirty_bytes and dirty_ratio may be
specified. When one sysctl is written, the other appears as 0 when read.
The `bytes' files operate on a page size granularity since dirty limits
are compared with ZVC values, which are in page units.
Prior to this change, the minimum dirty_ratio was 5 as implemented by
get_dirty_limits() although /proc/sys/vm/dirty_ratio would show any user
written value between 0 and 100. This restriction is maintained, but
dirty_bytes has a lower limit of only one page.
Also prior to this change, the dirty_background_ratio could not equal or
exceed dirty_ratio. This restriction is maintained in addition to
restricting dirty_background_bytes. If either background threshold equals
or exceeds that of the dirty threshold, it is implicitly set to half the
dirty threshold.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: David Rientjes <rientjes@google.com>
Cc: Andrea Righi <righi.andrea@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-01-06 14:39:31 -08:00
|
|
|
if (vm_dirty_bytes)
|
|
|
|
dirty = DIV_ROUND_UP(vm_dirty_bytes, PAGE_SIZE);
|
|
|
|
else {
|
|
|
|
int dirty_ratio;
|
|
|
|
|
|
|
|
dirty_ratio = vm_dirty_ratio;
|
|
|
|
if (dirty_ratio < 5)
|
|
|
|
dirty_ratio = 5;
|
|
|
|
dirty = (dirty_ratio * available_memory) / 100;
|
|
|
|
}
|
2005-04-16 15:20:36 -07:00
|
|
|
|
mm: add dirty_background_bytes and dirty_bytes sysctls
This change introduces two new sysctls to /proc/sys/vm:
dirty_background_bytes and dirty_bytes.
dirty_background_bytes is the counterpart to dirty_background_ratio and
dirty_bytes is the counterpart to dirty_ratio.
With growing memory capacities of individual machines, it's no longer
sufficient to specify dirty thresholds as a percentage of the amount of
dirtyable memory over the entire system.
dirty_background_bytes and dirty_bytes specify quantities of memory, in
bytes, that represent the dirty limits for the entire system. If either
of these values is set, its value represents the amount of dirty memory
that is needed to commence either background or direct writeback.
When a `bytes' or `ratio' file is written, its counterpart becomes a
function of the written value. For example, if dirty_bytes is written to
be 8096, 8K of memory is required to commence direct writeback.
dirty_ratio is then functionally equivalent to 8K / the amount of
dirtyable memory:
dirtyable_memory = free pages + mapped pages + file cache
dirty_background_bytes = dirty_background_ratio * dirtyable_memory
-or-
dirty_background_ratio = dirty_background_bytes / dirtyable_memory
AND
dirty_bytes = dirty_ratio * dirtyable_memory
-or-
dirty_ratio = dirty_bytes / dirtyable_memory
Only one of dirty_background_bytes and dirty_background_ratio may be
specified at a time, and only one of dirty_bytes and dirty_ratio may be
specified. When one sysctl is written, the other appears as 0 when read.
The `bytes' files operate on a page size granularity since dirty limits
are compared with ZVC values, which are in page units.
Prior to this change, the minimum dirty_ratio was 5 as implemented by
get_dirty_limits() although /proc/sys/vm/dirty_ratio would show any user
written value between 0 and 100. This restriction is maintained, but
dirty_bytes has a lower limit of only one page.
Also prior to this change, the dirty_background_ratio could not equal or
exceed dirty_ratio. This restriction is maintained in addition to
restricting dirty_background_bytes. If either background threshold equals
or exceeds that of the dirty threshold, it is implicitly set to half the
dirty threshold.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: David Rientjes <rientjes@google.com>
Cc: Andrea Righi <righi.andrea@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-01-06 14:39:31 -08:00
|
|
|
if (dirty_background_bytes)
|
|
|
|
background = DIV_ROUND_UP(dirty_background_bytes, PAGE_SIZE);
|
|
|
|
else
|
|
|
|
background = (dirty_background_ratio * available_memory) / 100;
|
2005-04-16 15:20:36 -07:00
|
|
|
|
mm: add dirty_background_bytes and dirty_bytes sysctls
This change introduces two new sysctls to /proc/sys/vm:
dirty_background_bytes and dirty_bytes.
dirty_background_bytes is the counterpart to dirty_background_ratio and
dirty_bytes is the counterpart to dirty_ratio.
With growing memory capacities of individual machines, it's no longer
sufficient to specify dirty thresholds as a percentage of the amount of
dirtyable memory over the entire system.
dirty_background_bytes and dirty_bytes specify quantities of memory, in
bytes, that represent the dirty limits for the entire system. If either
of these values is set, its value represents the amount of dirty memory
that is needed to commence either background or direct writeback.
When a `bytes' or `ratio' file is written, its counterpart becomes a
function of the written value. For example, if dirty_bytes is written to
be 8096, 8K of memory is required to commence direct writeback.
dirty_ratio is then functionally equivalent to 8K / the amount of
dirtyable memory:
dirtyable_memory = free pages + mapped pages + file cache
dirty_background_bytes = dirty_background_ratio * dirtyable_memory
-or-
dirty_background_ratio = dirty_background_bytes / dirtyable_memory
AND
dirty_bytes = dirty_ratio * dirtyable_memory
-or-
dirty_ratio = dirty_bytes / dirtyable_memory
Only one of dirty_background_bytes and dirty_background_ratio may be
specified at a time, and only one of dirty_bytes and dirty_ratio may be
specified. When one sysctl is written, the other appears as 0 when read.
The `bytes' files operate on a page size granularity since dirty limits
are compared with ZVC values, which are in page units.
Prior to this change, the minimum dirty_ratio was 5 as implemented by
get_dirty_limits() although /proc/sys/vm/dirty_ratio would show any user
written value between 0 and 100. This restriction is maintained, but
dirty_bytes has a lower limit of only one page.
Also prior to this change, the dirty_background_ratio could not equal or
exceed dirty_ratio. This restriction is maintained in addition to
restricting dirty_background_bytes. If either background threshold equals
or exceeds that of the dirty threshold, it is implicitly set to half the
dirty threshold.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: David Rientjes <rientjes@google.com>
Cc: Andrea Righi <righi.andrea@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-01-06 14:39:31 -08:00
|
|
|
if (background >= dirty)
|
|
|
|
background = dirty / 2;
|
2005-04-16 15:20:36 -07:00
|
|
|
tsk = current;
|
|
|
|
if (tsk->flags & PF_LESS_THROTTLE || rt_task(tsk)) {
|
|
|
|
background += background / 4;
|
|
|
|
dirty += dirty / 4;
|
|
|
|
}
|
|
|
|
*pbackground = background;
|
|
|
|
*pdirty = dirty;
|
2007-10-16 23:25:50 -07:00
|
|
|
|
|
|
|
if (bdi) {
|
2008-04-30 00:54:35 -07:00
|
|
|
u64 bdi_dirty;
|
2007-10-16 23:25:50 -07:00
|
|
|
long numerator, denominator;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Calculate this BDI's share of the dirty ratio.
|
|
|
|
*/
|
|
|
|
bdi_writeout_fraction(bdi, &numerator, &denominator);
|
|
|
|
|
2008-04-30 00:54:35 -07:00
|
|
|
bdi_dirty = (dirty * (100 - bdi_min_ratio)) / 100;
|
2007-10-16 23:25:50 -07:00
|
|
|
bdi_dirty *= numerator;
|
|
|
|
do_div(bdi_dirty, denominator);
|
2008-04-30 00:54:35 -07:00
|
|
|
bdi_dirty += (dirty * bdi->min_ratio) / 100;
|
2008-04-30 00:54:36 -07:00
|
|
|
if (bdi_dirty > (dirty * bdi->max_ratio) / 100)
|
|
|
|
bdi_dirty = dirty * bdi->max_ratio / 100;
|
2007-10-16 23:25:50 -07:00
|
|
|
|
|
|
|
*pbdi_dirty = bdi_dirty;
|
|
|
|
clip_bdi_dirty_limit(bdi, dirty, pbdi_dirty);
|
2007-10-16 23:25:50 -07:00
|
|
|
task_dirty_limit(current, pbdi_dirty);
|
2007-10-16 23:25:50 -07:00
|
|
|
}
|
2005-04-16 15:20:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* balance_dirty_pages() must be called by processes which are generating dirty
|
|
|
|
* data. It looks at the number of dirty pages in the machine and will force
|
|
|
|
* the caller to perform writeback if the system is over `vm_dirty_ratio'.
|
2009-09-23 19:37:09 +02:00
|
|
|
* If we're over `background_thresh' then the writeback threads are woken to
|
|
|
|
* perform some writeout.
|
2005-04-16 15:20:36 -07:00
|
|
|
*/
|
2009-09-23 21:56:00 +08:00
|
|
|
static void balance_dirty_pages(struct address_space *mapping,
|
|
|
|
unsigned long write_chunk)
|
2005-04-16 15:20:36 -07:00
|
|
|
{
|
2007-11-14 16:59:15 -08:00
|
|
|
long nr_reclaimable, bdi_nr_reclaimable;
|
|
|
|
long nr_writeback, bdi_nr_writeback;
|
2009-01-06 14:39:29 -08:00
|
|
|
unsigned long background_thresh;
|
|
|
|
unsigned long dirty_thresh;
|
|
|
|
unsigned long bdi_thresh;
|
2005-04-16 15:20:36 -07:00
|
|
|
unsigned long pages_written = 0;
|
2009-09-17 19:59:14 +02:00
|
|
|
unsigned long pause = 1;
|
2005-04-16 15:20:36 -07:00
|
|
|
|
|
|
|
struct backing_dev_info *bdi = mapping->backing_dev_info;
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
struct writeback_control wbc = {
|
|
|
|
.bdi = bdi,
|
|
|
|
.sync_mode = WB_SYNC_NONE,
|
|
|
|
.older_than_this = NULL,
|
|
|
|
.nr_to_write = write_chunk,
|
[PATCH] writeback: fix range handling
When a writeback_control's `start' and `end' fields are used to
indicate a one-byte-range starting at file offset zero, the required
values of .start=0,.end=0 mean that the ->writepages() implementation
has no way of telling that it is being asked to perform a range
request. Because we're currently overloading (start == 0 && end == 0)
to mean "this is not a write-a-range request".
To make all this sane, the patch changes range of writeback_control.
So caller does: If it is calling ->writepages() to write pages, it
sets range (range_start/end or range_cyclic) always.
And if range_cyclic is true, ->writepages() thinks the range is
cyclic, otherwise it just uses range_start and range_end.
This patch does,
- Add LLONG_MAX, LLONG_MIN, ULLONG_MAX to include/linux/kernel.h
-1 is usually ok for range_end (type is long long). But, if someone did,
range_end += val; range_end is "val - 1"
u64val = range_end >> bits; u64val is "~(0ULL)"
or something, they are wrong. So, this adds LLONG_MAX to avoid nasty
things, and uses LLONG_MAX for range_end.
- All callers of ->writepages() sets range_start/end or range_cyclic.
- Fix updates of ->writeback_index. It seems already bit strange.
If it starts at 0 and ended by check of nr_to_write, this last
index may reduce chance to scan end of file. So, this updates
->writeback_index only if range_cyclic is true or whole-file is
scanned.
Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Cc: Nathan Scott <nathans@sgi.com>
Cc: Anton Altaparmakov <aia21@cantab.net>
Cc: Steven French <sfrench@us.ibm.com>
Cc: "Vladimir V. Saveliev" <vs@namesys.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-06-23 02:03:26 -07:00
|
|
|
.range_cyclic = 1,
|
2005-04-16 15:20:36 -07:00
|
|
|
};
|
|
|
|
|
2007-10-16 23:25:50 -07:00
|
|
|
get_dirty_limits(&background_thresh, &dirty_thresh,
|
|
|
|
&bdi_thresh, bdi);
|
2007-11-14 16:59:15 -08:00
|
|
|
|
|
|
|
nr_reclaimable = global_page_state(NR_FILE_DIRTY) +
|
|
|
|
global_page_state(NR_UNSTABLE_NFS);
|
|
|
|
nr_writeback = global_page_state(NR_WRITEBACK);
|
|
|
|
|
2007-10-16 23:25:50 -07:00
|
|
|
bdi_nr_reclaimable = bdi_stat(bdi, BDI_RECLAIMABLE);
|
|
|
|
bdi_nr_writeback = bdi_stat(bdi, BDI_WRITEBACK);
|
2007-11-14 16:59:15 -08:00
|
|
|
|
2007-10-16 23:25:50 -07:00
|
|
|
if (bdi_nr_reclaimable + bdi_nr_writeback <= bdi_thresh)
|
|
|
|
break;
|
2005-04-16 15:20:36 -07:00
|
|
|
|
2007-11-14 16:59:15 -08:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
|
2007-10-16 23:25:50 -07:00
|
|
|
if (!bdi->dirty_exceeded)
|
|
|
|
bdi->dirty_exceeded = 1;
|
2005-04-16 15:20:36 -07:00
|
|
|
|
|
|
|
/* Note: nr_reclaimable denotes nr_dirty + nr_unstable.
|
|
|
|
* Unstable writes are a feature of certain networked
|
|
|
|
* filesystems (i.e. NFS) in which data may have been
|
|
|
|
* written to the server's write cache, but has not yet
|
|
|
|
* been flushed to permanent storage.
|
2009-06-30 11:41:35 -07:00
|
|
|
* Only move pages to writeback if this bdi is over its
|
|
|
|
* threshold otherwise wait until the disk writes catch
|
|
|
|
* up.
|
2005-04-16 15:20:36 -07:00
|
|
|
*/
|
2009-06-30 11:41:35 -07:00
|
|
|
if (bdi_nr_reclaimable > bdi_thresh) {
|
2009-09-09 09:08:54 +02:00
|
|
|
writeback_inodes_wbc(&wbc);
|
2005-04-16 15:20:36 -07:00
|
|
|
pages_written += write_chunk - wbc.nr_to_write;
|
|