diff -urN oldtree/Documentation/sysctl/vm.txt newtree/Documentation/sysctl/vm.txt --- oldtree/Documentation/sysctl/vm.txt 2006-06-21 12:00:37.642299250 +0000 +++ newtree/Documentation/sysctl/vm.txt 2006-06-21 12:36:52.058191750 +0000 @@ -22,6 +22,8 @@ - dirty_background_ratio - dirty_expire_centisecs - dirty_writeback_centisecs +- hardmaplimit +- mapped - max_map_count - min_free_kbytes - laptop_mode @@ -88,6 +90,27 @@ ============================================================== +hardmaplimit: + +This flag makes the vm adhere to the mapped value as closely as possible +except in the most extreme vm stress where doing so would provoke an out +of memory condition (see mapped below). + +Enabled by default. + +============================================================== + +mapped: + +This is the percentage ram that is filled with mapped pages (applications) +before the vm will start reclaiming mapped pages by moving them to swap. +It is altered by the relative stress of the vm at the time so is not +strictly adhered to to prevent provoking out of memory kills. + +Set to 66 by default. + +============================================================== + max_map_count: This file contains the maximum number of memory map areas a process diff -urN oldtree/include/linux/swap.h newtree/include/linux/swap.h --- oldtree/include/linux/swap.h 2006-06-21 12:00:43.866688250 +0000 +++ newtree/include/linux/swap.h 2006-06-21 12:36:51.930183750 +0000 @@ -184,7 +184,8 @@ /* linux/mm/vmscan.c */ extern unsigned long try_to_free_pages(struct zone **, gfp_t); extern unsigned long shrink_all_memory(unsigned long nr_pages); -extern int vm_swappiness; +extern int vm_mapped; +extern int vm_hardmaplimit; extern int remove_mapping(struct address_space *mapping, struct page *page); extern long vm_total_pages; diff -urN oldtree/include/linux/sysctl.h newtree/include/linux/sysctl.h --- oldtree/include/linux/sysctl.h 2006-06-21 12:00:43.870688500 +0000 +++ newtree/include/linux/sysctl.h 2006-06-21 12:37:15.915682750 +0000 @@ -179,7 +179,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 */ @@ -198,6 +198,7 @@ VM_SWAP_PREFETCH=35, /* swap prefetch */ VM_READAHEAD_RATIO=36, /* percent of read-ahead size to thrashing-threshold */ VM_READAHEAD_HIT_RATE=37, /* one accessed page legitimizes so many read-ahead pages */ + VM_HARDMAPLIMIT=38, /* Make mapped a hard limit */ }; /* CTL_NET names: */ diff -urN oldtree/kernel/sysctl.c newtree/kernel/sysctl.c --- oldtree/kernel/sysctl.c 2006-06-21 12:00:44.014697500 +0000 +++ newtree/kernel/sysctl.c 2006-06-21 12:36:51.978186750 +0000 @@ -888,16 +888,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 -urN oldtree/mm/vmscan.c newtree/mm/vmscan.c --- oldtree/mm/vmscan.c 2006-06-21 12:00:44.086702000 +0000 +++ newtree/mm/vmscan.c 2006-06-21 12:38:37.884805500 +0000 @@ -64,7 +64,7 @@ * whole list at once. */ int swap_cluster_max; - int swappiness; + int mapped; }; #define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru)) @@ -98,10 +98,11 @@ #endif /* - * From 0 .. 100. Higher means more swappy. + * From 0 .. 100. Lower means more swappy. */ -int vm_swappiness = 60; -long vm_total_pages; /* The total number of pages which the VM controls */ +int vm_mapped __read_mostly = 66; +int vm_hardmaplimit __read_mostly = 1; +static long total_memory __read_mostly; static LIST_HEAD(shrinker_list); static DECLARE_RWSEM(shrinker_rwsem); @@ -760,10 +761,14 @@ * The distress ratio is important - we don't want to start * going oom. * - * A 100% value of vm_swappiness overrides this algorithm - * altogether. + * This distress value is ignored if we apply a hardmaplimit except + * in extreme distress. + * + * A 0% value of vm_mapped overrides this algorithm altogether. */ - swap_tendency = mapped_ratio / 2 + distress + sc->swappiness; + swap_tendency = mapped_ratio * 100 / (sc->mapped + 1); + if (!vm_hardmaplimit || distress == 100) + swap_tendency += distress; /* * Now use this metric to decide whether to start moving mapped @@ -979,7 +984,7 @@ .may_writepage = !laptop_mode, .swap_cluster_max = SWAP_CLUSTER_MAX, .may_swap = 1, - .swappiness = vm_swappiness, + .mapped = vm_mapped, }; delay_swap_prefetch(); @@ -1074,7 +1079,7 @@ .gfp_mask = GFP_KERNEL, .may_swap = 1, .swap_cluster_max = SWAP_CLUSTER_MAX, - .swappiness = vm_swappiness, + .mapped = vm_mapped, }; loop_again: @@ -1362,7 +1367,7 @@ .may_swap = 0, .swap_cluster_max = nr_pages, .may_writepage = 1, - .swappiness = vm_swappiness, + .mapped = vm_mapped, }; delay_swap_prefetch(); @@ -1409,7 +1414,7 @@ /* Force reclaiming mapped pages in the passes #3 and #4 */ if (pass > 2) { sc.may_swap = 1; - sc.swappiness = 100; + sc.mapped = 0; } for (prio = DEF_PRIORITY; prio >= 0; prio--) { @@ -1561,7 +1566,7 @@ .swap_cluster_max = max_t(unsigned long, nr_pages, SWAP_CLUSTER_MAX), .gfp_mask = gfp_mask, - .swappiness = vm_swappiness, + .mapped = vm_mapped, }; disable_swap_token();