--- ./kernel/sysctl.c.~1~ 2003-09-16 20:44:14.000000000 -0400 +++ ./kernel/sysctl.c 2003-09-21 00:49:32.000000000 -0400 @@ -281,6 +281,8 @@ &vm_gfp_debug, sizeof(int), 0644, NULL, &proc_dointvec}, {VM_VFS_SCAN_RATIO, "vm_vfs_scan_ratio", &vm_vfs_scan_ratio, sizeof(int), 0644, NULL, &proc_dointvec}, + {VM_VFS_SCAN_INTERVAL, "vm_vfs_scan_interval", + &vm_vfs_scan_interval, sizeof(int), 0644, NULL, &proc_dointvec}, {VM_CACHE_SCAN_RATIO, "vm_cache_scan_ratio", &vm_cache_scan_ratio, sizeof(int), 0644, NULL, &proc_dointvec}, {VM_MAPPED_RATIO, "vm_mapped_ratio", --- ./mm/vmscan.c.~1~ 2003-09-16 20:44:14.000000000 -0400 +++ ./mm/vmscan.c 2003-09-21 11:24:49.000000000 -0400 @@ -65,6 +65,12 @@ int vm_vfs_scan_ratio = 6; /* + * "vm_vfs_scan_interval" is how often (in seconds) + * memory gets reclaimed from inode/dentry cache. + */ +int vm_vfs_scan_interval = MAX_SCHEDULE_TIMEOUT / HZ; + +/* * The swap-out function returns 1 if it successfully * scanned all the pages it was asked to (`count'). * It returns zero if it couldn't do anything, @@ -364,6 +370,23 @@ return 0; } +#define shrink_vfs_caches(gfp_mask) __shrink_vfs_caches(0, gfp_mask) +#define shrink_vfs_caches_force(gfp_mask) __shrink_vfs_caches(1, gfp_mask) + +static void __shrink_vfs_caches(int force, unsigned int gfp_mask) +{ + static unsigned long last_scan = 0; + + if (force || time_after(jiffies, last_scan + vm_vfs_scan_interval * HZ)) { + shrink_dcache_memory(vm_vfs_scan_ratio, gfp_mask); + shrink_icache_memory(vm_vfs_scan_ratio, gfp_mask); +#ifdef CONFIG_QUOTA + shrink_dqcache_memory(vm_vfs_scan_ratio, gfp_mask); +#endif + last_scan = jiffies; + } +} + static void FASTCALL(refill_inactive(int nr_pages, zone_t * classzone)); static int FASTCALL(shrink_cache(int nr_pages, zone_t * classzone, unsigned int gfp_mask, int * failed_swapout)); static int shrink_cache(int nr_pages, zone_t * classzone, unsigned int gfp_mask, int * failed_swapout) @@ -401,6 +424,8 @@ if (!memclass(page_zone(page), classzone)) continue; + max_scan--; + /* Racy check to avoid trylocking when not worthwhile */ if (!page->buffers && (page_count(page) != 1 || !page->mapping)) goto page_mapped; @@ -516,11 +541,7 @@ if (nr_pages <= 0) goto out; - shrink_dcache_memory(vm_vfs_scan_ratio, gfp_mask); - shrink_icache_memory(vm_vfs_scan_ratio, gfp_mask); -#ifdef CONFIG_QUOTA - shrink_dqcache_memory(vm_vfs_scan_ratio, gfp_mask); -#endif + shrink_vfs_caches_force(gfp_mask); if (!*failed_swapout) *failed_swapout = !swap_out(classzone); @@ -614,6 +635,8 @@ if (nr_pages <= 0) goto out; + shrink_vfs_caches(gfp_mask); + spin_lock(&pagemap_lru_lock); refill_inactive(nr_pages, classzone); @@ -638,11 +661,9 @@ nr_pages = shrink_caches(classzone, gfp_mask, nr_pages, &failed_swapout); if (nr_pages <= 0) return 1; - shrink_dcache_memory(vm_vfs_scan_ratio, gfp_mask); - shrink_icache_memory(vm_vfs_scan_ratio, gfp_mask); -#ifdef CONFIG_QUOTA - shrink_dqcache_memory(vm_vfs_scan_ratio, gfp_mask); -#endif + + shrink_vfs_caches_force(gfp_mask); + if (!failed_swapout) failed_swapout = !swap_out(classzone); } while (--tries); --- ./include/linux/swap.h.~1~ 2003-09-16 20:46:35.000000000 -0400 +++ ./include/linux/swap.h 2003-09-21 00:56:23.000000000 -0400 @@ -116,6 +116,7 @@ extern int FASTCALL(try_to_free_pages_zone(zone_t *, unsigned int)); extern int FASTCALL(try_to_free_pages(unsigned int)); extern int vm_vfs_scan_ratio, vm_cache_scan_ratio, vm_lru_balance_ratio, vm_passes, vm_gfp_debug, vm_mapped_ratio; +extern int vm_vfs_scan_interval; /* linux/mm/page_io.c */ extern void rw_swap_page(int, struct page *); --- ./include/linux/sysctl.h.~1~ 2003-09-16 20:46:35.000000000 -0400 +++ ./include/linux/sysctl.h 2003-09-21 00:59:37.000000000 -0400 @@ -154,6 +154,7 @@ VM_GFP_DEBUG=18, /* debug GFP failures */ VM_CACHE_SCAN_RATIO=19, /* part of the inactive cache list to scan */ VM_MAPPED_RATIO=20, /* amount of unfreeable pages that triggers swapout */ + VM_VFS_SCAN_INTERVAL=21,/* interval (in secs) between reclaiming memory from inode/dentry cache */ };