diff options
author | Christoph Lameter <clameter@sgi.com> | 2006-06-30 04:55:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-30 14:25:35 -0400 |
commit | b1e7a8fd854d2f895730e82137400012b509650e (patch) | |
tree | 9fba87ff6b0146ebd4ee5bc7d5f0c8b037dbb3ad | |
parent | df849a1529c106f7460e51479ca78fe07b07dc8c (diff) |
[PATCH] zoned vm counters: conversion of nr_dirty to per zone counter
This makes nr_dirty a per zone counter. Looping over all processors is
avoided during writeback state determination.
The counter aggregation for nr_dirty had to be undone in the NFS layer since
we summed up the page counts from multiple zones. Someone more familiar with
NFS should probably review what I have done.
[akpm@osdl.org: bugfix]
Signed-off-by: Christoph Lameter <clameter@sgi.com>
Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | arch/i386/mm/pgtable.c | 2 | ||||
-rw-r--r-- | drivers/base/node.c | 4 | ||||
-rw-r--r-- | fs/buffer.c | 2 | ||||
-rw-r--r-- | fs/fs-writeback.c | 2 | ||||
-rw-r--r-- | fs/nfs/pagelist.c | 1 | ||||
-rw-r--r-- | fs/nfs/write.c | 3 | ||||
-rw-r--r-- | fs/proc/proc_misc.c | 2 | ||||
-rw-r--r-- | include/linux/mmzone.h | 1 | ||||
-rw-r--r-- | include/linux/vmstat.h | 1 | ||||
-rw-r--r-- | mm/page-writeback.c | 11 | ||||
-rw-r--r-- | mm/page_alloc.c | 2 | ||||
-rw-r--r-- | mm/vmstat.c | 2 |
12 files changed, 16 insertions, 17 deletions
diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c index 0bb1e5c13442..aa211dcddb08 100644 --- a/arch/i386/mm/pgtable.c +++ b/arch/i386/mm/pgtable.c | |||
@@ -59,7 +59,7 @@ void show_mem(void) | |||
59 | printk(KERN_INFO "%d pages swap cached\n", cached); | 59 | printk(KERN_INFO "%d pages swap cached\n", cached); |
60 | 60 | ||
61 | get_page_state(&ps); | 61 | get_page_state(&ps); |
62 | printk(KERN_INFO "%lu pages dirty\n", ps.nr_dirty); | 62 | printk(KERN_INFO "%lu pages dirty\n", global_page_state(NR_FILE_DIRTY)); |
63 | printk(KERN_INFO "%lu pages writeback\n", ps.nr_writeback); | 63 | printk(KERN_INFO "%lu pages writeback\n", ps.nr_writeback); |
64 | printk(KERN_INFO "%lu pages mapped\n", global_page_state(NR_FILE_MAPPED)); | 64 | printk(KERN_INFO "%lu pages mapped\n", global_page_state(NR_FILE_MAPPED)); |
65 | printk(KERN_INFO "%lu pages slab\n", global_page_state(NR_SLAB)); | 65 | printk(KERN_INFO "%lu pages slab\n", global_page_state(NR_SLAB)); |
diff --git a/drivers/base/node.c b/drivers/base/node.c index c22fb67ec50c..6fed520d00f4 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
@@ -50,8 +50,6 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf) | |||
50 | __get_zone_counts(&active, &inactive, &free, NODE_DATA(nid)); | 50 | __get_zone_counts(&active, &inactive, &free, NODE_DATA(nid)); |
51 | 51 | ||
52 | /* Check for negative values in these approximate counters */ | 52 | /* Check for negative values in these approximate counters */ |
53 | if ((long)ps.nr_dirty < 0) | ||
54 | ps.nr_dirty = 0; | ||
55 | if ((long)ps.nr_writeback < 0) | 53 | if ((long)ps.nr_writeback < 0) |
56 | ps.nr_writeback = 0; | 54 | ps.nr_writeback = 0; |
57 | 55 | ||
@@ -81,7 +79,7 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf) | |||
81 | nid, K(i.freehigh), | 79 | nid, K(i.freehigh), |
82 | nid, K(i.totalram - i.totalhigh), | 80 | nid, K(i.totalram - i.totalhigh), |
83 | nid, K(i.freeram - i.freehigh), | 81 | nid, K(i.freeram - i.freehigh), |
84 | nid, K(ps.nr_dirty), | 82 | nid, K(node_page_state(nid, NR_FILE_DIRTY)), |
85 | nid, K(ps.nr_writeback), | 83 | nid, K(ps.nr_writeback), |
86 | nid, K(node_page_state(nid, NR_FILE_PAGES)), | 84 | nid, K(node_page_state(nid, NR_FILE_PAGES)), |
87 | nid, K(node_page_state(nid, NR_FILE_MAPPED)), | 85 | nid, K(node_page_state(nid, NR_FILE_MAPPED)), |
diff --git a/fs/buffer.c b/fs/buffer.c index e9994722f4a3..90e52e677209 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -852,7 +852,7 @@ int __set_page_dirty_buffers(struct page *page) | |||
852 | write_lock_irq(&mapping->tree_lock); | 852 | write_lock_irq(&mapping->tree_lock); |
853 | if (page->mapping) { /* Race with truncate? */ | 853 | if (page->mapping) { /* Race with truncate? */ |
854 | if (mapping_cap_account_dirty(mapping)) | 854 | if (mapping_cap_account_dirty(mapping)) |
855 | inc_page_state(nr_dirty); | 855 | __inc_zone_page_state(page, NR_FILE_DIRTY); |
856 | radix_tree_tag_set(&mapping->page_tree, | 856 | radix_tree_tag_set(&mapping->page_tree, |
857 | page_index(page), | 857 | page_index(page), |
858 | PAGECACHE_TAG_DIRTY); | 858 | PAGECACHE_TAG_DIRTY); |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 031b27a4bc9a..e5ad10756848 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -464,7 +464,7 @@ void sync_inodes_sb(struct super_block *sb, int wait) | |||
464 | .range_start = 0, | 464 | .range_start = 0, |
465 | .range_end = LLONG_MAX, | 465 | .range_end = LLONG_MAX, |
466 | }; | 466 | }; |
467 | unsigned long nr_dirty = read_page_state(nr_dirty); | 467 | unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY); |
468 | unsigned long nr_unstable = read_page_state(nr_unstable); | 468 | unsigned long nr_unstable = read_page_state(nr_unstable); |
469 | 469 | ||
470 | wbc.nr_to_write = nr_dirty + nr_unstable + | 470 | wbc.nr_to_write = nr_dirty + nr_unstable + |
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index d89f6fb3b3a3..26b1fe909377 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c | |||
@@ -315,6 +315,7 @@ nfs_scan_lock_dirty(struct nfs_inode *nfsi, struct list_head *dst, | |||
315 | req->wb_index, NFS_PAGE_TAG_DIRTY); | 315 | req->wb_index, NFS_PAGE_TAG_DIRTY); |
316 | nfs_list_remove_request(req); | 316 | nfs_list_remove_request(req); |
317 | nfs_list_add_request(req, dst); | 317 | nfs_list_add_request(req, dst); |
318 | dec_zone_page_state(req->wb_page, NR_FILE_DIRTY); | ||
318 | res++; | 319 | res++; |
319 | } | 320 | } |
320 | } | 321 | } |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 8fccb9cb173b..a6d1ca513dde 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -497,7 +497,7 @@ nfs_mark_request_dirty(struct nfs_page *req) | |||
497 | nfs_list_add_request(req, &nfsi->dirty); | 497 | nfs_list_add_request(req, &nfsi->dirty); |
498 | nfsi->ndirty++; | 498 | nfsi->ndirty++; |
499 | spin_unlock(&nfsi->req_lock); | 499 | spin_unlock(&nfsi->req_lock); |
500 | inc_page_state(nr_dirty); | 500 | inc_zone_page_state(req->wb_page, NR_FILE_DIRTY); |
501 | mark_inode_dirty(inode); | 501 | mark_inode_dirty(inode); |
502 | } | 502 | } |
503 | 503 | ||
@@ -609,7 +609,6 @@ nfs_scan_dirty(struct inode *inode, struct list_head *dst, unsigned long idx_sta | |||
609 | if (nfsi->ndirty != 0) { | 609 | if (nfsi->ndirty != 0) { |
610 | res = nfs_scan_lock_dirty(nfsi, dst, idx_start, npages); | 610 | res = nfs_scan_lock_dirty(nfsi, dst, idx_start, npages); |
611 | nfsi->ndirty -= res; | 611 | nfsi->ndirty -= res; |
612 | sub_page_state(nr_dirty,res); | ||
613 | if ((nfsi->ndirty == 0) != list_empty(&nfsi->dirty)) | 612 | if ((nfsi->ndirty == 0) != list_empty(&nfsi->dirty)) |
614 | printk(KERN_ERR "NFS: desynchronized value of nfs_i.ndirty.\n"); | 613 | printk(KERN_ERR "NFS: desynchronized value of nfs_i.ndirty.\n"); |
615 | } | 614 | } |
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 0eae68f84210..e23717dec3c1 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c | |||
@@ -190,7 +190,7 @@ static int meminfo_read_proc(char *page, char **start, off_t off, | |||
190 | K(i.freeram-i.freehigh), | 190 | K(i.freeram-i.freehigh), |
191 | K(i.totalswap), | 191 | K(i.totalswap), |
192 | K(i.freeswap), | 192 | K(i.freeswap), |
193 | K(ps.nr_dirty), | 193 | K(global_page_state(NR_FILE_DIRTY)), |
194 | K(ps.nr_writeback), | 194 | K(ps.nr_writeback), |
195 | K(global_page_state(NR_ANON_PAGES)), | 195 | K(global_page_state(NR_ANON_PAGES)), |
196 | K(global_page_state(NR_FILE_MAPPED)), | 196 | K(global_page_state(NR_FILE_MAPPED)), |
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 15adb435f240..1cc8412ac264 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h | |||
@@ -53,6 +53,7 @@ enum zone_stat_item { | |||
53 | NR_FILE_PAGES, | 53 | NR_FILE_PAGES, |
54 | NR_SLAB, /* Pages used by slab allocator */ | 54 | NR_SLAB, /* Pages used by slab allocator */ |
55 | NR_PAGETABLE, /* used for pagetables */ | 55 | NR_PAGETABLE, /* used for pagetables */ |
56 | NR_FILE_DIRTY, | ||
56 | NR_VM_ZONE_STAT_ITEMS }; | 57 | NR_VM_ZONE_STAT_ITEMS }; |
57 | 58 | ||
58 | struct per_cpu_pages { | 59 | struct per_cpu_pages { |
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 56220441d7c9..b323ea2c6260 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h | |||
@@ -22,7 +22,6 @@ | |||
22 | * commented here. | 22 | * commented here. |
23 | */ | 23 | */ |
24 | struct page_state { | 24 | struct page_state { |
25 | unsigned long nr_dirty; /* Dirty writeable pages */ | ||
26 | unsigned long nr_writeback; /* Pages under writeback */ | 25 | unsigned long nr_writeback; /* Pages under writeback */ |
27 | unsigned long nr_unstable; /* NFS unstable pages */ | 26 | unsigned long nr_unstable; /* NFS unstable pages */ |
28 | #define GET_PAGE_STATE_LAST nr_unstable | 27 | #define GET_PAGE_STATE_LAST nr_unstable |
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 0faacfe18909..da8547830098 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -109,7 +109,7 @@ struct writeback_state | |||
109 | 109 | ||
110 | static void get_writeback_state(struct writeback_state *wbs) | 110 | static void get_writeback_state(struct writeback_state *wbs) |
111 | { | 111 | { |
112 | wbs->nr_dirty = read_page_state(nr_dirty); | 112 | wbs->nr_dirty = global_page_state(NR_FILE_DIRTY); |
113 | wbs->nr_unstable = read_page_state(nr_unstable); | 113 | wbs->nr_unstable = read_page_state(nr_unstable); |
114 | wbs->nr_mapped = global_page_state(NR_FILE_MAPPED) + | 114 | wbs->nr_mapped = global_page_state(NR_FILE_MAPPED) + |
115 | global_page_state(NR_ANON_PAGES); | 115 | global_page_state(NR_ANON_PAGES); |
@@ -641,7 +641,8 @@ int __set_page_dirty_nobuffers(struct page *page) | |||
641 | if (mapping2) { /* Race with truncate? */ | 641 | if (mapping2) { /* Race with truncate? */ |
642 | BUG_ON(mapping2 != mapping); | 642 | BUG_ON(mapping2 != mapping); |
643 | if (mapping_cap_account_dirty(mapping)) | 643 | if (mapping_cap_account_dirty(mapping)) |
644 | inc_page_state(nr_dirty); | 644 | __inc_zone_page_state(page, |
645 | NR_FILE_DIRTY); | ||
645 | radix_tree_tag_set(&mapping->page_tree, | 646 | radix_tree_tag_set(&mapping->page_tree, |
646 | page_index(page), PAGECACHE_TAG_DIRTY); | 647 | page_index(page), PAGECACHE_TAG_DIRTY); |
647 | } | 648 | } |
@@ -728,9 +729,9 @@ int test_clear_page_dirty(struct page *page) | |||
728 | radix_tree_tag_clear(&mapping->page_tree, | 729 | radix_tree_tag_clear(&mapping->page_tree, |
729 | page_index(page), | 730 | page_index(page), |
730 | PAGECACHE_TAG_DIRTY); | 731 | PAGECACHE_TAG_DIRTY); |
731 | write_unlock_irqrestore(&mapping->tree_lock, flags); | ||
732 | if (mapping_cap_account_dirty(mapping)) | 732 | if (mapping_cap_account_dirty(mapping)) |
733 | dec_page_state(nr_dirty); | 733 | __dec_zone_page_state(page, NR_FILE_DIRTY); |
734 | write_unlock_irqrestore(&mapping->tree_lock, flags); | ||
734 | return 1; | 735 | return 1; |
735 | } | 736 | } |
736 | write_unlock_irqrestore(&mapping->tree_lock, flags); | 737 | write_unlock_irqrestore(&mapping->tree_lock, flags); |
@@ -761,7 +762,7 @@ int clear_page_dirty_for_io(struct page *page) | |||
761 | if (mapping) { | 762 | if (mapping) { |
762 | if (TestClearPageDirty(page)) { | 763 | if (TestClearPageDirty(page)) { |
763 | if (mapping_cap_account_dirty(mapping)) | 764 | if (mapping_cap_account_dirty(mapping)) |
764 | dec_page_state(nr_dirty); | 765 | dec_zone_page_state(page, NR_FILE_DIRTY); |
765 | return 1; | 766 | return 1; |
766 | } | 767 | } |
767 | return 0; | 768 | return 0; |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index ed3f2a7b4071..c2b9aa4acc46 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -1314,7 +1314,7 @@ void show_free_areas(void) | |||
1314 | "unstable:%lu free:%u slab:%lu mapped:%lu pagetables:%lu\n", | 1314 | "unstable:%lu free:%u slab:%lu mapped:%lu pagetables:%lu\n", |
1315 | active, | 1315 | active, |
1316 | inactive, | 1316 | inactive, |
1317 | ps.nr_dirty, | 1317 | global_page_state(NR_FILE_DIRTY), |
1318 | ps.nr_writeback, | 1318 | ps.nr_writeback, |
1319 | ps.nr_unstable, | 1319 | ps.nr_unstable, |
1320 | nr_free_pages(), | 1320 | nr_free_pages(), |
diff --git a/mm/vmstat.c b/mm/vmstat.c index 292a35fe56c9..1982fb533a40 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c | |||
@@ -400,9 +400,9 @@ static char *vmstat_text[] = { | |||
400 | "nr_file_pages", | 400 | "nr_file_pages", |
401 | "nr_slab", | 401 | "nr_slab", |
402 | "nr_page_table_pages", | 402 | "nr_page_table_pages", |
403 | "nr_dirty", | ||
403 | 404 | ||
404 | /* Page state */ | 405 | /* Page state */ |
405 | "nr_dirty", | ||
406 | "nr_writeback", | 406 | "nr_writeback", |
407 | "nr_unstable", | 407 | "nr_unstable", |
408 | 408 | ||