__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 --- memhotplug-dave/include/linux/swap.h | 13 +++++++++++-- memhotplug-dave/mm/swapfile.c | 8 +++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff -puN include/linux/swap.h~AA-PM-16-remove_exclusive_swap_page include/linux/swap.h --- memhotplug/include/linux/swap.h~AA-PM-16-remove_exclusive_swap_page 2005-03-11 10:51:57.000000000 -0800 +++ memhotplug-dave/include/linux/swap.h 2005-03-11 10:51:57.000000000 -0800 @@ -228,7 +228,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; @@ -282,11 +286,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; diff -puN mm/swapfile.c~AA-PM-16-remove_exclusive_swap_page mm/swapfile.c --- memhotplug/mm/swapfile.c~AA-PM-16-remove_exclusive_swap_page 2005-03-11 10:51:57.000000000 -0800 +++ memhotplug-dave/mm/swapfile.c 2005-03-11 10:51:57.000000000 -0800 @@ -337,11 +337,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)); @@ -350,7 +351,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; @@ -363,7 +364,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; _