Commit d3bc1fef authored by Wu Fengguang's avatar Wu Fengguang

writeback: fix dirtied pages accounting on sub-page writes

When dd in 512bytes, generic_perform_write() calls
balance_dirty_pages_ratelimited() 8 times for the same page, but
obviously the page is only dirtied once.

Fix it by accounting tsk->nr_dirtied and bdp_ratelimits at page dirty time.
Acked-by: default avatarJan Kara <jack@suse.cz>
Acked-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: default avatarWu Fengguang <fengguang.wu@intel.com>
parent 54848d73
...@@ -1258,8 +1258,6 @@ void balance_dirty_pages_ratelimited_nr(struct address_space *mapping, ...@@ -1258,8 +1258,6 @@ void balance_dirty_pages_ratelimited_nr(struct address_space *mapping,
if (bdi->dirty_exceeded) if (bdi->dirty_exceeded)
ratelimit = min(ratelimit, 32 >> (PAGE_SHIFT - 10)); ratelimit = min(ratelimit, 32 >> (PAGE_SHIFT - 10));
current->nr_dirtied += nr_pages_dirtied;
preempt_disable(); preempt_disable();
/* /*
* This prevents one CPU to accumulate too many dirtied pages without * This prevents one CPU to accumulate too many dirtied pages without
...@@ -1270,13 +1268,10 @@ void balance_dirty_pages_ratelimited_nr(struct address_space *mapping, ...@@ -1270,13 +1268,10 @@ void balance_dirty_pages_ratelimited_nr(struct address_space *mapping,
p = &__get_cpu_var(bdp_ratelimits); p = &__get_cpu_var(bdp_ratelimits);
if (unlikely(current->nr_dirtied >= ratelimit)) if (unlikely(current->nr_dirtied >= ratelimit))
*p = 0; *p = 0;
else { else if (unlikely(*p >= ratelimit_pages)) {
*p += nr_pages_dirtied;
if (unlikely(*p >= ratelimit_pages)) {
*p = 0; *p = 0;
ratelimit = 0; ratelimit = 0;
} }
}
/* /*
* Pick up the dirtied pages by the exited tasks. This avoids lots of * Pick up the dirtied pages by the exited tasks. This avoids lots of
* short-lived tasks (eg. gcc invocations in a kernel build) escaping * short-lived tasks (eg. gcc invocations in a kernel build) escaping
...@@ -1768,6 +1763,8 @@ void account_page_dirtied(struct page *page, struct address_space *mapping) ...@@ -1768,6 +1763,8 @@ void account_page_dirtied(struct page *page, struct address_space *mapping)
__inc_bdi_stat(mapping->backing_dev_info, BDI_RECLAIMABLE); __inc_bdi_stat(mapping->backing_dev_info, BDI_RECLAIMABLE);
__inc_bdi_stat(mapping->backing_dev_info, BDI_DIRTIED); __inc_bdi_stat(mapping->backing_dev_info, BDI_DIRTIED);
task_io_account_write(PAGE_CACHE_SIZE); task_io_account_write(PAGE_CACHE_SIZE);
current->nr_dirtied++;
this_cpu_inc(bdp_ratelimits);
} }
} }
EXPORT_SYMBOL(account_page_dirtied); EXPORT_SYMBOL(account_page_dirtied);
......
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