diff -urN vm-ref/fs/exec.c vm/fs/exec.c --- vm-ref/fs/exec.c Sun Nov 18 07:24:48 2001 +++ vm/fs/exec.c Sun Nov 18 07:25:03 2001 @@ -275,7 +275,6 @@ goto out; if (!pte_none(*pte)) goto out; - lru_cache_add(page); flush_dcache_page(page); flush_page_to_ram(page); set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page, PAGE_COPY)))); diff -urN vm-ref/include/linux/pagemap.h vm/include/linux/pagemap.h --- vm-ref/include/linux/pagemap.h Sun Nov 18 07:24:53 2001 +++ vm/include/linux/pagemap.h Sun Nov 18 07:25:03 2001 @@ -29,7 +29,7 @@ #define PAGE_CACHE_ALIGN(addr) (((addr)+PAGE_CACHE_SIZE-1)&PAGE_CACHE_MASK) #define page_cache_get(x) get_page(x) -extern void FASTCALL(page_cache_release(struct page *)); +#define page_cache_release(x) __free_page(x) static inline struct page *page_cache_alloc(struct address_space *x) { diff -urN vm-ref/include/linux/swap.h vm/include/linux/swap.h --- vm-ref/include/linux/swap.h Sun Nov 18 07:24:53 2001 +++ vm/include/linux/swap.h Sun Nov 18 07:25:03 2001 @@ -176,6 +176,8 @@ BUG(); \ if (PageActive(page)) \ BUG(); \ + if (page_count(page) <= 0) \ + BUG(); \ } while (0) #define inc_nr_active_pages(page) \ @@ -262,12 +264,14 @@ list_del(&(page)->lru); \ ClearPageActive(page); \ dec_nr_active_pages(page); \ + DEBUG_LRU_PAGE(page); \ } while (0) #define del_page_from_inactive_list(page) \ do { \ list_del(&(page)->lru); \ dec_nr_inactive_pages(page); \ + DEBUG_LRU_PAGE(page); \ } while (0) #define inc_nr_cache_pages(page) \ diff -urN vm-ref/kernel/ksyms.c vm/kernel/ksyms.c --- vm-ref/kernel/ksyms.c Sun Nov 18 07:24:53 2001 +++ vm/kernel/ksyms.c Sun Nov 18 07:25:03 2001 @@ -95,7 +95,6 @@ EXPORT_SYMBOL(alloc_pages_node); EXPORT_SYMBOL(__get_free_pages); EXPORT_SYMBOL(get_zeroed_page); -EXPORT_SYMBOL(page_cache_release); EXPORT_SYMBOL(__free_pages); EXPORT_SYMBOL(free_pages); EXPORT_SYMBOL(free_exact); diff -urN vm-ref/mm/memory.c vm/mm/memory.c --- vm-ref/mm/memory.c Sun Nov 18 07:24:53 2001 +++ vm/mm/memory.c Sun Nov 18 07:25:03 2001 @@ -952,7 +952,6 @@ if (PageReserved(old_page)) ++mm->rss; break_cow(vma, new_page, address, page_table); - lru_cache_add(new_page); /* Free the old page.. */ new_page = old_page; @@ -1183,7 +1182,6 @@ mm->rss++; flush_page_to_ram(page); entry = pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot))); - lru_cache_add(page); } set_pte(page_table, entry); @@ -1235,7 +1233,6 @@ return -1; copy_user_highpage(page, new_page, address); page_cache_release(new_page); - lru_cache_add(page); new_page = page; } diff -urN vm-ref/mm/page_alloc.c vm/mm/page_alloc.c --- vm-ref/mm/page_alloc.c Sun Nov 18 07:24:53 2001 +++ vm/mm/page_alloc.c Sun Nov 18 07:25:03 2001 @@ -446,15 +446,6 @@ return 0; } -void page_cache_release(struct page *page) -{ - if (!PageReserved(page) && put_page_testzero(page)) { - if (PageLRU(page)) - lru_cache_del(page); - __free_pages_ok(page, 0); - } -} - void __free_pages(struct page *page, unsigned int order) { if (!PageReserved(page) && put_page_testzero(page)) diff -urN vm-ref/mm/shmem.c vm/mm/shmem.c --- vm-ref/mm/shmem.c Sun Nov 18 06:04:47 2001 +++ vm/mm/shmem.c Sun Nov 18 07:25:03 2001 @@ -449,6 +449,7 @@ BUG(); /* Remove it from the page cache */ + lru_cache_del(page); remove_inode_page(page); page_cache_release(page); diff -urN vm-ref/mm/swap.c vm/mm/swap.c --- vm-ref/mm/swap.c Sun Nov 18 07:24:53 2001 +++ vm/mm/swap.c Sun Nov 18 07:25:05 2001 @@ -61,11 +61,13 @@ */ void lru_cache_add(struct page * page) { - if (!TestSetPageLRU(page)) { - spin_lock(&pagemap_lru_lock); - add_page_to_inactive_list(page); - spin_unlock(&pagemap_lru_lock); - } + if (unlikely(!PageLocked(page))) + BUG(); + spin_lock(&pagemap_lru_lock); + if (unlikely(TestSetPageLRU(page))) + BUG(); + add_page_to_inactive_list(page); + spin_unlock(&pagemap_lru_lock); } /** @@ -77,13 +79,13 @@ */ void __lru_cache_del(struct page * page) { - if (TestClearPageLRU(page)) { - if (PageActive(page)) { - del_page_from_active_list(page); - } else { - del_page_from_inactive_list(page); - } + if (PageActive(page)) { + del_page_from_active_list(page); + } else { + del_page_from_inactive_list(page); } + if (unlikely(!TestClearPageLRU(page))) + BUG(); } /** @@ -92,6 +94,9 @@ */ void lru_cache_del(struct page * page) { + if (unlikely(!PageLocked(page))) + BUG(); + spin_lock(&pagemap_lru_lock); __lru_cache_del(page); spin_unlock(&pagemap_lru_lock); diff -urN vm-ref/mm/swap_state.c vm/mm/swap_state.c --- vm-ref/mm/swap_state.c Sun Nov 18 07:24:53 2001 +++ vm/mm/swap_state.c Sun Nov 18 07:25:03 2001 @@ -120,6 +120,7 @@ if (!block_flushpage(page, 0)) /* an anonymous page cannot have page->buffers set */ BUG(); + lru_cache_del(page); entry.val = page->index; diff -urN vm-ref/mm/swapfile.c vm/mm/swapfile.c --- vm-ref/mm/swapfile.c Sun Nov 18 07:24:53 2001 +++ vm/mm/swapfile.c Sun Nov 18 07:25:03 2001 @@ -322,9 +322,12 @@ return 0; entry.val = page->index; + spin_lock(&pagemap_lru_lock); p = swap_info_get(entry); - if (unlikely(!p)) + if (unlikely(!p)) { + spin_unlock(&pagemap_lru_lock); return 0; + } /* Is the only swap cache user the cache itself? */ retval = 0; @@ -335,6 +338,7 @@ if (page->buffers && !try_to_free_buffers(page, 0)) /* an anonymous page cannot have page->buffers set */ BUG(); + __lru_cache_del(page); __delete_from_swap_cache(page); swap_entry_free(p, SWP_OFFSET(entry)); SetPageDirty(page); @@ -343,6 +347,7 @@ spin_unlock(&pagecache_lock); } swap_info_put(p); + spin_unlock(&pagemap_lru_lock); if (retval) page_cache_release(page); diff -urN vm-ref/mm/vmscan.c vm/mm/vmscan.c --- vm-ref/mm/vmscan.c Sun Nov 18 07:24:53 2001 +++ vm/mm/vmscan.c Sun Nov 18 07:25:03 2001 @@ -37,7 +37,7 @@ * "vm_mapped_ratio" controls when we start to swapout, the lower, * the earlier we'll start to swapout. */ -int vm_mapped_ratio = 100; +int vm_mapped_ratio = 50; /* * "vm_lru_balance_ratio" controls the balance between active and