Containers: Pagecache accounting and control subsystem (v1)
Subsystems (6)
cover Containers: Pagecache accounting and control subsystem (v1)
Containers: Pagecache accounting and control subsystem (v1)
-----------------------------------------------------------
This patch adds pagecache accounting and control on top of Paul's container subsystem v7 posted at
http://lkml.org/lkml/2007/2/12/88
and Balbir's RSS controller posted at
http://lkml.org/lkml/2007/2/26/8
This patchset depends on Balbir's RSS controller and cannot work independent of it. The page reclaim code has been merged with container RSS controller. However compile time options can individually enable/disable memory controller and/or pagecache controller.
Comments, suggestions and criticisms are welcome.
Features:
--------
* New subsystem called 'pagecache_acct' is registered with containers
* Container pointer is added to struct address_space to keep track of associated container
* In filemap.c and swap_state.c, the corresponding container's pagecache_acct subsystem is charged and uncharged whenever a new page is added or removed from pagecache
* The accounting number include pages in swap cache and filesystem buffer pages apart from pagecache, basically everything under NR_FILE_PAGES is counted as pagecache. However this excluded mapped and anonymous pages
* Limits on pagecache can be set by echo 100000 > pagecache_limit on the /container file system. The unit is in kilobytes
* If the pagecache utilisation limit is exceeded, pagecache reclaim code is invoked to recover dirty and clean pagecache pages only.
Advantages:
-----------
* Does not add container pointers in struct page
Limitations:
-----------
* Code is not safe for container deletion/task migration
* Pagecache page reclaim needs performance improvements
* Global LRU is churned in search of pagecache pages
Usage:
-----
* Add patch on top of Paul container (v7) at kernel version 2.6.20
* Enable CONFIG_CONTAINER_PAGECACHE_ACCT in 'General Setup'
* Boot new kernel
* Mount container filesystem
mount -t container /container
cd /container
* Create new container
mkdir mybox
cd /container/mybox
* Add current shell to container
echo $$ > tasks
* There are two files pagecache_usage and pagecache_limit
* In order to set limit, echo value in kilobytes to pagecache_limit
echo 100000 > pagecache_limit #This would set 100MB limit on pagecache usage
* Trash the system from current shell using scp/cp/dd/tar etc
* Watch pagecache_usage and /proc/meminfo to verify behavior
* Only unmapped pagecache data will be accounted and controlled. These are memory used by cp, scp, tar etc. While file mmap will be controlled by Balbir's RSS controller.
Tests:
------
* Ran kernbench within container with pagecache_limits set
ToDo:
----
* Merge with container RSS controller and eliminate redundant code
* Test and support task migration and container deletion
* Review reclaim performance
* Optimise page reclaim
Patch Series:
-------------
pagecache-controller-setup.patch
pagecache-controller-acct.patch
pagecache-controller-reclaim.patch
---
RFC PATCH 1/3 Containers: Pagecache controller setup
This patch adds basic infrastructure for pagecache accounting and control subsystem within the container framework.
pagecache_usage and pagecache_limit files are created along with every new container. Routines to extract subsystem pointers and container pointers have been added.
Compile time kernel options and have been added along with Makefile changes.
--- include/linux/pagecache_acct.h | 53 +++++ init/Kconfig | 7 mm/Makefile | 1 mm/pagecache_acct.c | 368 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 429 insertions(+)
include/linux/pagecache_acct.h new file +53 -0
@@ -0,0 +1,53 @@ +/* +* Pagecache controller - "Account and control pagecache usage" +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* Copyright IBM Corporation, 2007 +* +* Author: Vaidyanathan Srinivasan <[email protected]> +* +*/ + +#ifndef _LINUX_PAGECACHE_ACCT_H +#define _LINUX_PAGECACHE_ACCT_H + +#include <linux/container.h> + +#ifdef CONFIG_CONTAINER_PAGECACHE_ACCT +extern void pagecache_acct_init_page_ptr (struct page *page); +extern void pagecache_acct_charge (struct page *page); +extern void pagecache_acct_uncharge (struct page *page); +extern int pagecache_acct_page_overlimit (struct page *page); +extern int pagecache_acct_mapping_overlimit (struct address_space *mapping); +extern int pagecache_acct_cont_overlimit (struct container *cont); +extern int pagecache_acct_shrink_used (unsigned long nr_pages); +#else +static inline void pagecache_acct_init_page_ptr (struct page *page) {} +static inline void pagecache_acct_charge (struct page *page) {} +static inline void pagecache_acct_uncharge (struct page *page) {} +static inline int pagecache_acct_page_overlimit ( +struct page *page) {return 0 ; } +static inline int pagecache_acct_mapping_overlimit ( +struct address_space *mapping) {return 0 ; } +static inline int pagecache_acct_cont_overlimit ( +struct container *cont) {return 0 ; } +static inline int pagecache_acct_shrink_used ( +unsigned long nr_pages) {return 0 ; } +#endif /* CONFIG_CONTAINER_PAGECACHE_ACCT */ + +#endif /* _LINUX_PAGECACHE_ACCT_H */ + +
init/Kconfig +7 -0
@@ -313,6 +313,13 @@ config CONTAINER_MEMCONTROL Provides a simple Resource Controller for monitoring and controlling the total Resident Set Size of the tasks in a container +config CONTAINER_PAGECACHE_ACCT + bool "Simple PageCache accounting & control container subsystem" + select CONTAINERS + help + Provides a simple Resource Controller for monitoring the + total pagecache memory consumed by the tasks in a container + config RELAY bool "Kernel->user space relay support (formerly relayfs)" help
mm/Makefile +1 -0
@@ -30,3 +30,4 @@ obj-$(CONFIG_FS_XIP) += filemap_xip.o obj-$(CONFIG_MIGRATION) += migrate.o obj-$(CONFIG_SMP) += allocpercpu.o obj-$(CONFIG_CONTAINER_MEMCONTROL) += memcontrol.o +obj-$(CONFIG_CONTAINER_PAGECACHE_ACCT) += pagecache_acct.o
mm/pagecache_acct.c new file +368 -0
368 lines not on this page · raw message
Re: [PATCH 2/3][RFC] Containers: Pagecache controller accounting
In reply to Vaidyanathan SrinivasanThe accounting framework works by adding a container pointer in address_space structure. Each page in pagecache belongs to a radix tree within the address_space structure corresponding to the inode.
In order to charge the container for pagecache usage, the corresponding address_space is obtained from struct page which holds the container pointer. This framework avoids any additional pointers in struct page.
additions and deletions from pagecache are hooked to charge and uncharge the corresponding container.
--- include/linux/fs.h | 4 ++++ mm/filemap.c | 8 ++++++++ 2 files changed, 12 insertions(+)
include/linux/fs.h +4 -0
@@ -447,6 +447,10 @@ struct address_space {spinlock_t private_lock;/* for use by the address_space */ struct list_head private_list;/* ditto */ struct address_space *assoc_mapping;/* ditto */ +#ifdef CONFIG_CONTAINER_PAGECACHE_ACCT +struct container *container;/* Charge page to the right container +using page->mapping */ +#endif } __attribute__((aligned(sizeof(long))));/* * On most architectures that alignment is already the case; but
mm/filemap.c +8 -0
@@ -30,6 +30,7 @@#include <linux/security.h> #include <linux/syscalls.h> #include <linux/cpuset.h> +#include <linux/pagecache_acct.h> #include "filemap.h" #include "internal.h"
@@ -117,6 +118,8 @@ void __remove_from_page_cache(struct pagstruct address_space *mapping = page->mapping;radix_tree_delete (&mapping->page_tree, page->index); +/* Uncharge before the mapping is gone */ +pagecache_acct_uncharge (page); page->mapping =NULL ; mapping->nrpages--;__dec_zone_page_state (page,NR_FILE_PAGES );
@@ -451,6 +454,11 @@ int add_to_page_cache(struct page *page,__inc_zone_page_state (page,NR_FILE_PAGES ); }write_unlock_irq (&mapping->tree_lock); +/* Unlock before charge, because we may reclaim this inline */ +if (!error) { +pagecache_acct_init_page_ptr (page); +pagecache_acct_charge (page); + }radix_tree_preload_end (); }return error;
RFC PATCH 3/3 Containers: Pagecache controller reclaim
In reply to Vaidyanathan SrinivasanThe reclaim code is similar to RSS memory controller. Scan control is slightly different since we are targeting different type of pages.
Additionally no mapped pages are touched when scanning for pagecache pages.
RSS memory controller and pagecache controller share common code in reclaim and hence pagecache controller patches are dependent on RSS memory controller patch even though the features are independently configurable at compile time.
--- include/linux/memcontrol.h | 6 +++ mm/memcontrol.c | 4 +- mm/pagecache_acct.c | 11 ++++++ mm/vmscan.c | 71 +++++++++++++++++++++++++++++++++++++-------- 4 files changed, 77 insertions(+), 15 deletions(-)
include/linux/memcontrol.h +6 -0
@@ -36,6 +36,12 @@ enum { MEMCONTROL_DONT_CHECK_LIMIT = false, }; +/* Type of memory to reclaim in shrink_container_memory() */ +enum { +RECLAIM_MAPPED_MEMORY =1 , +RECLAIM_PAGECACHE_MEMORY , +}; +#ifdef CONFIG_CONTAINER_MEMCONTROL #include <linux/wait.h>
mm/memcontrol.c +2 -2
@@ -165,8 +165,8 @@ static int memcontrol_check_and_reclaim( nr_pages = (pushback * limit) /100 ; mem->reclaim_in_progress = true;spin_unlock (&mem->lock); - nr_reclaimed += -memcontrol_shrink_mapped_memory (nr_pages, cont); + nr_reclaimed +=shrink_container_memory ( +RECLAIM_MAPPED_MEMORY , nr_pages, cont);spin_lock (&mem->lock); mem->reclaim_in_progress = false;wake_up_all (&mem->wq);
mm/pagecache_acct.c +10 -1
@@ -29,6 +29,7 @@#include <linux/uaccess.h> #include <asm/div64.h> #include <linux/pagecache_acct.h> +#include <linux/memcontrol.h> /* * Convert unit from pages to kilobytes
@@ -337,12 +338,20 @@ int pagecache_acct_cont_overlimit(structreturn 0 ; } -extern unsigned long shrink_all_pagecache_memory (unsigned long nr_pages); +extern unsigned long shrink_container_memory (unsigned int memory_type, +unsigned long nr_pages,void *container);int pagecache_acct_shrink_used (unsigned long nr_pages) {unsigned long ret =0 ;atomic_inc (&reclaim_count); + +/* Don't call reclaim for each page above limit */ +if (nr_pages >NR_PAGES_RECLAIM_THRESHOLD ) { + ret +=shrink_container_memory ( +RECLAIM_PAGECACHE_MEMORY , nr_pages,NULL ); + } +return 0 ; }
mm/vmscan.c +59 -12
168 lines not on this page · raw message
Re: [PATCH 3/3][RFC] Containers: Pagecache controller reclaim
Vaidyanathan Srinivasan <[email protected]> writes in gmane.linux.kernel,gmane.linux.kernel.mm:
Quoted 22 lines
mm/pagecache_acct.c +3
-1@@ -29,6 +29,7 @@#include <linux/uaccess.h> #include <asm/div64.h> #include <linux/pagecache_acct.h> +#include <linux/memcontrol.h> /* * Convert unit from pages to kilobytes @@ -337,12 +338,20 @@ int pagecache_acct_cont_overlimit(structreturn 0 ; } -extern unsigned long shrink_all_pagecache_memory (unsigned long nr_pages); +extern unsigned long shrink_container_memory (unsigned int memory_type, +unsigned long nr_pages,void *container);int pagecache_acct_shrink_used (unsigned long nr_pages) {unsigned long ret =0 ;atomic_inc (&reclaim_count);
mm/pagecache_acct.c int pagecache_acct_cont_overlimit(struct · line 357
Quoted 10 lines
mm/pagecache_acct.c +7
-0+ +/* Don't call reclaim for each page above limit */ +if (nr_pages >NR_PAGES_RECLAIM_THRESHOLD ) { + ret +=shrink_container_memory ( +RECLAIM_PAGECACHE_MEMORY , nr_pages,NULL ); + } +return 0 ; }
'ret' is not used ?
/ Kari Hurtta
Re: [PATCH 3/3][RFC] Containers: Pagecache controller reclaim
Quoted 21 lines · Kari Hurtta
Vaidyanathan Srinivasan <[email protected]> writes in gmane.linux.kernel,gmane.linux.kernel.mm:
Quoted 18 lines
mm/pagecache_acct.c +3
-1@@ -29,6 +29,7 @@#include <linux/uaccess.h> #include <asm/div64.h> #include <linux/pagecache_acct.h> +#include <linux/memcontrol.h> /* * Convert unit from pages to kilobytes @@ -337,12 +338,20 @@ int pagecache_acct_cont_overlimit(structreturn 0 ; } -extern unsigned long shrink_all_pagecache_memory (unsigned long nr_pages); +extern unsigned long shrink_container_memory (unsigned int memory_type, +unsigned long nr_pages,void *container);
Quoted 16 lines
Quoted 4 lines
mm/pagecache_acct.c +0
-0int pagecache_acct_shrink_used (unsigned long nr_pages) {unsigned long ret =0 ;atomic_inc (&reclaim_count);mm/pagecache_acct.c int pagecache_acct_cont_overlimit(struct · line 357
Quoted 10 lines
mm/pagecache_acct.c +7
-0+ +/* Don't call reclaim for each page above limit */ +if (nr_pages >NR_PAGES_RECLAIM_THRESHOLD ) { + ret +=shrink_container_memory ( +RECLAIM_PAGECACHE_MEMORY , nr_pages,NULL ); + } +return 0 ; }'ret' is not used ?
I have been setting watch points and tracing the value of ret. Basically that is used while debugging. I have not removed it since this is an RFC post and we would go through many cleanups cycles.
I will remember to remove it in the next version or verify that the compiler does remove 'ret' :)
--Vaidy
Quoted 8 lines
/ Kari Hurtta
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 3/3][RFC] Containers: Pagecache controller reclaim
In reply to Vaidyanathan SrinivasanQuoted 56 lines · Vaidyanathan Srinivasan
The reclaim code is similar to RSS memory controller. Scan control is slightly different since we are targeting different type of pages.
Additionally no mapped pages are touched when scanning for pagecache pages.
RSS memory controller and pagecache controller share common code in reclaim and hence pagecache controller patches are dependent on RSS memory controller patch even though the features are independently configurable at compile time.
mm/vmscan.c +14
-1@@ -43,6 +43,7 @@#include <linux/swapops.h> #include <linux/memcontrol.h> +#include <linux/pagecache_acct.h> #include "internal.h" @@ -70,6 +71,8 @@ struct scan_control {struct container *container;/* Used by containers for reclaiming */ /* pages when the limit is exceeded */ +int reclaim_pagecache_only;/* Set when called from +pagecache controller */ };/* @@ -474,6 +477,15 @@ static unsigned long shrink_page_list(st goto keep;VM_BUG_ON (PageActive (page)); +/* Take it easy if we are doing only pagecache pages */ +if (sc->reclaim_pagecache_only) { +/* Check if this is a pagecache page they are not mapped */ +if (page_mapped (page)) + goto keep_locked; +/* Check if this container has exceeded pagecache limit */ +if (!pagecache_acct_page_overlimit (page)) + goto keep_locked; + } sc->nr_scanned++;@@ -522,7 +534,8 @@ static unsigned long shrink_page_list(st }if (PageDirty (page)) { -if (referenced) +/* Reclaim even referenced pagecache pages if over limit */ +if (!pagecache_acct_page_overlimit (page) && referenced) goto keep_locked;if (!may_enter_fs) goto keep_locked;
mm/vmscan.c force_reclaim_mapped: · line 891
Quoted 10 lines
mm/vmscan.c +7
-0@@ -869,6 +882,13 @@ force_reclaim_mapped:cond_resched (); page =lru_to_page (&l_hold);list_del (&page->lru); +/* While reclaiming pagecache make it easy */ +if (sc->reclaim_pagecache_only) { +if (page_mapped (page) || !pagecache_acct_page_overlimit (page)) { +list_add (&page->lru, &l_active); +continue ; + } + }
Please correct me if I'm wrong.
Here, if page type is mapped or not overlimit, why add it back to active list? Did shrink_page_list() is called by shrink_inactive_list()?
-Aubrey
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 3/3][RFC] Containers: Pagecache controller reclaim
Quoted 62 lines · Aubrey Li
Quoted 61 lines · Vaidyanathan Srinivasan
The reclaim code is similar to RSS memory controller. Scan control is slightly different since we are targeting different type of pages.
Additionally no mapped pages are touched when scanning for pagecache pages.
RSS memory controller and pagecache controller share common code in reclaim and hence pagecache controller patches are dependent on RSS memory controller patch even though the features are independently configurable at compile time.
mm/vmscan.c +17
-1@@ -43,6 +43,7 @@#include <linux/swapops.h> #include <linux/memcontrol.h> +#include <linux/pagecache_acct.h> #include "internal.h" @@ -70,6 +71,8 @@ struct scan_control {struct container *container;/* Used by containers for reclaiming */ /* pages when the limit is exceeded */ +int reclaim_pagecache_only;/* Set when called from +pagecache controller */ };/* @@ -474,6 +477,15 @@ static unsigned long shrink_page_list(st goto keep;VM_BUG_ON (PageActive (page)); +/* Take it easy if we are doing only pagecache pages */ +if (sc->reclaim_pagecache_only) { +/* Check if this is a pagecache page they are not mapped */ +if (page_mapped (page)) + goto keep_locked; +/* Check if this container has exceeded pagecache limit */ +if (!pagecache_acct_page_overlimit (page)) + goto keep_locked; + } sc->nr_scanned++;@@ -522,7 +534,8 @@ static unsigned long shrink_page_list(st }if (PageDirty (page)) { -if (referenced) +/* Reclaim even referenced pagecache pages if over limit */ +if (!pagecache_acct_page_overlimit (page) && referenced) goto keep_locked;if (!may_enter_fs) goto keep_locked;@@ -869,6 +882,13 @@ force_reclaim_mapped:cond_resched (); page =lru_to_page (&l_hold);list_del (&page->lru); +/* While reclaiming pagecache make it easy */ +if (sc->reclaim_pagecache_only) { +if (page_mapped (page) || !pagecache_acct_page_overlimit (page)) {
Quoted 8 lines
mm/vmscan.c force_reclaim_mapped: · line 891
Quoted 4 lines
mm/vmscan.c +4
-0+list_add (&page->lru, &l_active); +continue ; + } + }Please correct me if I'm wrong.
Here, if page type is mapped or not overlimit, why add it back to active list? Didshrink_page_list()is called byshrink_inactive_list()?
Correct, shrink_page_list() is called from shrink_inactive_list() but the above code is patched in shrink_active_list(). The 'force_reclaim_mapped' label is from function shrink_active_list() and not in shrink_page_list() as it may seem in the patch file.
While removing pages from active_list, we want to select only pagecache pages and leave the remaining in the active_list. page_mapped() pages are _not_ of interest to pagecache controller (they will be taken care by rss controller) and hence we put it back.
Also if the pagecache controller is below limit, no need to reclaim
so we put back all pages and come out.
--Vaidy
Re: [PATCH 3/3][RFC] Containers: Pagecache controller reclaim
Quoted 11 lines · Vaidyanathan Srinivasan
Correct,
shrink_page_list()is called fromshrink_inactive_list()but the above code is patched inshrink_active_list(). The 'force_reclaim_mapped' label is from functionshrink_active_list()and not inshrink_page_list()as it may seem in the patch file.While removing pages from
active_list, we want to select only pagecache pages and leave the remaining in theactive_list.page_mapped()pages are _not_ of interest to pagecache controller (they will be taken care by rss controller) and hence we put it back.
Also if the pagecache controller is below limit, no need to reclaim
so we put back all pages and come out.
Oh, I just read the patch, not apply it to my local tree, I'm working on 2.6.19 now.
So the question is, when vfs pagecache limit is hit, the current implementation just reclaim few pages, so it's quite possible the limit is hit again, and hence the reclaim code will be called again and again, that will impact application performance.
-Aubrey
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 3/3][RFC] Containers: Pagecache controller reclaim
Quoted 13 lines · Aubrey Li
Quoted 11 lines · Vaidyanathan Srinivasan
Correct,
shrink_page_list()is called fromshrink_inactive_list()but the above code is patched inshrink_active_list(). The 'force_reclaim_mapped' label is from functionshrink_active_list()and not inshrink_page_list()as it may seem in the patch file.While removing pages from
active_list, we want to select only pagecache pages and leave the remaining in theactive_list.page_mapped()pages are _not_ of interest to pagecache controller (they will be taken care by rss controller) and hence we put it back.
Also if the pagecache controller is below limit, no need to reclaim
so we put back all pages and come out.
Quoted 6 lines
Oh, I just read the patch, not apply it to my local tree, I'm working on 2.6.19 now.
So the question is, when vfs pagecache limit is hit, the current implementation just reclaim few pages, so it's quite possible the limit is hit again, and hence the reclaim code will be called again and again, that will impact application performance.
Yes, you are correct. So if we start reclaiming one page at a time, then the cost of reclaim is very high and we would be calling the reclaim code too often. Hence we have a 'buffer zone' or 'reclaim threshold' or 'push back' around the limit. In the patch we have a 64 page (256KB) NR_PAGES_RECLAIM_THRESHOLD:
int pagecache_acct_shrink_used(unsigned long nr_pages) {
unsigned long ret = 0; atomic_inc(&reclaim_count);
+
+ /* Don't call reclaim for each page above limit */
+ if (nr_pages > NR_PAGES_RECLAIM_THRESHOLD) {
+ ret += shrink_container_memory(
+ RECLAIM_PAGECACHE_MEMORY, nr_pages, NULL);
+ }
+
return 0;
}
Hence we do not call the reclaimer if the threshold is exceeded by just 1 page... we wait for 64 pages or 256KB of pagecache memory to go
overlimit and then call the reclaimer which will reclaim all 64 pages
in one shot.
This prevents the reclaim code from being called too often and it also keeps the cost of reclaim low.
In future patches we are planing to have a percentage based reclaim threshold so that it would scale well with the container size.
--Vaidy
Re: [PATCH 3/3][RFC] Containers: Pagecache controller reclaim
Quoted 48 lines · Vaidyanathan Srinivasan
Quoted 13 lines · Aubrey Li
Quoted 11 lines · Vaidyanathan Srinivasan
Correct,
shrink_page_list()is called fromshrink_inactive_list()but the above code is patched inshrink_active_list(). The 'force_reclaim_mapped' label is from functionshrink_active_list()and not inshrink_page_list()as it may seem in the patch file.While removing pages from
active_list, we want to select only pagecache pages and leave the remaining in theactive_list.page_mapped()pages are _not_ of interest to pagecache controller (they will be taken care by rss controller) and hence we put it back.
Also if the pagecache controller is below limit, no need to reclaim
so we put back all pages and come out.Quoted 6 lines
Oh, I just read the patch, not apply it to my local tree, I'm working on 2.6.19 now.
So the question is, when vfs pagecache limit is hit, the current implementation just reclaim few pages, so it's quite possible the limit is hit again, and hence the reclaim code will be called again and again, that will impact application performance.Yes, you are correct. So if we start reclaiming one page at a time, then the cost of reclaim is very high and we would be calling the reclaim code too often. Hence we have a 'buffer zone' or 'reclaim threshold' or 'push back' around the limit. In the patch we have a 64 page (256KB)
NR_PAGES_RECLAIM_THRESHOLD:int
pagecache_acct_shrink_used(unsigned long nr_pages){ unsigned long ret = 0; atomic_inc(&reclaim_count);mm/pagecache_acct.c +7
-0+ +/* Don't call reclaim for each page above limit */ +if (nr_pages >NR_PAGES_RECLAIM_THRESHOLD ) { + ret +=shrink_container_memory ( +RECLAIM_PAGECACHE_MEMORY , nr_pages,NULL ); + } +return 0 ; }Hence we do not call the reclaimer if the threshold is exceeded by just 1 page... we wait for 64 pages or 256KB of pagecache memory to go
overlimit and then call the reclaimer which will reclaim all 64 pages
in one shot.
Quoted 6 lines
This prevents the reclaim code from being called too often and it also keeps the cost of reclaim low.
In future patches we are planing to have a percentage based reclaim threshold so that it would scale well with the container size.
Actually it's not a good idea IMHO. No matter how big the threshold is, it's not suitable. If it's too small, application performance will be impacted seriously after pagecache limit is hit. If it's too large, Limiting pagecache is useless.
Why not reclaim pages as much as possible when the pagecache limit is hit?
-Aubrey
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 3/3][RFC] Containers: Pagecache controller reclaim
Quoted 57 lines · Aubrey Li
Quoted 45 lines · Vaidyanathan Srinivasan
Quoted 12 lines · Aubrey Li
Quoted 11 lines · Vaidyanathan Srinivasan
Correct,
shrink_page_list()is called fromshrink_inactive_list()but the above code is patched inshrink_active_list(). The 'force_reclaim_mapped' label is from functionshrink_active_list()and not inshrink_page_list()as it may seem in the patch file.While removing pages from
active_list, we want to select only pagecache pages and leave the remaining in theactive_list.page_mapped()pages are _not_ of interest to pagecache controller (they will be taken care by rss controller) and hence we put it back.
Also if the pagecache controller is below limit, no need to reclaim
so we put back all pages and come out.Quoted 6 lines
Oh, I just read the patch, not apply it to my local tree, I'm working on 2.6.19 now.
So the question is, when vfs pagecache limit is hit, the current implementation just reclaim few pages, so it's quite possible the limit is hit again, and hence the reclaim code will be called again and again, that will impact application performance.Yes, you are correct. So if we start reclaiming one page at a time, then the cost of reclaim is very high and we would be calling the reclaim code too often. Hence we have a 'buffer zone' or 'reclaim threshold' or 'push back' around the limit. In the patch we have a 64 page (256KB)
NR_PAGES_RECLAIM_THRESHOLD:int
pagecache_acct_shrink_used(unsigned long nr_pages){ unsigned long ret = 0; atomic_inc(&reclaim_count);mm/pagecache_acct.c +7
-0+ +/* Don't call reclaim for each page above limit */ +if (nr_pages >NR_PAGES_RECLAIM_THRESHOLD ) { + ret +=shrink_container_memory ( +RECLAIM_PAGECACHE_MEMORY , nr_pages,NULL ); + } +return 0 ; }Hence we do not call the reclaimer if the threshold is exceeded by just 1 page... we wait for 64 pages or 256KB of pagecache memory to go
overlimit and then call the reclaimer which will reclaim all 64 pages
in one shot.Quoted 6 lines
This prevents the reclaim code from being called too often and it also keeps the cost of reclaim low.
In future patches we are planing to have a percentage based reclaim threshold so that it would scale well with the container size.
Actually it's not a good idea IMHO. No matter how big the threshold is, it's not suitable. If it's too small, application performance will be impacted seriously after pagecache limit is hit. If it's too large, Limiting pagecache is useless.
Quoted 2 lines
Why not reclaim pages as much as possible when the pagecache limit is hit?
Well, that seems to be a good suggestion. We will try it out by asking the reclaimer to do as much as possible in minimum time/effort.
However we have to figure out how hard we want to push the reclaimer. In fact we can push the shrink_active_list() andshrink_inactive_list() routines to reclaim the _all_ container pages.
We do have reclaim priority to play with. Let see if we can comeup
with some automatic method to reclaim 'good' number of pages each time.
--Vaidy