From 3aa1dc772547672e6ff453117d169c47a5a7cbc5 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 14 Aug 2002 21:20:48 -0700 Subject: [PATCH] multithread page reclaim This patch multithreads the main page reclaim function, shrink_cache(). This function used to run under pagemap_lru_lock. Instead, we grab that lock, put 32 pages from the LRU into a private list, drop the pagemap_lru_lock and then proceed to attempt to free those pages. Any pages which were succesfully reclaimed are batch-freed. Pages which were not reclaimed are re-added to the LRU. This patch reduces pagemap_lru_lock contention on the 4-way by a factor of thirty. The shrink_cache() code has been simplified somewhat. refill_inactive() was being called too often - often just to process two or three pages. Fiddled with that so it processes pages at the same rate, but works on 32 pages at a time. Added a couple of mark_page_accessed() calls into mm/memory.c from 2.4. They seem appropriate. Change the shrink_caches() logic so that it will still trickle through the active list (via refill_inactive) even if the inactive list is much larger than the active list. --- include/linux/mm.h | 1 + include/linux/page-flags.h | 2 ++ include/linux/swap.h | 9 +++++++-- 3 files changed, 10 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mm.h b/include/linux/mm.h index baafd9a57b25..df42d899e41f 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -195,6 +195,7 @@ struct page { */ #define get_page(p) atomic_inc(&(p)->count) #define put_page(p) __free_page(p) +#define __put_page(p) atomic_dec(&(p)->count) #define put_page_testzero(p) atomic_dec_and_test(&(p)->count) #define page_count(p) atomic_read(&(p)->count) #define set_page_count(p,v) atomic_set(&(p)->count, v) diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index f6b48a987cd4..9801b15876d9 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -154,6 +154,7 @@ extern void get_page_state(struct page_state *ret); ret; \ }) +#define SetPageLRU(page) set_bit(PG_lru, &(page)->flags) #define PageLRU(page) test_bit(PG_lru, &(page)->flags) #define TestSetPageLRU(page) test_and_set_bit(PG_lru, &(page)->flags) #define TestClearPageLRU(page) test_and_clear_bit(PG_lru, &(page)->flags) @@ -161,6 +162,7 @@ extern void get_page_state(struct page_state *ret); #define PageActive(page) test_bit(PG_active, &(page)->flags) #define SetPageActive(page) set_bit(PG_active, &(page)->flags) #define ClearPageActive(page) clear_bit(PG_active, &(page)->flags) +#define TestClearPageActive(page) test_and_clear_bit(PG_active, &(page)->flags) #define PageSlab(page) test_bit(PG_slab, &(page)->flags) #define SetPageSlab(page) set_bit(PG_slab, &(page)->flags) diff --git a/include/linux/swap.h b/include/linux/swap.h index b3bae533a6a4..8dbd9d7e401d 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -227,12 +227,17 @@ do { \ BUG(); \ } while (0) +#define __add_page_to_active_list(page) \ +do { \ + list_add(&(page)->lru, &active_list); \ + inc_page_state(nr_active); \ +} while (0) + #define add_page_to_active_list(page) \ do { \ DEBUG_LRU_PAGE(page); \ SetPageActive(page); \ - list_add(&(page)->lru, &active_list); \ - inc_page_state(nr_active); \ + __add_page_to_active_list(page); \ } while (0) #define add_page_to_inactive_list(page) \ -- cgit v1.2.3