X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=mm%2Fpage-writeback.c;h=624ce500fb169a8f3cc9f275fd26fc0f13dc3612;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=343998d46bb03344d27845a79b6c20096e1508ca;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 343998d46..624ce500f 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -133,17 +133,29 @@ static void get_writeback_state(struct writeback_state *wbs) * clamping level. */ static void -get_dirty_limits(struct writeback_state *wbs, long *pbackground, long *pdirty) +get_dirty_limits(struct writeback_state *wbs, long *pbackground, long *pdirty, + struct address_space *mapping) { int background_ratio; /* Percentages */ int dirty_ratio; int unmapped_ratio; long background; long dirty; + unsigned long available_memory = total_pages; struct task_struct *tsk; get_writeback_state(wbs); +#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; +#endif + + unmapped_ratio = 100 - (wbs->nr_mapped * 100) / total_pages; dirty_ratio = vm_dirty_ratio; @@ -157,8 +169,8 @@ get_dirty_limits(struct writeback_state *wbs, long *pbackground, long *pdirty) if (background_ratio >= dirty_ratio) background_ratio = dirty_ratio / 2; - background = (background_ratio * total_pages) / 100; - dirty = (dirty_ratio * total_pages) / 100; + background = (background_ratio * available_memory) / 100; + dirty = (dirty_ratio * available_memory) / 100; tsk = current; if (tsk->flags & PF_LESS_THROTTLE || rt_task(tsk)) { background += background / 4; @@ -194,7 +206,8 @@ static void balance_dirty_pages(struct address_space *mapping) .nr_to_write = write_chunk, }; - get_dirty_limits(&wbs, &background_thresh, &dirty_thresh); + get_dirty_limits(&wbs, &background_thresh, + &dirty_thresh, mapping); nr_reclaimable = wbs.nr_dirty + wbs.nr_unstable; if (nr_reclaimable + wbs.nr_writeback <= dirty_thresh) break; @@ -210,7 +223,7 @@ static void balance_dirty_pages(struct address_space *mapping) if (nr_reclaimable) { writeback_inodes(&wbc); get_dirty_limits(&wbs, &background_thresh, - &dirty_thresh); + &dirty_thresh, mapping); nr_reclaimable = wbs.nr_dirty + wbs.nr_unstable; if (nr_reclaimable + wbs.nr_writeback <= dirty_thresh) break; @@ -296,7 +309,7 @@ static void background_writeout(unsigned long _min_pages) long background_thresh; long dirty_thresh; - get_dirty_limits(&wbs, &background_thresh, &dirty_thresh); + get_dirty_limits(&wbs, &background_thresh, &dirty_thresh, NULL); if (wbs.nr_dirty + wbs.nr_unstable < background_thresh && min_pages <= 0) break; @@ -504,6 +517,11 @@ void __init page_writeback_init(void) dirty_background_ratio /= 100; vm_dirty_ratio *= correction; vm_dirty_ratio /= 100; + + if (dirty_background_ratio <= 0) + dirty_background_ratio = 1; + if (vm_dirty_ratio <= 0) + vm_dirty_ratio = 1; } mod_timer(&wb_timer, jiffies + (dirty_writeback_centisecs * HZ) / 100); set_ratelimit(); @@ -580,12 +598,13 @@ int __set_page_dirty_nobuffers(struct page *page) if (!TestSetPageDirty(page)) { struct address_space *mapping = page_mapping(page); + struct address_space *mapping2; if (mapping) { spin_lock_irq(&mapping->tree_lock); - mapping = page_mapping(page); - if (page_mapping(page)) { /* Race with truncate? */ - BUG_ON(page_mapping(page) != mapping); + mapping2 = page_mapping(page); + if (mapping2) { /* Race with truncate? */ + BUG_ON(mapping2 != mapping); if (!mapping->backing_dev_info->memory_backed) inc_page_state(nr_dirty); radix_tree_tag_set(&mapping->page_tree,