From: Jerome Marchand <jmarchan@redhat.com> Date: Tue, 3 Mar 2009 17:27:26 +0100 Subject: [misc] IO accounting: write accounting Message-id: 20090303162957.654984299@dhcp-0-152.brq.redhat.com O-Subject: [RHEL5.4 Patch 04/12] IO accounting: write accounting Bugzilla: 461636 RH-Acked-by: Jiri Pirko <jpirko@redhat.com> bz461636 Accounting writes is fairly simple: whenever a process flips a page from clean to dirty, we accuse it of having caused a write to underlying storage of PAGE_CACHE_SIZE bytes. This may overestimate the amount of writing: the page-dirtying may cause only one buffer_head's worth of writeout. Fixing that is possible, but probably a bit messy and isn't obviously important. Patch is upstream commit 55e829af06681e5d731c03ba04febbd1c76ca293 diff --git a/fs/buffer.c b/fs/buffer.c index eb2c148..80c238d 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -35,6 +35,7 @@ #include <linux/hash.h> #include <linux/suspend.h> #include <linux/buffer_head.h> +#include <linux/task_io_accounting_ops.h> #include <linux/bio.h> #include <linux/notifier.h> #include <linux/cpu.h> @@ -861,8 +862,10 @@ int __set_page_dirty_buffers(struct page *page) if (!TestSetPageDirty(page)) { write_lock_irq(&mapping->tree_lock); if (page->mapping) { /* Race with truncate? */ - if (mapping_cap_account_dirty(mapping)) + if (mapping_cap_account_dirty(mapping)) { __inc_zone_page_state(page, NR_FILE_DIRTY); + task_io_account_write(PAGE_CACHE_SIZE); + } radix_tree_tag_set(&mapping->page_tree, page_index(page), PAGECACHE_TAG_DIRTY); diff --git a/mm/page-writeback.c b/mm/page-writeback.c index cb415a8..4fa0f54 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -21,6 +21,7 @@ #include <linux/writeback.h> #include <linux/init.h> #include <linux/backing-dev.h> +#include <linux/task_io_accounting_ops.h> #include <linux/blkdev.h> #include <linux/mpage.h> #include <linux/percpu.h> @@ -636,9 +637,11 @@ int __set_page_dirty_nobuffers(struct page *page) mapping2 = page_mapping(page); if (mapping2) { /* Race with truncate? */ BUG_ON(mapping2 != mapping); - if (mapping_cap_account_dirty(mapping)) + if (mapping_cap_account_dirty(mapping)) { __inc_zone_page_state(page, NR_FILE_DIRTY); + task_io_account_write(PAGE_CACHE_SIZE); + } radix_tree_tag_set(&mapping->page_tree, page_index(page), PAGECACHE_TAG_DIRTY); }