diff -Naur linux-2.6.10/include/linux/mmzone.h linux-2.6.11-rc2-no1-broken-out/include/linux/mmzone.h --- linux-2.6.10/include/linux/mmzone.h 2005-01-28 14:48:45.412035904 -0800 +++ linux-2.6.11-rc2-no1-broken-out/include/linux/mmzone.h 2005-01-28 15:20:53.155974280 -0800 @@ -110,7 +110,7 @@ struct zone { /* Fields commonly accessed by the page allocator */ unsigned long free_pages; - unsigned long pages_min, pages_low, pages_high; + unsigned long pages_min, pages_low, pages_high, pages_lots; /* * We don't know if the memory that we're going to allocate will be freeable * or/and it will be released eventually, so to avoid totally wasting several diff -Naur linux-2.6.10/include/linux/swap.h linux-2.6.11-rc2-no1-broken-out/include/linux/swap.h --- linux-2.6.10/include/linux/swap.h 2005-01-28 14:48:46.191917344 -0800 +++ linux-2.6.11-rc2-no1-broken-out/include/linux/swap.h 2005-01-28 15:20:53.204966832 -0800 @@ -174,7 +174,8 @@ /* linux/mm/vmscan.c */ extern int try_to_free_pages(struct zone **, unsigned int, unsigned int); extern int shrink_all_memory(int); -extern int vm_swappiness; +extern int vm_mapped; +extern int vm_hardmaplimit; #ifdef CONFIG_MMU /* linux/mm/shmem.c */ diff -Naur linux-2.6.10/include/linux/sysctl.h linux-2.6.11-rc2-no1-broken-out/include/linux/sysctl.h --- linux-2.6.10/include/linux/sysctl.h 2005-01-28 14:48:46.231911264 -0800 +++ linux-2.6.11-rc2-no1-broken-out/include/linux/sysctl.h 2005-01-28 15:21:27.709721312 -0800 @@ -161,7 +161,7 @@ VM_OVERCOMMIT_RATIO=16, /* percent of RAM to allow overcommit in */ VM_PAGEBUF=17, /* struct: Control pagebuf parameters */ VM_HUGETLB_PAGES=18, /* int: Number of available Huge Pages */ - VM_SWAPPINESS=19, /* Tendency to steal mapped memory */ + VM_MAPPED=19, /* percent mapped min while evicting cache */ VM_LOWMEM_RESERVE_RATIO=20,/* reservation ratio for lower memory zones */ VM_MIN_FREE_KBYTES=21, /* Minimum free kilobytes to maintain */ VM_MAX_MAP_COUNT=22, /* int: Maximum number of mmaps/address-space */ @@ -171,7 +171,8 @@ VM_VFS_CACHE_PRESSURE=26, /* dcache/icache reclaim pressure */ VM_LEGACY_VA_LAYOUT=27, /* legacy/compatibility virtual address space layout */ VM_SWAP_TOKEN_TIMEOUT=28, /* default time for token time out */ -}; + VM_HARDMAPLIMIT=29, /* Make mapped a hard limit */ + }; /* CTL_NET names: */ diff -Naur linux-2.6.10/kernel/sysctl.c linux-2.6.11-rc2-no1-broken-out/kernel/sysctl.c --- linux-2.6.10/kernel/sysctl.c 2005-01-28 14:48:47.340742696 -0800 +++ linux-2.6.11-rc2-no1-broken-out/kernel/sysctl.c 2005-01-28 15:20:53.270956800 -0800 @@ -731,16 +731,24 @@ .proc_handler = &proc_dointvec, }, { - .ctl_name = VM_SWAPPINESS, - .procname = "swappiness", - .data = &vm_swappiness, - .maxlen = sizeof(vm_swappiness), + .ctl_name = VM_MAPPED, + .procname = "mapped", + .data = &vm_mapped, + .maxlen = sizeof(vm_mapped), .mode = 0644, .proc_handler = &proc_dointvec_minmax, .strategy = &sysctl_intvec, .extra1 = &zero, .extra2 = &one_hundred, }, + { + .ctl_name = VM_HARDMAPLIMIT, + .procname = "hardmaplimit", + .data = &vm_hardmaplimit, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, #ifdef CONFIG_HUGETLB_PAGE { .ctl_name = VM_HUGETLB_PAGES, diff -Naur linux-2.6.10/mm/page_alloc.c linux-2.6.11-rc2-no1-broken-out/mm/page_alloc.c --- linux-2.6.10/mm/page_alloc.c 2005-01-28 14:48:51.771069184 -0800 +++ linux-2.6.11-rc2-no1-broken-out/mm/page_alloc.c 2005-01-28 15:20:53.314950112 -0800 @@ -2107,6 +2107,7 @@ */ zone->pages_low = (zone->pages_min * 5) / 4; zone->pages_high = (zone->pages_min * 6) / 4; + zone->pages_lots = (zone->pages_min * 12) / 4; spin_unlock_irqrestore(&zone->lru_lock, flags); } } diff -Naur linux-2.6.10/mm/vmscan.c linux-2.6.11-rc2-no1-broken-out/mm/vmscan.c --- linux-2.6.10/mm/vmscan.c 2005-01-28 14:48:51.928045320 -0800 +++ linux-2.6.11-rc2-no1-broken-out/mm/vmscan.c 2005-01-28 15:20:53.337946616 -0800 @@ -116,10 +116,8 @@ #define prefetchw_prev_lru_page(_page, _base, _field) do { } while (0) #endif -/* - * From 0 .. 100. Higher means more swappy. - */ -int vm_swappiness = 60; +int vm_mapped = 66; +int vm_hardmaplimit = 0; static long total_memory; static LIST_HEAD(shrinker_list); @@ -715,10 +713,13 @@ * doesn't necessarily mean that page reclaim isn't succeeding. * * The distress ratio is important - we don't want to start going oom. + * This distress value is ignored if we apply a hardmaplimit. * - * A 100% value of vm_swappiness overrides this algorithm altogether. + * A 0% value of vm_mapped overrides this algorithm altogether. */ - swap_tendency = mapped_ratio / 2 + distress + vm_swappiness; + swap_tendency = mapped_ratio * 100 / (vm_mapped + 1); + if (!vm_hardmaplimit) + swap_tendency += distress; /* * Now use this metric to decide whether to start moving mapped memory @@ -1045,8 +1046,23 @@ priority != DEF_PRIORITY) continue; + /* + * The pages_lots watermark is relaxed + * till it drops to pages_high under anything + * but very light stress (DEF_PRIORITY) + */ + if (priority != DEF_PRIORITY && + zone->free_pages <= zone->pages_lots && + zone->pages_lots > zone->pages_high) { + spin_lock(&zone->lru_lock); + zone->pages_lots = + zone->free_pages - 1; + spin_unlock(&zone->lru_lock); + } + + if (!zone_watermark_ok(zone, order, - zone->pages_high, 0, 0, 0)) { + zone->pages_lots, 0, 0, 0)) { end_zone = i; goto scan; }