| /* |
| * Memory Migration functionality - linux/mm/migration.c |
| * |
| * Copyright (C) 2006 Silicon Graphics, Inc., Christoph Lameter |
| * |
| * Page migration was first developed in the context of the memory hotplug |
| * project. The main authors of the migration code are: |
| * |
| * IWAMOTO Toshihiro <iwamoto@valinux.co.jp> |
| * Hirokazu Takahashi <taka@valinux.co.jp> |
| * Dave Hansen <haveblue@us.ibm.com> |
| * Christoph Lameter <clameter@sgi.com> |
| */ |
| |
| #include <linux/migrate.h> |
| #include <linux/module.h> |
| #include <linux/swap.h> |
| #include <linux/pagemap.h> |
| #include <linux/buffer_head.h> |
| #include <linux/mm_inline.h> |
| #include <linux/pagevec.h> |
| #include <linux/rmap.h> |
| #include <linux/topology.h> |
| #include <linux/cpu.h> |
| #include <linux/cpuset.h> |
| #include <linux/swapops.h> |
| |
| #include "internal.h" |
| |
| /* The maximum number of pages to take off the LRU for migration */ |
| #define MIGRATE_CHUNK_SIZE 256 |
| |
| #define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru)) |
| |
| /* |
| * Isolate one page from the LRU lists. If successful put it onto |
| * the indicated list with elevated page count. |
| * |
| * Result: |
| * -EBUSY: page not on LRU list |
| * 0: page removed from LRU list and added to the specified list. |
| */ |
| int isolate_lru_page(struct page *page, struct list_head *pagelist) |
| { |
| int ret = -EBUSY; |
| |
| if (PageLRU(page)) { |
| struct zone *zone = page_zone(page); |
| |
| spin_lock_irq(&zone->lru_lock); |
| if (PageLRU(page)) { |
| ret = 0; |
| get_page(page); |
| ClearPageLRU(page); |
| if (PageActive(page)) |
| del_page_from_active_list(zone, page); |
| else |
| del_page_from_inactive_list(zone, page); |
| list_add_tail(&page->lru, pagelist); |
| } |
| spin_unlock_irq(&zone->lru_lock); |
| } |
| return ret; |
| } |
| |
| /* |
| * migrate_prep() needs to be called after we have compiled the list of pages |
| * to be migrated using isolate_lru_page() but before we begin a series of calls |
| * to migrate_pages(). |
| */ |
| int migrate_prep(void) |
| { |
| /* Must have swap device for migration */ |
| if (nr_swap_pages <= 0) |
| return -ENODEV; |
| |
| /* |
| * Clear the LRU lists so pages can be isolated. |
| * Note that pages may be moved off the LRU after we have |
| * drained them. Those pages will fail to migrate like other |
| * pages that may be busy. |
| */ |
| lru_add_drain_all(); |
| |
| return 0; |
| } |
| |
| static inline void move_to_lru(struct page *page) |
| { |
| list_del(&page->lru); |
| if (PageActive(page)) { |
| /* |
| * lru_cache_add_active checks that |
| * the PG_active bit is off. |
| */ |
| ClearPageActive(page); |
| lru_cache_add_active(page); |
| } else { |
| lru_cache_add(page); |
| } |
| put_page(page); |
| } |
| |
| /* |
| * Add isolated pages on the list back to the LRU. |
| * |
| * returns the number of pages put back. |
| */ |
| int putback_lru_pages(struct list_head *l) |
| { |
| struct page *page; |
| struct page *page2; |
| int count = 0; |
| |
| list_for_each_entry_safe(page, page2, l, lru) { |
| move_to_lru(page); |
| count++; |
| } |
| return count; |
| } |
| |
| /* |
| * swapout a single page |
| * page is locked upon entry, unlocked on exit |
| */ |
| static int swap_page(struct page *page) |
| { |
| struct address_space *mapping = page_mapping(page); |
| |
| if (page_mapped(page) && mapping) |
| if (try_to_unmap(page, 1) != SWAP_SUCCESS) |
| goto unlock_retry; |
| |
| if (PageDirty(page)) { |
| /* Page is dirty, try to write it out here */ |
| switch(pageout(page, mapping)) { |
| case PAGE_KEEP: |
| case PAGE_ACTIVATE: |
| goto unlock_retry; |
| |
| case PAGE_SUCCESS: |
| goto retry; |
| |
| case PAGE_CLEAN: |
| ; /* try to free the page below */ |
| } |
| } |
| |
| if (PagePrivate(page)) { |
| if (!try_to_release_page(page, GFP_KERNEL) || |
| (!mapping && page_count(page) == 1)) |
| goto unlock_retry; |
| } |
| |
| if (remove_mapping(mapping, page)) { |
| /* Success */ |
| unlock_page(page); |
| return 0; |
| } |
| |
| unlock_retry: |
| unlock_page(page); |
| |
| retry: |
| return -EAGAIN; |
| } |
| |
| /* |
| * Replace the page in the mapping. |
| * |
| * The number of remaining references must be: |
| * 1 for anonymous pages without a mapping |
| * 2 for pages with a mapping |
| * 3 for pages with a mapping and PagePrivate set. |
| */ |
| static int migrate_page_move_mapping(struct address_space *mapping, |
| struct page *newpage, struct page *page) |
| { |
| struct page **radix_pointer; |
| |
| write_lock_irq(&mapping->tree_lock); |
| |
| radix_pointer = (struct page **)radix_tree_lookup_slot( |
| &mapping->page_tree, |
| page_index(page)); |
| |
| if (!page_mapping(page) || |
| page_count(page) != 2 + !!PagePrivate(page) || |
| *radix_pointer != page) { |
| write_unlock_irq(&mapping->tree_lock); |
| return -EAGAIN; |
| } |
| |
| /* |
| * Now we know that no one else is looking at the page. |
| */ |
| get_page(newpage); |
| if (PageSwapCache(page)) { |
| SetPageSwapCache(newpage); |
| set_page_private(newpage, page_private(page)); |
| } |
| |
| *radix_pointer = newpage; |
| __put_page(page); |
| write_unlock_irq(&mapping->tree_lock); |
| |
| return 0; |
| } |
| |
| /* |
| * Copy the page to its new location |
| */ |
| static void migrate_page_copy(struct page *newpage, struct page *page) |
| { |
| copy_highpage(newpage, page); |
| |
| if (PageError(page)) |
| SetPageError(newpage); |
| if (PageReferenced(page)) |
| SetPageReferenced(newpage); |
| if (PageUptodate(page)) |
| SetPageUptodate(newpage); |
| if (PageActive(page)) |
| SetPageActive(newpage); |
| if (PageChecked(page)) |
| SetPageChecked(newpage); |
| if (PageMappedToDisk(page)) |
| SetPageMappedToDisk(newpage); |
| |
| if (PageDirty(page)) { |
| clear_page_dirty_for_io(page); |
| set_page_dirty(newpage); |
| } |
| |
| ClearPageSwapCache(page); |
| ClearPageActive(page); |
| ClearPagePrivate(page); |
| set_page_private(page, 0); |
| page->mapping = NULL; |
| |
| /* |
| * If any waiters have accumulated on the new page then |
| * wake them up. |
| */ |
| if (PageWriteback(newpage)) |
| end_page_writeback(newpage); |
| } |
| |
| /************************************************************ |
| * Migration functions |
| ***********************************************************/ |
| |
| /* Always fail migration. Used for mappings that are not movable */ |
| int fail_migrate_page(struct address_space *mapping, |
| struct page *newpage, struct page *page) |
| { |
| return -EIO; |
| } |
| EXPORT_SYMBOL(fail_migrate_page); |
| |
| /* |
| * Common logic to directly migrate a single page suitable for |
| * pages that do not use PagePrivate. |
| * |
| * Pages are locked upon entry and exit. |
| */ |
| int migrate_page(struct address_space *mapping, |
| struct page *newpage, struct page *page) |
| { |
| int rc; |
| |
| BUG_ON(PageWriteback(page)); /* Writeback must be complete */ |
| |
| rc = migrate_page_move_mapping(mapping, newpage, page); |
| |
| if (rc) |
| return rc; |
| |
| migrate_page_copy(newpage, page); |
| |
| /* |
| * Remove auxiliary swap entries and replace |
| * them with real ptes. |
| * |
| * Note that a real pte entry will allow processes that are not |
| * waiting on the page lock to use the new page via the page tables |
| * before the new page is unlocked. |
| */ |
| remove_from_swap(newpage); |
| return 0; |
| } |
| EXPORT_SYMBOL(migrate_page); |
| |
| /* |
| * Migration function for pages with buffers. This function can only be used |
| * if the underlying filesystem guarantees that no other references to "page" |
| * exist. |
| */ |
| int buffer_migrate_page(struct address_space *mapping, |
| struct page *newpage, struct page *page) |
| { |
| struct buffer_head *bh, *head; |
| int rc; |
| |
| if (!page_has_buffers(page)) |
| return migrate_page(mapping, newpage, page); |
| |
| head = page_buffers(page); |
| |
| rc = migrate_page_move_mapping(mapping, newpage, page); |
| |
| if (rc) |
| return rc; |
| |
| bh = head; |
| do { |
| get_bh(bh); |
| lock_buffer(bh); |
| bh = bh->b_this_page; |
| |
| } while (bh != head); |
| |
| ClearPagePrivate(page); |
| set_page_private(newpage, page_private(page)); |
| set_page_private(page, 0); |
| put_page(page); |
| get_page(newpage); |
| |
| bh = head; |
| do { |
| set_bh_page(bh, newpage, bh_offset(bh)); |
| bh = bh->b_this_page; |
| |
| } while (bh != head); |
| |
| SetPagePrivate(newpage); |
| |
| migrate_page_copy(newpage, page); |
| |
| bh = head; |
| do { |
| unlock_buffer(bh); |
| put_bh(bh); |
| bh = bh->b_this_page; |
| |
| } while (bh != head); |
| |
| return 0; |
| } |
| EXPORT_SYMBOL(buffer_migrate_page); |
| |
| /* |
| * migrate_pages |
| * |
| * Two lists are passed to this function. The first list |
| * contains the pages isolated from the LRU to be migrated. |
| * The second list contains new pages that the pages isolated |
| * can be moved to. If the second list is NULL then all |
| * pages are swapped out. |
| * |
| * The function returns after 10 attempts or if no pages |
| * are movable anymore because to has become empty |
| * or no retryable pages exist anymore. |
| * |
| * Return: Number of pages not migrated when "to" ran empty. |
| */ |
| int migrate_pages(struct list_head *from, struct list_head *to, |
| struct list_head *moved, struct list_head *failed) |
| { |
| int retry; |
| int nr_failed = 0; |
| int pass = 0; |
| struct page *page; |
| struct page *page2; |
| int swapwrite = current->flags & PF_SWAPWRITE; |
| int rc; |
| |
| if (!swapwrite) |
| current->flags |= PF_SWAPWRITE; |
| |
| redo: |
| retry = 0; |
| |
| list_for_each_entry_safe(page, page2, from, lru) { |
| struct page *newpage = NULL; |
| struct address_space *mapping; |
| |
| cond_resched(); |
| |
| rc = 0; |
| if (page_count(page) == 1) |
| /* page was freed from under us. So we are done. */ |
| goto next; |
| |
| if (to && list_empty(to)) |
| break; |
| |
| /* |
| * Skip locked pages during the first two passes to give the |
| * functions holding the lock time to release the page. Later we |
| * use lock_page() to have a higher chance of acquiring the |
| * lock. |
| */ |
| rc = -EAGAIN; |
| if (pass > 2) |
| lock_page(page); |
| else |
| if (TestSetPageLocked(page)) |
| goto next; |
| |
| /* |
| * Only wait on writeback if we have already done a pass where |
| * we we may have triggered writeouts for lots of pages. |
| */ |
| if (pass > 0) { |
| wait_on_page_writeback(page); |
| } else { |
| if (PageWriteback(page)) |
| goto unlock_page; |
| } |
| |
| /* |
| * Anonymous pages must have swap cache references otherwise |
| * the information contained in the page maps cannot be |
| * preserved. |
| */ |
| if (PageAnon(page) && !PageSwapCache(page)) { |
| if (!add_to_swap(page, GFP_KERNEL)) { |
| rc = -ENOMEM; |
| goto unlock_page; |
| } |
| } |
| |
| if (!to) { |
| rc = swap_page(page); |
| goto next; |
| } |
| |
| /* |
| * Establish swap ptes for anonymous pages or destroy pte |
| * maps for files. |
| * |
| * In order to reestablish file backed mappings the fault handlers |
| * will take the radix tree_lock which may then be used to stop |
| * processses from accessing this page until the new page is ready. |
| * |
| * A process accessing via a swap pte (an anonymous page) will take a |
| * page_lock on the old page which will block the process until the |
| * migration attempt is complete. At that time the PageSwapCache bit |
| * will be examined. If the page was migrated then the PageSwapCache |
| * bit will be clear and the operation to retrieve the page will be |
| * retried which will find the new page in the radix tree. Then a new |
| * direct mapping may be generated based on the radix tree contents. |
| * |
| * If the page was not migrated then the PageSwapCache bit |
| * is still set and the operation may continue. |
| */ |
| rc = -EPERM; |
| if (try_to_unmap(page, 1) == SWAP_FAIL) |
| /* A vma has VM_LOCKED set -> permanent failure */ |
| goto unlock_page; |
| |
| rc = -EAGAIN; |
| if (page_mapped(page)) |
| goto unlock_page; |
| |
| newpage = lru_to_page(to); |
| lock_page(newpage); |
| /* Prepare mapping for the new page.*/ |
| newpage->index = page->index; |
| newpage->mapping = page->mapping; |
| |
| /* |
| * Pages are properly locked and writeback is complete. |
| * Try to migrate the page. |
| */ |
| mapping = page_mapping(page); |
| if (!mapping) |
| goto unlock_both; |
| |
| if (mapping->a_ops->migratepage) { |
| /* |
| * Most pages have a mapping and most filesystems |
| * should provide a migration function. Anonymous |
| * pages are part of swap space which also has its |
| * own migration function. This is the most common |
| * path for page migration. |
| */ |
| rc = mapping->a_ops->migratepage(mapping, |
| newpage, page); |
| goto unlock_both; |
| } |
| |
| /* |
| * Default handling if a filesystem does not provide |
| * a migration function. We can only migrate clean |
| * pages so try to write out any dirty pages first. |
| */ |
| if (PageDirty(page)) { |
| switch (pageout(page, mapping)) { |
| case PAGE_KEEP: |
| case PAGE_ACTIVATE: |
| goto unlock_both; |
| |
| case PAGE_SUCCESS: |
| unlock_page(newpage); |
| goto next; |
| |
| case PAGE_CLEAN: |
| ; /* try to migrate the page below */ |
| } |
| } |
| |
| /* |
| * Buffers are managed in a filesystem specific way. |
| * We must have no buffers or drop them. |
| */ |
| if (!page_has_buffers(page) || |
| try_to_release_page(page, GFP_KERNEL)) { |
| rc = migrate_page(mapping, newpage, page); |
| goto unlock_both; |
| } |
| |
| /* |
| * On early passes with mapped pages simply |
| * retry. There may be a lock held for some |
| * buffers that may go away. Later |
| * swap them out. |
| */ |
| if (pass > 4) { |
| /* |
| * Persistently unable to drop buffers..... As a |
| * measure of last resort we fall back to |
| * swap_page(). |
| */ |
| unlock_page(newpage); |
| newpage = NULL; |
| rc = swap_page(page); |
| goto next; |
| } |
| |
| unlock_both: |
| unlock_page(newpage); |
| |
| unlock_page: |
| unlock_page(page); |
| |
| next: |
| if (rc) { |
| if (newpage) |
| newpage->mapping = NULL; |
| |
| if (rc == -EAGAIN) |
| retry++; |
| else { |
| /* Permanent failure */ |
| list_move(&page->lru, failed); |
| nr_failed++; |
| } |
| } else { |
| if (newpage) { |
| /* Successful migration. Return page to LRU */ |
| move_to_lru(newpage); |
| } |
| list_move(&page->lru, moved); |
| } |
| } |
| if (retry && pass++ < 10) |
| goto redo; |
| |
| if (!swapwrite) |
| current->flags &= ~PF_SWAPWRITE; |
| |
| return nr_failed + retry; |
| } |
| |
| /* |
| * Migrate the list 'pagelist' of pages to a certain destination. |
| * |
| * Specify destination with either non-NULL vma or dest_node >= 0 |
| * Return the number of pages not migrated or error code |
| */ |
| int migrate_pages_to(struct list_head *pagelist, |
| struct vm_area_struct *vma, int dest) |
| { |
| LIST_HEAD(newlist); |
| LIST_HEAD(moved); |
| LIST_HEAD(failed); |
| int err = 0; |
| unsigned long offset = 0; |
| int nr_pages; |
| struct page *page; |
| struct list_head *p; |
| |
| redo: |
| nr_pages = 0; |
| list_for_each(p, pagelist) { |
| if (vma) { |
| /* |
| * The address passed to alloc_page_vma is used to |
| * generate the proper interleave behavior. We fake |
| * the address here by an increasing offset in order |
| * to get the proper distribution of pages. |
| * |
| * No decision has been made as to which page |
| * a certain old page is moved to so we cannot |
| * specify the correct address. |
| */ |
| page = alloc_page_vma(GFP_HIGHUSER, vma, |
| offset + vma->vm_start); |
| offset += PAGE_SIZE; |
| } |
| else |
| page = alloc_pages_node(dest, GFP_HIGHUSER, 0); |
| |
| if (!page) { |
| err = -ENOMEM; |
| goto out; |
| } |
| list_add_tail(&page->lru, &newlist); |
| nr_pages++; |
| if (nr_pages > MIGRATE_CHUNK_SIZE) |
| break; |
| } |
| err = migrate_pages(pagelist, &newlist, &moved, &failed); |
| |
| putback_lru_pages(&moved); /* Call release pages instead ?? */ |
| |
| if (err >= 0 && list_empty(&newlist) && !list_empty(pagelist)) |
| goto redo; |
| out: |
| /* Return leftover allocated pages */ |
| while (!list_empty(&newlist)) { |
| page = list_entry(newlist.next, struct page, lru); |
| list_del(&page->lru); |
| __free_page(page); |
| } |
| list_splice(&failed, pagelist); |
| if (err < 0) |
| return err; |
| |
| /* Calculate number of leftover pages */ |
| nr_pages = 0; |
| list_for_each(p, pagelist) |
| nr_pages++; |
| return nr_pages; |
| } |