Index: current/include/linux/page-flags.h =================================================================== --- current.orig/include/linux/page-flags.h 2007-02-03 10:16:48.000000000 -0800 +++ current/include/linux/page-flags.h 2007-02-03 14:06:54.000000000 -0800 @@ -93,6 +93,7 @@ #define PG_readahead 20 /* Reminder to do read-ahead */ +#define PG_mlocked 21 /* Page is mlocked */ #if (BITS_PER_LONG > 32) /* @@ -235,6 +236,10 @@ static inline void SetPageUptodate(struc #define SetPageReadahead(page) set_bit(PG_readahead, &(page)->flags) #define ClearPageReadahead(page) clear_bit(PG_readahead, &(page)->flags) +#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) + struct page; /* forward declaration */ extern void cancel_dirty_page(struct page *page, unsigned int account_size); Index: current/mm/memory.c =================================================================== --- current.orig/mm/memory.c 2007-02-03 13:08:06.000000000 -0800 +++ current/mm/memory.c 2007-02-03 14:06:54.000000000 -0800 @@ -682,9 +682,16 @@ static unsigned long zap_pte_range(struc file_rss--; } page_remove_rmap(page, vma); - if (vma->vm_flags & VM_LOCKED) { - __dec_zone_page_state(page, NR_MLOCK); - lru_cache_add_active(page); + if (vma->vm_flags & VM_LOCKED && PageMlocked(page)) { + struct zone *zone = page_zone(page); + + spin_lock_irq(&zone->lru_lock); + if (PageMlocked(page)) { + ClearPageMlocked(page); + lru_cache_add_active(page); + __dec_zone_state(zone, NR_MLOCK); + } + spin_unlock_irq(&zone->lru_lock); } tlb_remove_page(tlb, page); continue; Index: current/mm/vmscan.c =================================================================== --- current.orig/mm/vmscan.c 2007-02-03 13:11:35.000000000 -0800 +++ current/mm/vmscan.c 2007-02-03 14:06:54.000000000 -0800 @@ -596,6 +596,8 @@ free_it: continue; mlocked: + ClearPageActive(page); + SetPageMlocked(page); unlock_page(page); __inc_zone_page_state(page, NR_MLOCK); continue;