Index: linux-2.6.13-ck5/mm/swap_prefetch.c =================================================================== --- linux-2.6.13-ck5.orig/mm/swap_prefetch.c 2005-09-20 23:33:34.000000000 +1000 +++ linux-2.6.13-ck5/mm/swap_prefetch.c 2005-09-22 22:05:00.000000000 +1000 @@ -20,13 +20,13 @@ #define PREFETCH_INTERVAL (HZ) struct swapped_root_t { + int busy; + spinlock_t busylock; spinlock_t lock; + struct list_head list; unsigned int count; unsigned int maxcount; kmem_cache_t *cache; - struct list_head list; - int busy; - spinlock_t busylock; }; struct swapped_entry_t { @@ -35,8 +35,8 @@ struct swapped_entry_t { }; static struct swapped_root_t swapped_root = { - .count = 0, .list = LIST_HEAD_INIT(swapped_root.list), + .count = 0, }; static struct timer_list prefetch_timer; @@ -175,7 +175,7 @@ static struct page * prefetch_get_page(v (GFP_HIGHUSER & GFP_ZONEMASK); for_each_zone(z) { - if (z->name == "DMA" || z->present_pages == 0) + if (zone_idx(z) == ZONE_DMA || z->present_pages == 0) continue; page = buffered_rmqueue(z, 0, GFP_HIGHUSER); if (page) @@ -248,7 +248,7 @@ out: */ static int prefetch_suitable(void) { - unsigned long pending_writes; + unsigned long pending_writes, limit; struct zone *z; if (test_clear_busy()) @@ -264,10 +264,6 @@ static int prefetch_suitable(void) if (pending_writes > SWAP_CLUSTER_MAX) goto out_delay; - /* >2/3 of the ram is mapped, we need some free for pagecache */ - if (read_page_state(nr_mapped) > mapped_limit) - goto out_delay; - /* * Have some hysteresis between where page reclaiming and prefetching * will occur to prevent ping-ponging between them. @@ -279,6 +275,22 @@ static int prefetch_suitable(void) goto out_delay; } + /* >2/3 of the ram is mapped, we need some free for pagecache */ + limit = read_page_state(nr_mapped); + if (limit > mapped_limit) + goto out_delay; + + /* + * Add swapcache to limit as well, but check this last since it needs + * locking + */ + if (unlikely(!read_trylock(&swapper_space.tree_lock))) + goto out_delay; + limit += total_swapcache_pages; + read_unlock(&swapper_space.tree_lock); + if (limit > mapped_limit) + goto out_delay; + /* Survived all that? Hooray we can prefetch! */ return 1;