]> Git Repo - linux.git/commitdiff
hugetlb: simplify migrate_huge_page()
authorAneesh Kumar K.V <[email protected]>
Tue, 31 Jul 2012 23:42:06 +0000 (16:42 -0700)
committerLinus Torvalds <[email protected]>
Wed, 1 Aug 2012 01:42:40 +0000 (18:42 -0700)
Since we migrate only one hugepage, don't use linked list for passing the
page around.  Directly pass the page that need to be migrated as argument.
This also removes the usage of page->lru in the migrate path.

Signed-off-by: Aneesh Kumar K.V <[email protected]>
Reviewed-by: KAMEZAWA Hiroyuki <[email protected]>
Cc: David Rientjes <[email protected]>
Cc: Hillf Danton <[email protected]>
Reviewed-by: Michal Hocko <[email protected]>
Cc: KOSAKI Motohiro <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
include/linux/migrate.h
mm/memory-failure.c
mm/migrate.c

index 855c337b20c35cb22ef0a3fa6213cfb82a3a90b0..ce7e6671968b791194df3c35d180443dbd615869 100644 (file)
@@ -15,7 +15,7 @@ extern int migrate_page(struct address_space *,
 extern int migrate_pages(struct list_head *l, new_page_t x,
                        unsigned long private, bool offlining,
                        enum migrate_mode mode);
-extern int migrate_huge_pages(struct list_head *l, new_page_t x,
+extern int migrate_huge_page(struct page *, new_page_t x,
                        unsigned long private, bool offlining,
                        enum migrate_mode mode);
 
@@ -36,7 +36,7 @@ static inline void putback_lru_pages(struct list_head *l) {}
 static inline int migrate_pages(struct list_head *l, new_page_t x,
                unsigned long private, bool offlining,
                enum migrate_mode mode) { return -ENOSYS; }
-static inline int migrate_huge_pages(struct list_head *l, new_page_t x,
+static inline int migrate_huge_page(struct page *page, new_page_t x,
                unsigned long private, bool offlining,
                enum migrate_mode mode) { return -ENOSYS; }
 
index 6de0d613bbe6a49448259ac0ae317b669751f748..b04ff2d6f73de87ee8991b33ff88b1dae1ba7da7 100644 (file)
@@ -1416,7 +1416,6 @@ static int soft_offline_huge_page(struct page *page, int flags)
        int ret;
        unsigned long pfn = page_to_pfn(page);
        struct page *hpage = compound_head(page);
-       LIST_HEAD(pagelist);
 
        ret = get_any_page(page, pfn, flags);
        if (ret < 0)
@@ -1431,24 +1430,18 @@ static int soft_offline_huge_page(struct page *page, int flags)
        }
 
        /* Keep page count to indicate a given hugepage is isolated. */
-
-       list_add(&hpage->lru, &pagelist);
-       ret = migrate_huge_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL, false,
+       ret = migrate_huge_page(hpage, new_page, MPOL_MF_MOVE_ALL, false,
                                MIGRATE_SYNC);
+       put_page(hpage);
        if (ret) {
-               struct page *page1, *page2;
-               list_for_each_entry_safe(page1, page2, &pagelist, lru)
-                       put_page(page1);
-
                pr_info("soft offline: %#lx: migration failed %d, type %lx\n",
                        pfn, ret, page->flags);
-               if (ret > 0)
-                       ret = -EIO;
                return ret;
        }
 done:
        if (!PageHWPoison(hpage))
-               atomic_long_add(1 << compound_trans_order(hpage), &mce_bad_pages);
+               atomic_long_add(1 << compound_trans_order(hpage),
+                               &mce_bad_pages);
        set_page_hwpoison_huge_page(hpage);
        dequeue_hwpoisoned_huge_page(hpage);
        /* keep elevated page count for bad page */
index be26d5cbe56b34d63f8c8ac8b799782f9ef6424b..fdce3a29fc4c2261a73d5f4201f9bcbb4b0b1b40 100644 (file)
@@ -932,15 +932,8 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
        if (anon_vma)
                put_anon_vma(anon_vma);
        unlock_page(hpage);
-
 out:
-       if (rc != -EAGAIN) {
-               list_del(&hpage->lru);
-               put_page(hpage);
-       }
-
        put_page(new_hpage);
-
        if (result) {
                if (rc)
                        *result = rc;
@@ -1016,48 +1009,32 @@ out:
        return nr_failed + retry;
 }
 
-int migrate_huge_pages(struct list_head *from,
-               new_page_t get_new_page, unsigned long private, bool offlining,
-               enum migrate_mode mode)
+int migrate_huge_page(struct page *hpage, new_page_t get_new_page,
+                     unsigned long private, bool offlining,
+                     enum migrate_mode mode)
 {
-       int retry = 1;
-       int nr_failed = 0;
-       int pass = 0;
-       struct page *page;
-       struct page *page2;
-       int rc;
-
-       for (pass = 0; pass < 10 && retry; pass++) {
-               retry = 0;
-
-               list_for_each_entry_safe(page, page2, from, lru) {
+       int pass, rc;
+
+       for (pass = 0; pass < 10; pass++) {
+               rc = unmap_and_move_huge_page(get_new_page,
+                                             private, hpage, pass > 2, offlining,
+                                             mode);
+               switch (rc) {
+               case -ENOMEM:
+                       goto out;
+               case -EAGAIN:
+                       /* try again */
                        cond_resched();
-
-                       rc = unmap_and_move_huge_page(get_new_page,
-                                       private, page, pass > 2, offlining,
-                                       mode);
-
-                       switch(rc) {
-                       case -ENOMEM:
-                               goto out;
-                       case -EAGAIN:
-                               retry++;
-                               break;
-                       case 0:
-                               break;
-                       default:
-                               /* Permanent failure */
-                               nr_failed++;
-                               break;
-                       }
+                       break;
+               case 0:
+                       goto out;
+               default:
+                       rc = -EIO;
+                       goto out;
                }
        }
-       rc = 0;
 out:
-       if (rc)
-               return rc;
-
-       return nr_failed + retry;
+       return rc;
 }
 
 #ifdef CONFIG_NUMA
This page took 0.069939 seconds and 4 git commands to generate.