Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d3bc1fef authored by Wu Fengguang's avatar Wu Fengguang
Browse files

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
Loading
Loading
Loading
Loading
+5 −8
Original line number Diff line number Diff line
@@ -1258,8 +1258,6 @@ void balance_dirty_pages_ratelimited_nr(struct address_space *mapping,
	if (bdi->dirty_exceeded)
		ratelimit = min(ratelimit, 32 >> (PAGE_SHIFT - 10));

	current->nr_dirtied += nr_pages_dirtied;

	preempt_disable();
	/*
	 * 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,
	p =  &__get_cpu_var(bdp_ratelimits);
	if (unlikely(current->nr_dirtied >= ratelimit))
		*p = 0;
	else {
		*p += nr_pages_dirtied;
		if (unlikely(*p >= ratelimit_pages)) {
	else if (unlikely(*p >= ratelimit_pages)) {
		*p = 0;
		ratelimit = 0;
	}
	}
	/*
	 * Pick up the dirtied pages by the exited tasks. This avoids lots of
	 * 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)
		__inc_bdi_stat(mapping->backing_dev_info, BDI_RECLAIMABLE);
		__inc_bdi_stat(mapping->backing_dev_info, BDI_DIRTIED);
		task_io_account_write(PAGE_CACHE_SIZE);
		current->nr_dirtied++;
		this_cpu_inc(bdp_ratelimits);
	}
}
EXPORT_SYMBOL(account_page_dirtied);