mm/page-writeback.c | 33 ++++++++++++++++++++++++--------- 1 files changed, 24 insertions(+), 9 deletions(-) diff -puN mm/page-writeback.c~throttle-against-free-memory mm/page-writeback.c --- git-linux/mm/page-writeback.c~throttle-against-free-memory 2005-10-24 13:46:25.000000000 +0400 +++ git-linux-nikita/mm/page-writeback.c 2005-10-24 13:46:25.000000000 +0400 @@ -45,7 +45,6 @@ */ static long ratelimit_pages = 32; -static long total_pages; /* The total number of pages in the machine. */ static int dirty_exceeded; /* Dirty mem may be over limit */ /* @@ -117,6 +116,18 @@ static void get_writeback_state(struct w wbs->nr_async_writeback = read_page_state(nr_async_writeback); } +/* Maximal number of pages that can be consumed by pageable caches. */ +static unsigned long total_pageable_pages(void) +{ + unsigned long active; + unsigned long inactive; + unsigned long free; + + get_zone_counts(&active, &inactive, &free); + /* +1 to never return 0. */ + return active + inactive + free + 1; +} + /* * Work out the current dirty-memory clamping and background writeout * thresholds. @@ -143,21 +154,27 @@ get_dirty_limits(struct writeback_state int unmapped_ratio; long background; long dirty; - unsigned long available_memory = total_pages; + unsigned long total_pages; + unsigned long available_memory; struct task_struct *tsk; get_writeback_state(wbs); + available_memory = total_pages = total_pageable_pages(); + #ifdef CONFIG_HIGHMEM /* * If this mapping can only allocate from low memory, * we exclude high memory from our count. */ - if (mapping && !(mapping_gfp_mask(mapping) & __GFP_HIGHMEM)) - available_memory -= totalhigh_pages; + if (mapping && !(mapping_gfp_mask(mapping) & __GFP_HIGHMEM)) { + if (available_memory > totalhigh_pages) + available_memory -= totalhigh_pages; + else + available_memory = 1; + } #endif - unmapped_ratio = 100 - (wbs->nr_mapped * 100) / total_pages; dirty_ratio = vm_dirty_ratio; @@ -510,7 +527,7 @@ void laptop_sync_completion(void) static void set_ratelimit(void) { - ratelimit_pages = total_pages / (num_online_cpus() * 32); + ratelimit_pages = total_pageable_pages() / (num_online_cpus() * 32); if (ratelimit_pages < 16) ratelimit_pages = 16; if (ratelimit_pages * PAGE_CACHE_SIZE > 4096 * 1024) @@ -539,9 +556,7 @@ void __init page_writeback_init(void) long buffer_pages = nr_free_buffer_pages(); long correction; - total_pages = nr_free_pagecache_pages(); - - correction = (100 * 4 * buffer_pages) / total_pages; + correction = (100 * 4 * buffer_pages) / total_pageable_pages(); if (correction < 100) { dirty_background_ratio *= correction; _