From: Johannes Weiner <hidden> Date: 2011-09-30 07:17:19
Hi,
this is the third revision of the per-zone dirty limits. Changes from
the second version have been mostly documentation, changelog, and
naming fixes based on review feedback:
o add new dirty_balance_reserve instead of abusing totalreserve_pages
for undirtyable (per-zone) reserves and document the variable and
its calculation (Mel)
o use !ALLOC_WMARK_LOW instead of adding new ALLOC_SLOWPATH (Mel)
o rename determine_dirtyable_memory -> global_dirtyable_memory (Andrew)
o better explain behaviour on NUMA in changelog (Andrew)
o extend changelogs and code comments on how per-zone dirty limits are
calculated, and why, and their proportions to the global limit (Mel, Andrew)
o kernel-doc zone_dirty_ok() (Andrew)
o extend changelogs and code comments on how per-zone dirty limits are
used to protect zones from dirty pages (Mel, Andrew)
o revert back to a separate set of zone_dirtyable_memory() and zone_dirty_limit()
for easier reading (Andrew)
Based on v3.1-rc3-mmotm-2011-08-24-14-08.
fs/btrfs/file.c | 2 +-
include/linux/gfp.h | 4 +-
include/linux/mmzone.h | 6 ++
include/linux/swap.h | 1 +
include/linux/writeback.h | 1 +
mm/filemap.c | 5 +-
mm/page-writeback.c | 181 +++++++++++++++++++++++++++++++++------------
mm/page_alloc.c | 48 ++++++++++++
8 files changed, 197 insertions(+), 51 deletions(-)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Johannes Weiner <hidden> Date: 2011-09-30 07:17:20
The amount of dirtyable pages should not include the full number of
free pages: there is a number of reserved pages that the page
allocator and kswapd always try to keep free.
The closer (reclaimable pages - dirty pages) is to the number of
reserved pages, the more likely it becomes for reclaim to run into
dirty pages:
+----------+ ---
| anon | |
+----------+ |
| | |
| | -- dirty limit new -- flusher new
| file | | |
| | | |
| | -- dirty limit old -- flusher old
| | |
+----------+ --- reclaim
| reserved |
+----------+
| kernel |
+----------+
This patch introduces a per-zone dirty reserve that takes both the
lowmem reserve as well as the high watermark of the zone into account,
and a global sum of those per-zone values that is subtracted from the
global amount of dirtyable pages. The lowmem reserve is unavailable
to page cache allocations and kswapd tries to keep the high watermark
free. We don't want to end up in a situation where reclaim has to
clean pages in order to balance zones.
Not treating reserved pages as dirtyable on a global level is only a
conceptual fix. In reality, dirty pages are not distributed equally
across zones and reclaim runs into dirty pages on a regular basis.
But it is important to get this right before tackling the problem on a
per-zone level, where the distance between reclaim and the dirty pages
is mostly much smaller in absolute numbers.
Signed-off-by: Johannes Weiner <redacted>
Reviewed-by: Rik van Riel <redacted>
---
include/linux/mmzone.h | 6 ++++++
include/linux/swap.h | 1 +
mm/page-writeback.c | 6 ++++--
mm/page_alloc.c | 19 +++++++++++++++++++
4 files changed, 30 insertions(+), 2 deletions(-)
@@ -170,7 +170,8 @@ static unsigned long highmem_dirtyable_memory(unsigned long total)&NODE_DATA(node)->node_zones[ZONE_HIGHMEM];x+=zone_page_state(z,NR_FREE_PAGES)+-zone_reclaimable_pages(z);+zone_reclaimable_pages(z)-+zone->dirty_balance_reserve;}/**Makesurethatthenumberofhighmempagesisneverlarger
@@ -194,7 +195,8 @@ static unsigned long determine_dirtyable_memory(void){unsignedlongx;-x=global_page_state(NR_FREE_PAGES)+global_reclaimable_pages();+x=global_page_state(NR_FREE_PAGES)+global_reclaimable_pages()-+dirty_balance_reserve;if(!vm_highmem_is_dirtyable)x-=highmem_dirtyable_memory(x);
--
1.7.6.2
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Johannes Weiner <hidden> Date: 2011-09-30 07:17:21
The next patch will introduce per-zone dirty limiting functions in
addition to the traditional global dirty limiting.
Rename determine_dirtyable_memory() to global_dirtyable_memory()
before adding the zone-specific version, and fix up its documentation.
Also, move the functions to determine the dirtyable memory and the
function to calculate the dirty limit based on that together so that
their relationship is more apparent and that they can be commented on
as a group.
Signed-off-by: Johannes Weiner <redacted>
Reviewed-by: Minchan Kim <redacted>
Acked-by: Mel Gorman <redacted>
---
mm/page-writeback.c | 92 +++++++++++++++++++++++++-------------------------
1 files changed, 46 insertions(+), 46 deletions(-)
@@ -186,12 +186,12 @@ static unsigned long highmem_dirtyable_memory(unsigned long total)}/**-*determine_dirtyable_memory-amountofmemorythatmaybeused+*global_dirtyable_memory-numberofgloballydirtyablepages*-*Returnsthenumebrofpagesthatcancurrentlybefreedandused-*bythekernelfordirectmappings.+*Returnstheglobalnumberofpagespotentiallyavailablefordirty+*pagecache.Thisisthebasevaluefortheglobaldirtylimits.*/-staticunsignedlongdetermine_dirtyable_memory(void)+staticunsignedlongglobal_dirtyable_memory(void){unsignedlongx;
@@ -205,6 +205,47 @@ static unsigned long determine_dirtyable_memory(void)}/*+*global_dirty_limits-background-writebackanddirty-throttlingthresholds+*+*Calculatethedirtythresholdsbasedonsysctlparameters+*-vm.dirty_background_ratioorvm.dirty_background_bytes+*-vm.dirty_ratioorvm.dirty_bytes+*Thedirtylimitswillbeliftedby1/4forPF_LESS_THROTTLE(ie.nfsd)and+*real-timetasks.+*/+voidglobal_dirty_limits(unsignedlong*pbackground,unsignedlong*pdirty)+{+unsignedlongbackground;+unsignedlongdirty;+unsignedlonguninitialized_var(available_memory);+structtask_struct*tsk;++if(!vm_dirty_bytes||!dirty_background_bytes)+available_memory=global_dirtyable_memory();++if(vm_dirty_bytes)+dirty=DIV_ROUND_UP(vm_dirty_bytes,PAGE_SIZE);+else+dirty=(vm_dirty_ratio*available_memory)/100;++if(dirty_background_bytes)+background=DIV_ROUND_UP(dirty_background_bytes,PAGE_SIZE);+else+background=(dirty_background_ratio*available_memory)/100;++if(background>=dirty)+background=dirty/2;+tsk=current;+if(tsk->flags&PF_LESS_THROTTLE||rt_task(tsk)){+background+=background/4;+dirty+=dirty/4;+}+*pbackground=background;+*pdirty=dirty;+trace_global_dirty_state(background,dirty);+}++/**coupletheperiodtothedirty_ratio:**period/2~roundup_pow_of_two(dirtylimit)
@@ -216,7 +257,7 @@ static int calc_period_shift(void)if(vm_dirty_bytes)dirty_total=vm_dirty_bytes/PAGE_SIZE;else-dirty_total=(vm_dirty_ratio*determine_dirtyable_memory())/+dirty_total=(vm_dirty_ratio*global_dirtyable_memory())/100;return2+ilog2(dirty_total-1);}
@@ -416,47 +457,6 @@ static unsigned long hard_dirty_limit(unsigned long thresh)returnmax(thresh,global_dirty_limit);}-/*-*global_dirty_limits-background-writebackanddirty-throttlingthresholds-*-*Calculatethedirtythresholdsbasedonsysctlparameters-*-vm.dirty_background_ratioorvm.dirty_background_bytes-*-vm.dirty_ratioorvm.dirty_bytes-*Thedirtylimitswillbeliftedby1/4forPF_LESS_THROTTLE(ie.nfsd)and-*real-timetasks.-*/-voidglobal_dirty_limits(unsignedlong*pbackground,unsignedlong*pdirty)-{-unsignedlongbackground;-unsignedlongdirty;-unsignedlonguninitialized_var(available_memory);-structtask_struct*tsk;--if(!vm_dirty_bytes||!dirty_background_bytes)-available_memory=determine_dirtyable_memory();--if(vm_dirty_bytes)-dirty=DIV_ROUND_UP(vm_dirty_bytes,PAGE_SIZE);-else-dirty=(vm_dirty_ratio*available_memory)/100;--if(dirty_background_bytes)-background=DIV_ROUND_UP(dirty_background_bytes,PAGE_SIZE);-else-background=(dirty_background_ratio*available_memory)/100;--if(background>=dirty)-background=dirty/2;-tsk=current;-if(tsk->flags&PF_LESS_THROTTLE||rt_task(tsk)){-background+=background/4;-dirty+=dirty/4;-}-*pbackground=background;-*pdirty=dirty;-trace_global_dirty_state(background,dirty);-}-/***bdi_dirty_limit-@bdi'sshareofdirtythrottlingthreshold*@bdi:thebacking_dev_infotoquery
--
1.7.6.2
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Johannes Weiner <hidden> Date: 2011-09-30 07:17:22
The maximum number of dirty pages that exist in the system at any time
is determined by a number of pages considered dirtyable and a
user-configured percentage of those, or an absolute number in bytes.
This number of dirtyable pages is the sum of memory provided by all
the zones in the system minus their lowmem reserves and high
watermarks, so that the system can retain a healthy number of free
pages without having to reclaim dirty pages.
But there is a flaw in that we have a zoned page allocator which does
not care about the global state but rather the state of individual
memory zones. And right now there is nothing that prevents one zone
from filling up with dirty pages while other zones are spared, which
frequently leads to situations where kswapd, in order to restore the
watermark of free pages, does indeed have to write pages from that
zone's LRU list. This can interfere so badly with IO from the flusher
threads that major filesystems (btrfs, xfs, ext4) mostly ignore write
requests from reclaim already, taking away the VM's only possibility
to keep such a zone balanced, aside from hoping the flushers will soon
clean pages from that zone.
Enter per-zone dirty limits. They are to a zone's dirtyable memory
what the global limit is to the global amount of dirtyable memory, and
try to make sure that no single zone receives more than its fair share
of the globally allowed dirty pages in the first place. As the number
of pages considered dirtyable exclude the zones' lowmem reserves and
high watermarks, the maximum number of dirty pages in a zone is such
that the zone can always be balanced without requiring page cleaning.
As this is a placement decision in the page allocator and pages are
dirtied only after the allocation, this patch allows allocators to
pass __GFP_WRITE when they know in advance that the page will be
written to and become dirty soon. The page allocator will then
attempt to allocate from the first zone of the zonelist - which on
NUMA is determined by the task's NUMA memory policy - that has not
exceeded its dirty limit.
At first glance, it would appear that the diversion to lower zones can
increase pressure on them, but this is not the case. With a full high
zone, allocations will be diverted to lower zones eventually, so it is
more of a shift in timing of the lower zone allocations. Workloads
that previously could fit their dirty pages completely in the higher
zone may be forced to allocate from lower zones, but the amount of
pages that 'spill over' are limited themselves by the lower zones'
dirty constraints, and thus unlikely to become a problem.
For now, the problem of unfair dirty page distribution remains for
NUMA configurations where the zones allowed for allocation are in sum
not big enough to trigger the global dirty limits, wake up the flusher
threads and remedy the situation. Because of this, an allocation that
could not succeed on any of the considered zones is allowed to ignore
the dirty limits before going into direct reclaim or even failing the
allocation, until a future patch changes the global dirty throttling
and flusher thread activation so that they take individual zone states
into account.
Signed-off-by: Johannes Weiner <redacted>
Reviewed-by: Minchan Kim <redacted>
Acked-by: Mel Gorman <mgorman@suse.de>
---
include/linux/gfp.h | 4 ++-
include/linux/writeback.h | 1 +
mm/page-writeback.c | 83 +++++++++++++++++++++++++++++++++++++++++++++
mm/page_alloc.c | 29 ++++++++++++++++
4 files changed, 116 insertions(+), 1 deletions(-)
@@ -85,6 +86,7 @@ struct vm_area_struct;#define __GFP_NO_KSWAPD ((__force gfp_t)___GFP_NO_KSWAPD)#define __GFP_OTHER_NODE ((__force gfp_t)___GFP_OTHER_NODE) /* On behalf of other node */+#define __GFP_WRITE ((__force gfp_t)___GFP_WRITE) /* Allocator intends to dirty page *//**Thismayseemredundant,butit'sawayofannotatingfalsepositivesvs.
@@ -92,7 +94,7 @@ struct vm_area_struct;*/#define __GFP_NOTRACK_FALSE_POSITIVE (__GFP_NOTRACK)-#define __GFP_BITS_SHIFT 24 /* Room for N __GFP_FOO bits */+#define __GFP_BITS_SHIFT 25 /* Room for N __GFP_FOO bits */#define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))/* This equals 0, but use constants in case they ever change */
--
1.7.6.2
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Johannes Weiner <hidden> Date: 2011-09-30 07:17:23
Tell the page allocator that pages allocated through
grab_cache_page_write_begin() are expected to become dirty soon.
Signed-off-by: Johannes Weiner <redacted>
Reviewed-by: Rik van Riel <redacted>
Acked-by: Mel Gorman <mgorman@suse.de>
Reviewed-by: Minchan Kim <redacted>
---
mm/filemap.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
--
1.7.6.2
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Johannes Weiner <hidden> Date: 2011-09-30 07:17:24
Tell the page allocator that pages allocated for a buffered write are
expected to become dirty soon.
Signed-off-by: Johannes Weiner <redacted>
Reviewed-by: Rik van Riel <redacted>
---
fs/btrfs/file.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
--
1.7.6.2
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Pekka Enberg <hidden> Date: 2011-09-30 07:35:25
Hi Johannes!
On Fri, Sep 30, 2011 at 10:17 AM, Johannes Weiner [off-list ref] wrote:
But there is a flaw in that we have a zoned page allocator which does
not care about the global state but rather the state of individual
memory zones. And right now there is nothing that prevents one zone
from filling up with dirty pages while other zones are spared, which
frequently leads to situations where kswapd, in order to restore the
watermark of free pages, does indeed have to write pages from that
zone's LRU list. This can interfere so badly with IO from the flusher
threads that major filesystems (btrfs, xfs, ext4) mostly ignore write
requests from reclaim already, taking away the VM's only possibility
to keep such a zone balanced, aside from hoping the flushers will soon
clean pages from that zone.
The obvious question is: how did you test this? Can you share the results?
Pekka
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Johannes Weiner <hidden> Date: 2011-09-30 08:55:39
On Fri, Sep 30, 2011 at 10:35:25AM +0300, Pekka Enberg wrote:
Hi Johannes!
On Fri, Sep 30, 2011 at 10:17 AM, Johannes Weiner [off-list ref] wrote:
quoted
But there is a flaw in that we have a zoned page allocator which does
not care about the global state but rather the state of individual
memory zones. And right now there is nothing that prevents one zone
from filling up with dirty pages while other zones are spared, which
frequently leads to situations where kswapd, in order to restore the
watermark of free pages, does indeed have to write pages from that
zone's LRU list. This can interfere so badly with IO from the flusher
threads that major filesystems (btrfs, xfs, ext4) mostly ignore write
requests from reclaim already, taking away the VM's only possibility
to keep such a zone balanced, aside from hoping the flushers will soon
clean pages from that zone.
The obvious question is: how did you test this? Can you share the results?
Meh, sorry about that, they were in the series introduction the last
time and I forgot to copy them over.
I did single-threaded, linear writing to an USB stick as the effect is
most pronounced with slow backing devices.
[ The write deferring on ext4 because of delalloc is so extreme that I
could trigger it even with simple linear writers on a mediocre
rotating disk, though. I can not access the logfiles right now, but
the nr_vmscan_writes went practically away here as well and runtime
was unaffected with the patched kernel. ]
Test results
15M DMA + 3246M DMA32 + 504M Normal = 3765M memory
40% dirty ratio, 10% background ratio
16G USB thumb drive
10 runs of dd if=/dev/zero of=disk/zeroes bs=32k count=$((10 << 15))
seconds nr_vmscan_write
(stddev) min| median| max
xfs
vanilla: 549.747( 3.492) 0.000| 0.000| 0.000
patched: 550.996( 3.802) 0.000| 0.000| 0.000
fuse-ntfs
vanilla: 1183.094(53.178) 54349.000| 59341.000| 65163.000
patched: 558.049(17.914) 0.000| 0.000| 43.000
btrfs
vanilla: 573.679(14.015) 156657.000| 460178.000| 606926.000
patched: 563.365(11.368) 0.000| 0.000| 1362.000
ext4
vanilla: 561.197(15.782) 0.000|2725438.000|4143837.000
patched: 568.806(17.496) 0.000| 0.000| 0.000
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Michal Hocko <hidden> Date: 2011-09-30 13:53:14
On Fri 30-09-11 09:17:20, Johannes Weiner wrote:
The amount of dirtyable pages should not include the full number of
free pages: there is a number of reserved pages that the page
allocator and kswapd always try to keep free.
The closer (reclaimable pages - dirty pages) is to the number of
reserved pages, the more likely it becomes for reclaim to run into
dirty pages:
+----------+ ---
| anon | |
+----------+ |
| | |
| | -- dirty limit new -- flusher new
| file | | |
| | | |
| | -- dirty limit old -- flusher old
| | |
+----------+ --- reclaim
| reserved |
+----------+
| kernel |
+----------+
This patch introduces a per-zone dirty reserve that takes both the
lowmem reserve as well as the high watermark of the zone into account,
and a global sum of those per-zone values that is subtracted from the
global amount of dirtyable pages. The lowmem reserve is unavailable
to page cache allocations and kswapd tries to keep the high watermark
free. We don't want to end up in a situation where reclaim has to
clean pages in order to balance zones.
Not treating reserved pages as dirtyable on a global level is only a
conceptual fix. In reality, dirty pages are not distributed equally
across zones and reclaim runs into dirty pages on a regular basis.
But it is important to get this right before tackling the problem on a
per-zone level, where the distance between reclaim and the dirty pages
is mostly much smaller in absolute numbers.
Signed-off-by: Johannes Weiner <redacted>
Reviewed-by: Rik van Riel <redacted>
@@ -170,7 +170,8 @@ static unsigned long highmem_dirtyable_memory(unsigned long total)&NODE_DATA(node)->node_zones[ZONE_HIGHMEM];x+=zone_page_state(z,NR_FREE_PAGES)+-zone_reclaimable_pages(z);+zone_reclaimable_pages(z)-+zone->dirty_balance_reserve;}/**Makesurethatthenumberofhighmempagesisneverlarger
@@ -194,7 +195,8 @@ static unsigned long determine_dirtyable_memory(void){unsignedlongx;-x=global_page_state(NR_FREE_PAGES)+global_reclaimable_pages();+x=global_page_state(NR_FREE_PAGES)+global_reclaimable_pages()-+dirty_balance_reserve;if(!vm_highmem_is_dirtyable)x-=highmem_dirtyable_memory(x);
--
1.7.6.2
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
--
Michal Hocko
SUSE Labs
SUSE LINUX s.r.o.
Lihovarska 1060/12
190 00 Praha 9
Czech Republic
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Michal Hocko <hidden> Date: 2011-09-30 13:56:38
On Fri 30-09-11 09:17:21, Johannes Weiner wrote:
The next patch will introduce per-zone dirty limiting functions in
addition to the traditional global dirty limiting.
Rename determine_dirtyable_memory() to global_dirtyable_memory()
before adding the zone-specific version, and fix up its documentation.
Also, move the functions to determine the dirtyable memory and the
function to calculate the dirty limit based on that together so that
their relationship is more apparent and that they can be commented on
as a group.
Signed-off-by: Johannes Weiner <redacted>
Reviewed-by: Minchan Kim <redacted>
Acked-by: Mel Gorman <redacted>
@@ -186,12 +186,12 @@ static unsigned long highmem_dirtyable_memory(unsigned long total)}/**-*determine_dirtyable_memory-amountofmemorythatmaybeused+*global_dirtyable_memory-numberofgloballydirtyablepages*-*Returnsthenumebrofpagesthatcancurrentlybefreedandused-*bythekernelfordirectmappings.+*Returnstheglobalnumberofpagespotentiallyavailablefordirty+*pagecache.Thisisthebasevaluefortheglobaldirtylimits.*/-staticunsignedlongdetermine_dirtyable_memory(void)+staticunsignedlongglobal_dirtyable_memory(void){unsignedlongx;
@@ -205,6 +205,47 @@ static unsigned long determine_dirtyable_memory(void)}/*+*global_dirty_limits-background-writebackanddirty-throttlingthresholds+*+*Calculatethedirtythresholdsbasedonsysctlparameters+*-vm.dirty_background_ratioorvm.dirty_background_bytes+*-vm.dirty_ratioorvm.dirty_bytes+*Thedirtylimitswillbeliftedby1/4forPF_LESS_THROTTLE(ie.nfsd)and+*real-timetasks.+*/+voidglobal_dirty_limits(unsignedlong*pbackground,unsignedlong*pdirty)+{+unsignedlongbackground;+unsignedlongdirty;+unsignedlonguninitialized_var(available_memory);+structtask_struct*tsk;++if(!vm_dirty_bytes||!dirty_background_bytes)+available_memory=global_dirtyable_memory();++if(vm_dirty_bytes)+dirty=DIV_ROUND_UP(vm_dirty_bytes,PAGE_SIZE);+else+dirty=(vm_dirty_ratio*available_memory)/100;++if(dirty_background_bytes)+background=DIV_ROUND_UP(dirty_background_bytes,PAGE_SIZE);+else+background=(dirty_background_ratio*available_memory)/100;++if(background>=dirty)+background=dirty/2;+tsk=current;+if(tsk->flags&PF_LESS_THROTTLE||rt_task(tsk)){+background+=background/4;+dirty+=dirty/4;+}+*pbackground=background;+*pdirty=dirty;+trace_global_dirty_state(background,dirty);+}++/**coupletheperiodtothedirty_ratio:**period/2~roundup_pow_of_two(dirtylimit)
@@ -216,7 +257,7 @@ static int calc_period_shift(void)if(vm_dirty_bytes)dirty_total=vm_dirty_bytes/PAGE_SIZE;else-dirty_total=(vm_dirty_ratio*determine_dirtyable_memory())/+dirty_total=(vm_dirty_ratio*global_dirtyable_memory())/100;return2+ilog2(dirty_total-1);}
@@ -416,47 +457,6 @@ static unsigned long hard_dirty_limit(unsigned long thresh)returnmax(thresh,global_dirty_limit);}-/*-*global_dirty_limits-background-writebackanddirty-throttlingthresholds-*-*Calculatethedirtythresholdsbasedonsysctlparameters-*-vm.dirty_background_ratioorvm.dirty_background_bytes-*-vm.dirty_ratioorvm.dirty_bytes-*Thedirtylimitswillbeliftedby1/4forPF_LESS_THROTTLE(ie.nfsd)and-*real-timetasks.-*/-voidglobal_dirty_limits(unsignedlong*pbackground,unsignedlong*pdirty)-{-unsignedlongbackground;-unsignedlongdirty;-unsignedlonguninitialized_var(available_memory);-structtask_struct*tsk;--if(!vm_dirty_bytes||!dirty_background_bytes)-available_memory=determine_dirtyable_memory();--if(vm_dirty_bytes)-dirty=DIV_ROUND_UP(vm_dirty_bytes,PAGE_SIZE);-else-dirty=(vm_dirty_ratio*available_memory)/100;--if(dirty_background_bytes)-background=DIV_ROUND_UP(dirty_background_bytes,PAGE_SIZE);-else-background=(dirty_background_ratio*available_memory)/100;--if(background>=dirty)-background=dirty/2;-tsk=current;-if(tsk->flags&PF_LESS_THROTTLE||rt_task(tsk)){-background+=background/4;-dirty+=dirty/4;-}-*pbackground=background;-*pdirty=dirty;-trace_global_dirty_state(background,dirty);-}-/***bdi_dirty_limit-@bdi'sshareofdirtythrottlingthreshold*@bdi:thebacking_dev_infotoquery
--
1.7.6.2
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
--
Michal Hocko
SUSE Labs
SUSE LINUX s.r.o.
Lihovarska 1060/12
190 00 Praha 9
Czech Republic
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Michal Hocko <hidden> Date: 2011-09-30 14:28:05
On Fri 30-09-11 09:17:22, Johannes Weiner wrote:
The maximum number of dirty pages that exist in the system at any time
is determined by a number of pages considered dirtyable and a
user-configured percentage of those, or an absolute number in bytes.
This number of dirtyable pages is the sum of memory provided by all
the zones in the system minus their lowmem reserves and high
watermarks, so that the system can retain a healthy number of free
pages without having to reclaim dirty pages.
But there is a flaw in that we have a zoned page allocator which does
not care about the global state but rather the state of individual
memory zones. And right now there is nothing that prevents one zone
from filling up with dirty pages while other zones are spared, which
frequently leads to situations where kswapd, in order to restore the
watermark of free pages, does indeed have to write pages from that
zone's LRU list. This can interfere so badly with IO from the flusher
threads that major filesystems (btrfs, xfs, ext4) mostly ignore write
requests from reclaim already, taking away the VM's only possibility
to keep such a zone balanced, aside from hoping the flushers will soon
clean pages from that zone.
Enter per-zone dirty limits. They are to a zone's dirtyable memory
what the global limit is to the global amount of dirtyable memory, and
try to make sure that no single zone receives more than its fair share
of the globally allowed dirty pages in the first place. As the number
of pages considered dirtyable exclude the zones' lowmem reserves and
high watermarks, the maximum number of dirty pages in a zone is such
that the zone can always be balanced without requiring page cleaning.
As this is a placement decision in the page allocator and pages are
dirtied only after the allocation, this patch allows allocators to
pass __GFP_WRITE when they know in advance that the page will be
written to and become dirty soon. The page allocator will then
attempt to allocate from the first zone of the zonelist - which on
NUMA is determined by the task's NUMA memory policy - that has not
exceeded its dirty limit.
At first glance, it would appear that the diversion to lower zones can
increase pressure on them, but this is not the case. With a full high
zone, allocations will be diverted to lower zones eventually, so it is
more of a shift in timing of the lower zone allocations. Workloads
that previously could fit their dirty pages completely in the higher
zone may be forced to allocate from lower zones, but the amount of
pages that 'spill over' are limited themselves by the lower zones'
dirty constraints, and thus unlikely to become a problem.
For now, the problem of unfair dirty page distribution remains for
NUMA configurations where the zones allowed for allocation are in sum
not big enough to trigger the global dirty limits, wake up the flusher
threads and remedy the situation. Because of this, an allocation that
could not succeed on any of the considered zones is allowed to ignore
the dirty limits before going into direct reclaim or even failing the
allocation, until a future patch changes the global dirty throttling
and flusher thread activation so that they take individual zone states
into account.
Signed-off-by: Johannes Weiner <redacted>
Reviewed-by: Minchan Kim <redacted>
Acked-by: Mel Gorman <mgorman@suse.de>
@@ -85,6 +86,7 @@ struct vm_area_struct;#define __GFP_NO_KSWAPD ((__force gfp_t)___GFP_NO_KSWAPD)#define __GFP_OTHER_NODE ((__force gfp_t)___GFP_OTHER_NODE) /* On behalf of other node */+#define __GFP_WRITE ((__force gfp_t)___GFP_WRITE) /* Allocator intends to dirty page *//**Thismayseemredundant,butit'sawayofannotatingfalsepositivesvs.
@@ -92,7 +94,7 @@ struct vm_area_struct;*/#define __GFP_NOTRACK_FALSE_POSITIVE (__GFP_NOTRACK)-#define __GFP_BITS_SHIFT 24 /* Room for N __GFP_FOO bits */+#define __GFP_BITS_SHIFT 25 /* Room for N __GFP_FOO bits */#define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))/* This equals 0, but use constants in case they ever change */
--
1.7.6.2
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
--
Michal Hocko
SUSE Labs
SUSE LINUX s.r.o.
Lihovarska 1060/12
190 00 Praha 9
Czech Republic
From: Michal Hocko <hidden> Date: 2011-09-30 14:41:22
On Fri 30-09-11 09:17:23, Johannes Weiner wrote:
Tell the page allocator that pages allocated through
grab_cache_page_write_begin() are expected to become dirty soon.
Signed-off-by: Johannes Weiner <redacted>
Reviewed-by: Rik van Riel <redacted>
Acked-by: Mel Gorman <mgorman@suse.de>
Reviewed-by: Minchan Kim <redacted>
--
1.7.6.2
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
--
Michal Hocko
SUSE Labs
SUSE LINUX s.r.o.
Lihovarska 1060/12
190 00 Praha 9
Czech Republic
From: Minchan Kim <hidden> Date: 2011-10-01 07:10:01
On Fri, Sep 30, 2011 at 09:17:20AM +0200, Johannes Weiner wrote:
The amount of dirtyable pages should not include the full number of
free pages: there is a number of reserved pages that the page
allocator and kswapd always try to keep free.
The closer (reclaimable pages - dirty pages) is to the number of
reserved pages, the more likely it becomes for reclaim to run into
dirty pages:
+----------+ ---
| anon | |
+----------+ |
| | |
| | -- dirty limit new -- flusher new
| file | | |
| | | |
| | -- dirty limit old -- flusher old
| | |
+----------+ --- reclaim
| reserved |
+----------+
| kernel |
+----------+
This patch introduces a per-zone dirty reserve that takes both the
lowmem reserve as well as the high watermark of the zone into account,
and a global sum of those per-zone values that is subtracted from the
global amount of dirtyable pages. The lowmem reserve is unavailable
to page cache allocations and kswapd tries to keep the high watermark
free. We don't want to end up in a situation where reclaim has to
clean pages in order to balance zones.
Not treating reserved pages as dirtyable on a global level is only a
conceptual fix. In reality, dirty pages are not distributed equally
across zones and reclaim runs into dirty pages on a regular basis.
But it is important to get this right before tackling the problem on a
per-zone level, where the distance between reclaim and the dirty pages
is mostly much smaller in absolute numbers.
Signed-off-by: Johannes Weiner <redacted>
Reviewed-by: Rik van Riel <redacted>
Reviewed-by: Minchan Kim <redacted>
--
Kinds regards,
Minchan Kim
On Fri, Sep 30, 2011 at 09:17:20AM +0200, Johannes Weiner wrote:
The amount of dirtyable pages should not include the full number of
free pages: there is a number of reserved pages that the page
allocator and kswapd always try to keep free.
The closer (reclaimable pages - dirty pages) is to the number of
reserved pages, the more likely it becomes for reclaim to run into
dirty pages:
+----------+ ---
| anon | |
+----------+ |
| | |
| | -- dirty limit new -- flusher new
| file | | |
| | | |
| | -- dirty limit old -- flusher old
| | |
+----------+ --- reclaim
| reserved |
+----------+
| kernel |
+----------+
This patch introduces a per-zone dirty reserve that takes both the
lowmem reserve as well as the high watermark of the zone into account,
and a global sum of those per-zone values that is subtracted from the
global amount of dirtyable pages. The lowmem reserve is unavailable
to page cache allocations and kswapd tries to keep the high watermark
free. We don't want to end up in a situation where reclaim has to
clean pages in order to balance zones.
Not treating reserved pages as dirtyable on a global level is only a
conceptual fix. In reality, dirty pages are not distributed equally
across zones and reclaim runs into dirty pages on a regular basis.
But it is important to get this right before tackling the problem on a
per-zone level, where the distance between reclaim and the dirty pages
is mostly much smaller in absolute numbers.
Signed-off-by: Johannes Weiner <redacted>
Reviewed-by: Rik van Riel <redacted>
On Fri, Sep 30, 2011 at 09:17:24AM +0200, Johannes Weiner wrote:
Tell the page allocator that pages allocated for a buffered write are
expected to become dirty soon.
Signed-off-by: Johannes Weiner <redacted>
Reviewed-by: Rik van Riel <redacted>
//regression
3) much increased cpu %user and %system for btrfs
Sorry I find out that the CPU time regressions for btrfs are caused by
some additional trace events enabled on btrfs (for debugging an
unrelated btrfs hang bug) which results in 7 times more trace event
lines:
2701238 /export/writeback/thresh=1000M/btrfs-1dd-4k-8p-2941M-1000M:10-3.1.0-rc9-ioless-full-nfs-wq5-next-20111014+
19054054 /export/writeback/thresh=1000M/btrfs-1dd-4k-8p-2941M-1000M:10-3.1.0-rc9-ioless-full-per-zone-dirty-next-20111014+
So no real regressions.
Besides, the patchset also performs good on random writes:
3.1.0-rc9-ioless-full-nfs-wq5-next-20111014+ 3.1.0-rc9-ioless-full-per-zone-dirty-next-20111014+
------------------------ ------------------------
1.65 -5.1% 1.57 MMAP-RANDWRITE-4K/btrfs-fio_fat_mmap_randwrite_4k-4k-8p-4096M-20:10-X
18.65 -6.4% 17.46 MMAP-RANDWRITE-4K/ext3-fio_fat_mmap_randwrite_4k-4k-8p-4096M-20:10-X
2.09 +1.2% 2.12 MMAP-RANDWRITE-4K/ext4-fio_fat_mmap_randwrite_4k-4k-8p-4096M-20:10-X
2.49 -0.3% 2.48 MMAP-RANDWRITE-4K/xfs-fio_fat_mmap_randwrite_4k-4k-8p-4096M-20:10-X
51.35 +0.0% 51.36 MMAP-RANDWRITE-64K/btrfs-fio_fat_mmap_randwrite_64k-64k-8p-4096M-20:10-X
45.20 +0.5% 45.43 MMAP-RANDWRITE-64K/ext3-fio_fat_mmap_randwrite_64k-64k-8p-4096M-20:10-X
44.77 +0.7% 45.10 MMAP-RANDWRITE-64K/ext4-fio_fat_mmap_randwrite_64k-64k-8p-4096M-20:10-X
45.11 +2.5% 46.23 MMAP-RANDWRITE-64K/xfs-fio_fat_mmap_randwrite_64k-64k-8p-4096M-20:10-X
211.31 +0.2% 211.74 TOTAL write_bw
And writes to USB key:
3.1.0-rc9-ioless-full-nfs-wq5-next-20111014+ 3.1.0-rc9-ioless-full-per-zone-dirty-next-20111014+
------------------------ ------------------------
5.94 +0.8% 5.99 UKEY-thresh=1G/btrfs-1dd-4k-8p-4096M-1024M:10-X
2.64 -0.8% 2.62 UKEY-thresh=1G/ext3-10dd-4k-8p-4096M-1024M:10-X
5.10 +0.3% 5.12 UKEY-thresh=1G/ext3-1dd-4k-8p-4096M-1024M:10-X
3.26 -0.8% 3.24 UKEY-thresh=1G/ext3-2dd-4k-8p-4096M-1024M:10-X
5.63 -0.5% 5.60 UKEY-thresh=1G/ext4-10dd-4k-8p-4096M-1024M:10-X
6.04 -0.1% 6.04 UKEY-thresh=1G/ext4-1dd-4k-8p-4096M-1024M:10-X
5.90 -0.2% 5.88 UKEY-thresh=1G/ext4-2dd-4k-8p-4096M-1024M:10-X
2.45 +22.6% 3.00 UKEY-thresh=1G/xfs-10dd-4k-8p-4096M-1024M:10-X
6.18 -0.4% 6.16 UKEY-thresh=1G/xfs-1dd-4k-8p-4096M-1024M:10-X
4.81 +0.0% 4.81 UKEY-thresh=1G/xfs-2dd-4k-8p-4096M-1024M:10-X
47.94 +1.1% 48.45 TOTAL write_bw
In summary, I see no problem at all in these trivial writeback tests.
Tested-by: Wu Fengguang <redacted>
Thanks,
Fengguang
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
From: Johannes Weiner <hidden> Date: 2011-11-01 10:55:53
On Mon, Oct 31, 2011 at 07:33:21PM +0800, Wu Fengguang wrote:
quoted
//regression
3) much increased cpu %user and %system for btrfs
Sorry I find out that the CPU time regressions for btrfs are caused by
some additional trace events enabled on btrfs (for debugging an
unrelated btrfs hang bug) which results in 7 times more trace event
lines:
2701238 /export/writeback/thresh=1000M/btrfs-1dd-4k-8p-2941M-1000M:10-3.1.0-rc9-ioless-full-nfs-wq5-next-20111014+
19054054 /export/writeback/thresh=1000M/btrfs-1dd-4k-8p-2941M-1000M:10-3.1.0-rc9-ioless-full-per-zone-dirty-next-20111014+
So no real regressions.
Phew :-)
Besides, the patchset also performs good on random writes:
3.1.0-rc9-ioless-full-nfs-wq5-next-20111014+ 3.1.0-rc9-ioless-full-per-zone-dirty-next-20111014+
------------------------ ------------------------
1.65 -5.1% 1.57 MMAP-RANDWRITE-4K/btrfs-fio_fat_mmap_randwrite_4k-4k-8p-4096M-20:10-X
18.65 -6.4% 17.46 MMAP-RANDWRITE-4K/ext3-fio_fat_mmap_randwrite_4k-4k-8p-4096M-20:10-X
2.09 +1.2% 2.12 MMAP-RANDWRITE-4K/ext4-fio_fat_mmap_randwrite_4k-4k-8p-4096M-20:10-X
2.49 -0.3% 2.48 MMAP-RANDWRITE-4K/xfs-fio_fat_mmap_randwrite_4k-4k-8p-4096M-20:10-X
51.35 +0.0% 51.36 MMAP-RANDWRITE-64K/btrfs-fio_fat_mmap_randwrite_64k-64k-8p-4096M-20:10-X
45.20 +0.5% 45.43 MMAP-RANDWRITE-64K/ext3-fio_fat_mmap_randwrite_64k-64k-8p-4096M-20:10-X
44.77 +0.7% 45.10 MMAP-RANDWRITE-64K/ext4-fio_fat_mmap_randwrite_64k-64k-8p-4096M-20:10-X
45.11 +2.5% 46.23 MMAP-RANDWRITE-64K/xfs-fio_fat_mmap_randwrite_64k-64k-8p-4096M-20:10-X
211.31 +0.2% 211.74 TOTAL write_bw
Hmm, mmapped IO page allocations are not annotated yet, so I expect
this to be just runtime variations?
And writes to USB key:
3.1.0-rc9-ioless-full-nfs-wq5-next-20111014+ 3.1.0-rc9-ioless-full-per-zone-dirty-next-20111014+
------------------------ ------------------------
5.94 +0.8% 5.99 UKEY-thresh=1G/btrfs-1dd-4k-8p-4096M-1024M:10-X
2.64 -0.8% 2.62 UKEY-thresh=1G/ext3-10dd-4k-8p-4096M-1024M:10-X
5.10 +0.3% 5.12 UKEY-thresh=1G/ext3-1dd-4k-8p-4096M-1024M:10-X
3.26 -0.8% 3.24 UKEY-thresh=1G/ext3-2dd-4k-8p-4096M-1024M:10-X
5.63 -0.5% 5.60 UKEY-thresh=1G/ext4-10dd-4k-8p-4096M-1024M:10-X
6.04 -0.1% 6.04 UKEY-thresh=1G/ext4-1dd-4k-8p-4096M-1024M:10-X
5.90 -0.2% 5.88 UKEY-thresh=1G/ext4-2dd-4k-8p-4096M-1024M:10-X
2.45 +22.6% 3.00 UKEY-thresh=1G/xfs-10dd-4k-8p-4096M-1024M:10-X
6.18 -0.4% 6.16 UKEY-thresh=1G/xfs-1dd-4k-8p-4096M-1024M:10-X
4.81 +0.0% 4.81 UKEY-thresh=1G/xfs-2dd-4k-8p-4096M-1024M:10-X
47.94 +1.1% 48.45 TOTAL write_bw
In summary, I see no problem at all in these trivial writeback tests.
Tested-by: Wu Fengguang <redacted>
Thanks!
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>