From: Andrew Morton Modify balance_dirty_pages_ratelimited() so that it can take a number-of-pages-which-I-just-dirtied argument. For msync(). Signed-off-by: Andrew Morton --- include/linux/writeback.h | 10 +++++++++- mm/page-writeback.c | 24 +++++++++++++++--------- 2 files changed, 24 insertions(+), 10 deletions(-) diff -puN mm/page-writeback.c~balance_dirty_pages_ratelimited-take-nr_pages-arg mm/page-writeback.c --- devel/mm/page-writeback.c~balance_dirty_pages_ratelimited-take-nr_pages-arg 2006-02-10 14:22:33.000000000 -0800 +++ devel-akpm/mm/page-writeback.c 2006-02-10 14:22:33.000000000 -0800 @@ -256,8 +256,9 @@ static void balance_dirty_pages(struct a } /** - * balance_dirty_pages_ratelimited - balance dirty memory state + * balance_dirty_pages_ratelimited_nr - balance dirty memory state * @mapping: address_space which was dirtied + * @nr_pages: number of pages which the caller has just dirtied * * Processes which are dirtying memory should call in here once for each page * which was newly dirtied. The function will periodically check the system's @@ -268,10 +269,12 @@ static void balance_dirty_pages(struct a * limit we decrease the ratelimiting by a lot, to prevent individual processes * from overshooting the limit by (ratelimit_pages) each. */ -void balance_dirty_pages_ratelimited(struct address_space *mapping) +void balance_dirty_pages_ratelimited_nr(struct address_space *mapping, + unsigned long nr_pages_dirtied) { - static DEFINE_PER_CPU(int, ratelimits) = 0; - long ratelimit; + static DEFINE_PER_CPU(unsigned long, ratelimits) = 0; + unsigned long ratelimit; + unsigned long *p; ratelimit = ratelimit_pages; if (dirty_exceeded) @@ -281,15 +284,18 @@ void balance_dirty_pages_ratelimited(str * Check the rate limiting. Also, we do not want to throttle real-time * tasks in balance_dirty_pages(). Period. */ - if (get_cpu_var(ratelimits)++ >= ratelimit) { - __get_cpu_var(ratelimits) = 0; - put_cpu_var(ratelimits); + preempt_disable(); + p = &__get_cpu_var(ratelimits); + *p += nr_pages_dirtied; + if (unlikely(*p >= ratelimit)) { + *p = 0; + preempt_enable(); balance_dirty_pages(mapping); return; } - put_cpu_var(ratelimits); + preempt_enable(); } -EXPORT_SYMBOL(balance_dirty_pages_ratelimited); +EXPORT_SYMBOL(balance_dirty_pages_ratelimited_nr); void throttle_vm_writeout(void) { diff -puN include/linux/writeback.h~balance_dirty_pages_ratelimited-take-nr_pages-arg include/linux/writeback.h --- devel/include/linux/writeback.h~balance_dirty_pages_ratelimited-take-nr_pages-arg 2006-02-10 14:22:33.000000000 -0800 +++ devel-akpm/include/linux/writeback.h 2006-02-10 14:22:33.000000000 -0800 @@ -99,7 +99,15 @@ int dirty_writeback_centisecs_handler(st void __user *, size_t *, loff_t *); void page_writeback_init(void); -void balance_dirty_pages_ratelimited(struct address_space *mapping); +void balance_dirty_pages_ratelimited_nr(struct address_space *mapping, + unsigned long nr_pages_dirtied); + +static inline void +balance_dirty_pages_ratelimited(struct address_space *mapping) +{ + balance_dirty_pages_ratelimited_nr(mapping, 1); +} + int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0); int do_writepages(struct address_space *mapping, struct writeback_control *wbc); int sync_page_range(struct inode *inode, struct address_space *mapping, _