Originally posted by Hephasteus
View Post

--- /usr/src/sources/kernel/zen-upstream/mm/vmscan.c 2010-07-21 17:01:20.911512995 +0200 +++ mm/vmscan.c 2010-08-04 22:11:43.663379966 +0200 @@ -1113,6 +1113,47 @@ } /* + * Returns true if the caller should wait to clean dirty/writeback pages. + * + * If we are direct reclaiming for contiguous pages and we do not reclaim + * everything in the list, try again and wait for writeback IO to complete. + * This will stall high-order allocations noticeably. Only do that when really + * need to free the pages under high memory pressure. + */ +static inline bool should_reclaim_stall(unsigned long nr_taken, + unsigned long nr_freed, + int priority, + struct scan_control *sc) +{ + int lumpy_stall_priority; + + /* kswapd should not stall on sync IO */ + if (current_is_kswapd()) + return false; + + /* Only stall on lumpy reclaim */ + if (!sc->lumpy_reclaim_mode) + return false; + + /* If we have relaimed everything on the isolated list, no stall */ + if (nr_freed == nr_taken) + return false; + + /* + * For high-order allocations, there are two stall thresholds. + * High-cost allocations stall immediately where as lower + * order allocations such as stacks require the scanning + * priority to be much higher before stalling. + */ + if (sc->order > PAGE_ALLOC_COSTLY_ORDER) + lumpy_stall_priority = DEF_PRIORITY; + else + lumpy_stall_priority = DEF_PRIORITY / 3; + + return priority <= lumpy_stall_priority; +} + +/* * shrink_inactive_list() is a helper for shrink_zone(). It returns the number * of reclaimed pages */ @@ -1202,15 +1243,8 @@ nr_scanned += nr_scan; nr_freed = shrink_page_list(&page_list, sc, PAGEOUT_IO_ASYNC); - /* - * If we are direct reclaiming for contiguous pages and we do - * not reclaim everything in the list, try again and wait - * for IO to complete. This will stall high-order allocations - * but that should be acceptable to the caller - */ - if (nr_freed < nr_taken && !current_is_kswapd() && - sc->lumpy_reclaim_mode) { - congestion_wait(BLK_RW_ASYNC, HZ/10); + /* Check if we should syncronously wait for writeback */ + if (should_reclaim_stall(nr_taken, nr_freed, priority, sc)) { /* * The attempt at page out may have made some
File to patch: mm/vmscan.c patching file mm/vmscan.c Hunk #1 succeeded at 1112 (offset -1 lines). Hunk #2 succeeded at 1242 (offset -1 lines).
File to patch: mm/vmscan.c patching file mm/vmscan.c Hunk #1 succeeded at 1112 (offset -1 lines). Hunk #2 succeeded at 1242 (offset -1 lines).
dd if=/dev/zero of=test bs=1M count=5024 && rm test -f
Comment