Commit 972d1a7b authored by Christoph Lameter's avatar Christoph Lameter Committed by Linus Torvalds

[PATCH] ZVC: Support NR_SLAB_RECLAIMABLE / NR_SLAB_UNRECLAIMABLE

Remove the atomic counter for slab_reclaim_pages and replace the counter
and NR_SLAB with two ZVC counter that account for unreclaimable and
reclaimable slab pages: NR_SLAB_RECLAIMABLE and NR_SLAB_UNRECLAIMABLE.

Change the check in vmscan.c to refer to to NR_SLAB_RECLAIMABLE.  The
intend seems to be to check for slab pages that could be freed.
Signed-off-by: default avatarChristoph Lameter <clameter@sgi.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 8417bba4
...@@ -60,7 +60,9 @@ void show_mem(void) ...@@ -60,7 +60,9 @@ void show_mem(void)
printk(KERN_INFO "%lu pages writeback\n", printk(KERN_INFO "%lu pages writeback\n",
global_page_state(NR_WRITEBACK)); global_page_state(NR_WRITEBACK));
printk(KERN_INFO "%lu pages mapped\n", global_page_state(NR_FILE_MAPPED)); printk(KERN_INFO "%lu pages mapped\n", global_page_state(NR_FILE_MAPPED));
printk(KERN_INFO "%lu pages slab\n", global_page_state(NR_SLAB)); printk(KERN_INFO "%lu pages slab\n",
global_page_state(NR_SLAB_RECLAIMABLE) +
global_page_state(NR_SLAB_UNRECLAIMABLE));
printk(KERN_INFO "%lu pages pagetables\n", printk(KERN_INFO "%lu pages pagetables\n",
global_page_state(NR_PAGETABLE)); global_page_state(NR_PAGETABLE));
} }
......
...@@ -68,7 +68,9 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf) ...@@ -68,7 +68,9 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf)
"Node %d PageTables: %8lu kB\n" "Node %d PageTables: %8lu kB\n"
"Node %d NFS_Unstable: %8lu kB\n" "Node %d NFS_Unstable: %8lu kB\n"
"Node %d Bounce: %8lu kB\n" "Node %d Bounce: %8lu kB\n"
"Node %d Slab: %8lu kB\n", "Node %d Slab: %8lu kB\n"
"Node %d SReclaimable: %8lu kB\n"
"Node %d SUnreclaim: %8lu kB\n",
nid, K(i.totalram), nid, K(i.totalram),
nid, K(i.freeram), nid, K(i.freeram),
nid, K(i.totalram - i.freeram), nid, K(i.totalram - i.freeram),
...@@ -88,7 +90,10 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf) ...@@ -88,7 +90,10 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf)
nid, K(node_page_state(nid, NR_PAGETABLE)), nid, K(node_page_state(nid, NR_PAGETABLE)),
nid, K(node_page_state(nid, NR_UNSTABLE_NFS)), nid, K(node_page_state(nid, NR_UNSTABLE_NFS)),
nid, K(node_page_state(nid, NR_BOUNCE)), nid, K(node_page_state(nid, NR_BOUNCE)),
nid, K(node_page_state(nid, NR_SLAB))); nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE) +
node_page_state(nid, NR_SLAB_UNRECLAIMABLE)),
nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE)),
nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE)));
n += hugetlb_report_node_meminfo(nid, buf + n); n += hugetlb_report_node_meminfo(nid, buf + n);
return n; return n;
} }
......
...@@ -170,6 +170,8 @@ static int meminfo_read_proc(char *page, char **start, off_t off, ...@@ -170,6 +170,8 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
"AnonPages: %8lu kB\n" "AnonPages: %8lu kB\n"
"Mapped: %8lu kB\n" "Mapped: %8lu kB\n"
"Slab: %8lu kB\n" "Slab: %8lu kB\n"
"SReclaimable: %8lu kB\n"
"SUnreclaim: %8lu kB\n"
"PageTables: %8lu kB\n" "PageTables: %8lu kB\n"
"NFS_Unstable: %8lu kB\n" "NFS_Unstable: %8lu kB\n"
"Bounce: %8lu kB\n" "Bounce: %8lu kB\n"
...@@ -197,7 +199,10 @@ static int meminfo_read_proc(char *page, char **start, off_t off, ...@@ -197,7 +199,10 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
K(global_page_state(NR_WRITEBACK)), K(global_page_state(NR_WRITEBACK)),
K(global_page_state(NR_ANON_PAGES)), K(global_page_state(NR_ANON_PAGES)),
K(global_page_state(NR_FILE_MAPPED)), K(global_page_state(NR_FILE_MAPPED)),
K(global_page_state(NR_SLAB)), K(global_page_state(NR_SLAB_RECLAIMABLE) +
global_page_state(NR_SLAB_UNRECLAIMABLE)),
K(global_page_state(NR_SLAB_RECLAIMABLE)),
K(global_page_state(NR_SLAB_UNRECLAIMABLE)),
K(global_page_state(NR_PAGETABLE)), K(global_page_state(NR_PAGETABLE)),
K(global_page_state(NR_UNSTABLE_NFS)), K(global_page_state(NR_UNSTABLE_NFS)),
K(global_page_state(NR_BOUNCE)), K(global_page_state(NR_BOUNCE)),
......
...@@ -51,7 +51,8 @@ enum zone_stat_item { ...@@ -51,7 +51,8 @@ enum zone_stat_item {
NR_FILE_MAPPED, /* pagecache pages mapped into pagetables. NR_FILE_MAPPED, /* pagecache pages mapped into pagetables.
only modified from process context */ only modified from process context */
NR_FILE_PAGES, NR_FILE_PAGES,
NR_SLAB, /* Pages used by slab allocator */ NR_SLAB_RECLAIMABLE,
NR_SLAB_UNRECLAIMABLE,
NR_PAGETABLE, /* used for pagetables */ NR_PAGETABLE, /* used for pagetables */
NR_FILE_DIRTY, NR_FILE_DIRTY,
NR_WRITEBACK, NR_WRITEBACK,
......
...@@ -284,8 +284,6 @@ extern kmem_cache_t *fs_cachep; ...@@ -284,8 +284,6 @@ extern kmem_cache_t *fs_cachep;
extern kmem_cache_t *sighand_cachep; extern kmem_cache_t *sighand_cachep;
extern kmem_cache_t *bio_cachep; extern kmem_cache_t *bio_cachep;
extern atomic_t slab_reclaim_pages;
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _LINUX_SLAB_H */ #endif /* _LINUX_SLAB_H */
...@@ -116,7 +116,7 @@ int __vm_enough_memory(long pages, int cap_sys_admin) ...@@ -116,7 +116,7 @@ int __vm_enough_memory(long pages, int cap_sys_admin)
* which are reclaimable, under pressure. The dentry * which are reclaimable, under pressure. The dentry
* cache and most inode caches should fall into this * cache and most inode caches should fall into this
*/ */
free += atomic_read(&slab_reclaim_pages); free += global_page_state(NR_SLAB_RECLAIMABLE);
/* /*
* Leave the last 3% for root * Leave the last 3% for root
......
...@@ -1133,7 +1133,7 @@ int __vm_enough_memory(long pages, int cap_sys_admin) ...@@ -1133,7 +1133,7 @@ int __vm_enough_memory(long pages, int cap_sys_admin)
* which are reclaimable, under pressure. The dentry * which are reclaimable, under pressure. The dentry
* cache and most inode caches should fall into this * cache and most inode caches should fall into this
*/ */
free += atomic_read(&slab_reclaim_pages); free += global_page_state(NR_SLAB_RECLAIMABLE);
/* /*
* Leave the last 3% for root * Leave the last 3% for root
......
...@@ -1304,7 +1304,8 @@ void show_free_areas(void) ...@@ -1304,7 +1304,8 @@ void show_free_areas(void)
global_page_state(NR_WRITEBACK), global_page_state(NR_WRITEBACK),
global_page_state(NR_UNSTABLE_NFS), global_page_state(NR_UNSTABLE_NFS),
nr_free_pages(), nr_free_pages(),
global_page_state(NR_SLAB), global_page_state(NR_SLAB_RECLAIMABLE) +
global_page_state(NR_SLAB_UNRECLAIMABLE),
global_page_state(NR_FILE_MAPPED), global_page_state(NR_FILE_MAPPED),
global_page_state(NR_PAGETABLE)); global_page_state(NR_PAGETABLE));
......
...@@ -735,14 +735,6 @@ static inline void init_lock_keys(void) ...@@ -735,14 +735,6 @@ static inline void init_lock_keys(void)
static DEFINE_MUTEX(cache_chain_mutex); static DEFINE_MUTEX(cache_chain_mutex);
static struct list_head cache_chain; static struct list_head cache_chain;
/*
* vm_enough_memory() looks at this to determine how many slab-allocated pages
* are possibly freeable under pressure
*
* SLAB_RECLAIM_ACCOUNT turns this on per-slab
*/
atomic_t slab_reclaim_pages;
/* /*
* chicken and egg problem: delay the per-cpu array allocation * chicken and egg problem: delay the per-cpu array allocation
* until the general caches are up. * until the general caches are up.
...@@ -1580,8 +1572,11 @@ static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid) ...@@ -1580,8 +1572,11 @@ static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid)
nr_pages = (1 << cachep->gfporder); nr_pages = (1 << cachep->gfporder);
if (cachep->flags & SLAB_RECLAIM_ACCOUNT) if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
atomic_add(nr_pages, &slab_reclaim_pages); add_zone_page_state(page_zone(page),
add_zone_page_state(page_zone(page), NR_SLAB, nr_pages); NR_SLAB_RECLAIMABLE, nr_pages);
else
add_zone_page_state(page_zone(page),
NR_SLAB_UNRECLAIMABLE, nr_pages);
for (i = 0; i < nr_pages; i++) for (i = 0; i < nr_pages; i++)
__SetPageSlab(page + i); __SetPageSlab(page + i);
return page_address(page); return page_address(page);
...@@ -1596,7 +1591,12 @@ static void kmem_freepages(struct kmem_cache *cachep, void *addr) ...@@ -1596,7 +1591,12 @@ static void kmem_freepages(struct kmem_cache *cachep, void *addr)
struct page *page = virt_to_page(addr); struct page *page = virt_to_page(addr);
const unsigned long nr_freed = i; const unsigned long nr_freed = i;
sub_zone_page_state(page_zone(page), NR_SLAB, nr_freed); if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
sub_zone_page_state(page_zone(page),
NR_SLAB_RECLAIMABLE, nr_freed);
else
sub_zone_page_state(page_zone(page),
NR_SLAB_UNRECLAIMABLE, nr_freed);
while (i--) { while (i--) {
BUG_ON(!PageSlab(page)); BUG_ON(!PageSlab(page));
__ClearPageSlab(page); __ClearPageSlab(page);
...@@ -1605,8 +1605,6 @@ static void kmem_freepages(struct kmem_cache *cachep, void *addr) ...@@ -1605,8 +1605,6 @@ static void kmem_freepages(struct kmem_cache *cachep, void *addr)
if (current->reclaim_state) if (current->reclaim_state)
current->reclaim_state->reclaimed_slab += nr_freed; current->reclaim_state->reclaimed_slab += nr_freed;
free_pages((unsigned long)addr, cachep->gfporder); free_pages((unsigned long)addr, cachep->gfporder);
if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
atomic_sub(1 << cachep->gfporder, &slab_reclaim_pages);
} }
static void kmem_rcu_free(struct rcu_head *head) static void kmem_rcu_free(struct rcu_head *head)
......
...@@ -339,7 +339,3 @@ void kmem_cache_init(void) ...@@ -339,7 +339,3 @@ void kmem_cache_init(void)
mod_timer(&slob_timer, jiffies + HZ); mod_timer(&slob_timer, jiffies + HZ);
} }
atomic_t slab_reclaim_pages = ATOMIC_INIT(0);
EXPORT_SYMBOL(slab_reclaim_pages);
...@@ -1378,7 +1378,7 @@ unsigned long shrink_all_memory(unsigned long nr_pages) ...@@ -1378,7 +1378,7 @@ unsigned long shrink_all_memory(unsigned long nr_pages)
for_each_zone(zone) for_each_zone(zone)
lru_pages += zone->nr_active + zone->nr_inactive; lru_pages += zone->nr_active + zone->nr_inactive;
nr_slab = global_page_state(NR_SLAB); nr_slab = global_page_state(NR_SLAB_RECLAIMABLE);
/* If slab caches are huge, it's better to hit them first */ /* If slab caches are huge, it's better to hit them first */
while (nr_slab >= lru_pages) { while (nr_slab >= lru_pages) {
reclaim_state.reclaimed_slab = 0; reclaim_state.reclaimed_slab = 0;
......
...@@ -458,7 +458,8 @@ static char *vmstat_text[] = { ...@@ -458,7 +458,8 @@ static char *vmstat_text[] = {
"nr_anon_pages", "nr_anon_pages",
"nr_mapped", "nr_mapped",
"nr_file_pages", "nr_file_pages",
"nr_slab", "nr_slab_reclaimable",
"nr_slab_unreclaimable",
"nr_page_table_pages", "nr_page_table_pages",
"nr_dirty", "nr_dirty",
"nr_writeback", "nr_writeback",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment