__remove_exlusive_swap_page() can detach a page from the swap-cache when page_count(page) - page_mapcount(page) == 2 while the original remove_exlusive_swap_page() can do this only when a target page isn't mapped to any spaces and isn't shared. __remove_exlusive_swap_page() is called not to waste swap space right after memory migration is done. Signed-off-by: Hirokazu Takahashi Signed-off-by: Dave Hansen Index: linux-2.6.13/include/linux/swap.h =================================================================== --- linux-2.6.13.orig/include/linux/swap.h 2005-08-30 12:16:29.000000000 -0700 +++ linux-2.6.13/include/linux/swap.h 2005-08-30 12:16:50.000000000 -0700 @@ -230,7 +230,11 @@ extern void free_swap_and_cache(swp_entr extern sector_t map_swap_page(struct swap_info_struct *, pgoff_t); extern struct swap_info_struct *get_swap_info_struct(unsigned); extern int can_share_swap_page(struct page *); -extern int remove_exclusive_swap_page(struct page *); +extern int __remove_exclusive_swap_page(struct page *, int); +static inline int remove_exclusive_swap_page(struct page *p) +{ + return __remove_exclusive_swap_page(p, 0); +} struct backing_dev_info; extern struct swap_list_t swap_list; @@ -286,11 +290,16 @@ static inline void put_swap_token(struct #define delete_from_swap_cache(p) /*NOTHING*/ #define swap_token_default_timeout 0 -static inline int remove_exclusive_swap_page(struct page *p) +static inline int __remove_exclusive_swap_page(struct page *p, int force) { return 0; } +static inline int remove_exclusive_swap_page(struct page *p) +{ + return __remove_exclusive_swap_page(p, 0); +} + static inline swp_entry_t get_swap_page(void) { swp_entry_t entry; Index: linux-2.6.13/mm/swapfile.c =================================================================== --- linux-2.6.13.orig/mm/swapfile.c 2005-08-30 12:16:36.000000000 -0700 +++ linux-2.6.13/mm/swapfile.c 2005-08-30 12:16:50.000000000 -0700 @@ -313,11 +313,12 @@ int can_share_swap_page(struct page *pag * Work out if there are any other processes sharing this * swap cache page. Free it if you can. Return success. */ -int remove_exclusive_swap_page(struct page *page) +int __remove_exclusive_swap_page(struct page *page, int force) { int retval; struct swap_info_struct * p; swp_entry_t entry; + int mapcount = force ? page_mapcount(page) : 0; BUG_ON(PagePrivate(page)); BUG_ON(!PageLocked(page)); @@ -326,7 +327,7 @@ int remove_exclusive_swap_page(struct pa return 0; if (PageWriteback(page)) return 0; - if (page_count(page) != 2) /* 2: us + cache */ + if (page_count(page) - mapcount != 2) /* 2: us + cache */ return 0; entry.val = page->private; @@ -339,7 +340,8 @@ int remove_exclusive_swap_page(struct pa if (p->swap_map[swp_offset(entry)] == 1) { /* Recheck the page count with the swapcache lock held.. */ write_lock_irq(&swapper_space.tree_lock); - if ((page_count(page) == 2) && !PageWriteback(page)) { + mapcount = force ? page_mapcount(page) : 0; + if ((page_count(page) - mapcount == 2) && !PageWriteback(page)) { __delete_from_swap_cache(page); SetPageDirty(page); retval = 1;