Index: linux-2.6.8.1-ck8/include/linux/swap.h
===================================================================
--- linux-2.6.8.1-ck8.orig/include/linux/swap.h	2004-09-21 08:54:36.781815504 +1000
+++ linux-2.6.8.1-ck8/include/linux/swap.h	2004-09-21 08:55:54.198046448 +1000
@@ -175,6 +175,7 @@ extern void swap_setup(void);
 extern int try_to_free_pages(struct zone **, unsigned int, unsigned int);
 extern int shrink_all_memory(int);
 extern int vm_mapped;
+extern int vm_hardmaplimit;
 
 #ifdef CONFIG_MMU
 /* linux/mm/shmem.c */
Index: linux-2.6.8.1-ck8/include/linux/sysctl.h
===================================================================
--- linux-2.6.8.1-ck8.orig/include/linux/sysctl.h	2004-09-21 08:54:36.781815504 +1000
+++ linux-2.6.8.1-ck8/include/linux/sysctl.h	2004-09-21 08:55:54.198046448 +1000
@@ -167,6 +167,7 @@ enum
 	VM_BLOCK_DUMP=24,	/* block dump mode */
 	VM_HUGETLB_GROUP=25,	/* permitted hugetlb group */
 	VM_VFS_CACHE_PRESSURE=26, /* dcache/icache reclaim pressure */
+	VM_HARDMAPLIMIT=27,	/* Make mapped a hard limit */
 };
 
 
Index: linux-2.6.8.1-ck8/kernel/sysctl.c
===================================================================
--- linux-2.6.8.1-ck8.orig/kernel/sysctl.c	2004-09-21 08:54:36.782815352 +1000
+++ linux-2.6.8.1-ck8/kernel/sysctl.c	2004-09-21 08:55:54.199046296 +1000
@@ -727,6 +727,14 @@ static ctl_table vm_table[] = {
 		.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,
Index: linux-2.6.8.1-ck8/mm/vmscan.c
===================================================================
--- linux-2.6.8.1-ck8.orig/mm/vmscan.c	2004-09-21 08:55:40.038199072 +1000
+++ linux-2.6.8.1-ck8/mm/vmscan.c	2004-09-21 08:58:19.505956288 +1000
@@ -116,6 +116,7 @@ struct shrinker {
 #endif
 
 int vm_mapped = 66;
+int vm_hardmaplimit = 1;
 static long total_memory;
 
 static LIST_HEAD(shrinker_list);
@@ -645,6 +646,7 @@ refill_inactive_zone(struct zone *zone, 
 	int pgdeactivate = 0;
 	int pgscanned = 0;
 	int nr_pages = sc->nr_to_scan;
+	unsigned int mapped_ratio;
 	LIST_HEAD(l_hold);	/* The pages which were snipped off */
 	LIST_HEAD(l_inactive);	/* Pages to go onto the inactive_list */
 	LIST_HEAD(l_active);	/* Pages to go onto the active_list */
@@ -679,13 +681,16 @@ refill_inactive_zone(struct zone *zone, 
 	zone->nr_active -= pgmoved;
 	spin_unlock_irq(&zone->lru_lock);
 
+	mapped_ratio = (sc->nr_mapped * 100) / total_memory;
+
 	while (!list_empty(&l_hold)) {
 		page = lru_to_page(&l_hold);
 		list_del(&page->lru);
 		if (page_mapped(page)) {
-			if (zone->zone_pgdat->mapped_nrpages) {
-				list_add(&page->lru, &l_active);
-				continue;
+			if (zone->zone_pgdat->mapped_nrpages ||
+				vm_hardmaplimit && mapped_ratio < vm_mapped) {
+					list_add(&page->lru, &l_active);
+					continue;
 			}
 			page_map_lock(page);
 			if (page_referenced(page)) {

