Index: linux-2.6.20/mm/page_alloc.c =================================================================== --- linux-2.6.20.orig/mm/page_alloc.c 2007-02-15 20:11:20.000000000 -0800 +++ linux-2.6.20/mm/page_alloc.c 2007-02-15 20:19:41.000000000 -0800 @@ -203,6 +203,7 @@ 1 << PG_slab | 1 << PG_swapcache | 1 << PG_writeback | + 1 << PG_mlocked | 1 << PG_buddy ); set_page_count(page, 0); reset_page_mapcount(page); @@ -438,6 +439,7 @@ 1 << PG_swapcache | 1 << PG_writeback | 1 << PG_reserved | + 1 << PG_mlocked | 1 << PG_buddy )))) bad_page(page); if (PageDirty(page)) @@ -588,6 +590,7 @@ 1 << PG_swapcache | 1 << PG_writeback | 1 << PG_reserved | + 1 << PG_mlocked | 1 << PG_buddy )))) bad_page(page); Index: linux-2.6.20/mm/memory.c =================================================================== --- linux-2.6.20.orig/mm/memory.c 2007-02-15 20:11:36.000000000 -0800 +++ linux-2.6.20/mm/memory.c 2007-02-15 20:11:37.000000000 -0800 @@ -906,6 +906,8 @@ static void add_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long address) { + BUG_ON(PageLRU(page)); + BUG_ON(PageMlocked(page)); inc_mm_counter(vma->vm_mm, anon_rss); if (vma->vm_flags & VM_LOCKED) { /* Index: linux-2.6.20/include/linux/page-flags.h =================================================================== --- linux-2.6.20.orig/include/linux/page-flags.h 2007-02-15 20:24:57.000000000 -0800 +++ linux-2.6.20/include/linux/page-flags.h 2007-02-15 20:25:39.000000000 -0800 @@ -261,6 +261,7 @@ #define PageMlocked(page) test_bit(PG_mlocked, &(page)->flags) #define SetPageMlocked(page) set_bit(PG_mlocked, &(page)->flags) #define ClearPageMlocked(page) clear_bit(PG_mlocked, &(page)->flags) +#define __ClearPageMlocked(page) __clear_bit(PG_mlocked, &(page)->flags) struct page; /* forward declaration */ Index: linux-2.6.20/mm/swap.c =================================================================== --- linux-2.6.20.orig/mm/swap.c 2007-02-15 20:19:52.000000000 -0800 +++ linux-2.6.20/mm/swap.c 2007-02-15 20:27:10.000000000 -0800 @@ -40,14 +40,19 @@ */ static void fastcall __page_cache_release(struct page *page) { - if (PageLRU(page)) { + if (PageLRU(page) || PageMlocked(page)) { unsigned long flags; struct zone *zone = page_zone(page); spin_lock_irqsave(&zone->lru_lock, flags); - VM_BUG_ON(!PageLRU(page)); + if (PageLRU(page)) + del_page_from_lru(zone, page); + else { + VM_BUG_ON(!PageMlocked(page)); + __dec_zone_state(zone, NR_MLOCK); + } __ClearPageLRU(page); - del_page_from_lru(zone, page); + __ClearPageMlocked(page); spin_unlock_irqrestore(&zone->lru_lock, flags); } free_hot_page(page); @@ -291,7 +296,7 @@ if (!put_page_testzero(page)) continue; - if (PageLRU(page)) { + if (PageLRU(page) || PageMlocked(page)) { struct zone *pagezone = page_zone(page); if (pagezone != zone) { if (zone) @@ -299,9 +304,14 @@ zone = pagezone; spin_lock_irq(&zone->lru_lock); } - VM_BUG_ON(!PageLRU(page)); - __ClearPageLRU(page); - del_page_from_lru(zone, page); + if (PageLRU(page)) { + __ClearPageLRU(page); + del_page_from_lru(zone, page); + } else { + VM_BUG_ON(!PageMlocked(page)); + __ClearPageMlocked(page); + __dec_zone_state(zone, NR_MLOCK); + } } if (!pagevec_add(&pages_to_free, page)) {