--- linux-2.4.17-pre8/mm/filemap.c.orig Tue Dec 11 16:11:16 2001 +++ linux-2.4.17-pre8/mm/filemap.c Tue Dec 11 16:27:44 2001 @@ -1249,23 +1249,20 @@ } /* - * Mark a page as having seen activity. - * - * If it was already so marked, move it - * to the active queue and drop the referenced - * bit. Otherwise, just mark it for future - * action.. + * Simple second-chance replacement. + * As long as a page is on the active list, further references + * are ignored so used-once pages get replaced quickly. + * If a page on the inactive list gets referenced or has a + * referenced bit in the page table page, it gets moved back + * to the far end of the active list. */ void mark_page_accessed(struct page *page) { - if (!PageActive(page) && PageReferenced(page)) { + if (PageLRU(page) && !PageActive(page)) { activate_page(page); ClearPageReferenced(page); return; } - - /* Mark the page referenced, AFTER checking for previous usage.. */ - SetPageReferenced(page); } /* --- linux-2.4.17-pre8/mm/swap.c.orig Tue Dec 11 16:11:16 2001 +++ linux-2.4.17-pre8/mm/swap.c Tue Dec 11 16:13:11 2001 @@ -59,7 +59,7 @@ { if (!TestSetPageLRU(page)) { spin_lock(&pagemap_lru_lock); - add_page_to_inactive_list(page); + add_page_to_active_list(page); spin_unlock(&pagemap_lru_lock); } } --- linux-2.4.17-pre8/mm/vmscan.c.orig Tue Dec 11 16:11:16 2001 +++ linux-2.4.17-pre8/mm/vmscan.c Tue Dec 11 16:43:10 2001 @@ -526,10 +526,14 @@ /* * This moves pages from the active list to - * the inactive list. + * the inactive list. If they get referenced + * while on the inactive list, they will be + * activated again. * - * We move them the other way when we see the - * reference bit on the page. + * Note that we cannot (and don't want to) + * clear the referenced bits in the page tables + * of pages, so the working sets of processes + * have an edge on cache pages. */ static void refill_inactive(int nr_pages) { @@ -542,15 +546,10 @@ page = list_entry(entry, struct page, lru); entry = entry->prev; - if (PageTestandClearReferenced(page)) { - list_del(&page->lru); - list_add(&page->lru, &active_list); - continue; - } del_page_from_active_list(page); add_page_to_inactive_list(page); - SetPageReferenced(page); + ClearPageReferenced(page); } spin_unlock(&pagemap_lru_lock); } @@ -570,16 +569,16 @@ ratio = (unsigned long) nr_pages * nr_active_pages / ((nr_inactive_pages + 1) * 2); refill_inactive(ratio); - nr_pages = shrink_cache(nr_pages, classzone, gfp_mask, priority); - if (nr_pages <= 0) - return 0; - shrink_dcache_memory(priority, gfp_mask); shrink_icache_memory(priority, gfp_mask); #ifdef CONFIG_QUOTA shrink_dqcache_memory(DEF_PRIORITY, gfp_mask); #endif + nr_pages = shrink_cache(nr_pages, classzone, gfp_mask, priority); + + if (nr_pages <= 0) + return 0; return nr_pages; }