Commit cf608ac19c95804dc2df43b1f4f9e068aa9034ab

Authored by Minchan Kim
Committed by Linus Torvalds
1 parent e4455abb50

mm: compaction: fix COMPACTPAGEFAILED counting

Presently update_nr_listpages() doesn't have a role.  That's because lists
passed is always empty just after calling migrate_pages.  The
migrate_pages cleans up page list which have failed to migrate before
returning by aaa994b3.

 [PATCH] page migration: handle freeing of pages in migrate_pages()

 Do not leave pages on the lists passed to migrate_pages().  Seems that we will
 not need any postprocessing of pages.  This will simplify the handling of
 pages by the callers of migrate_pages().

At that time, we thought we don't need any postprocessing of pages.  But
the situation is changed.  The compaction need to know the number of
failed to migrate for COMPACTPAGEFAILED stat

This patch makes new rule for caller of migrate_pages to call
putback_lru_pages.  So caller need to clean up the lists so it has a
chance to postprocess the pages.  [suggested by Christoph Lameter]

Signed-off-by: Minchan Kim <minchan.kim@gmail.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Andi Kleen <andi@firstfloor.org>
Reviewed-by: Mel Gorman <mel@csn.ul.ie>
Reviewed-by: Wu Fengguang <fengguang.wu@intel.com>
Acked-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 4 changed files with 18 additions and 7 deletions Side-by-side Diff

... ... @@ -1292,6 +1292,7 @@
1292 1292 list_add(&hpage->lru, &pagelist);
1293 1293 ret = migrate_huge_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL, 0);
1294 1294 if (ret) {
  1295 + putback_lru_pages(&pagelist);
1295 1296 pr_debug("soft offline: %#lx: migration failed %d, type %lx\n",
1296 1297 pfn, ret, page->flags);
1297 1298 if (ret > 0)
... ... @@ -731,6 +731,8 @@
731 731 goto out;
732 732 /* this function returns # of failed pages */
733 733 ret = migrate_pages(&source, hotremove_migrate_alloc, 0, 1);
  734 + if (ret)
  735 + putback_lru_pages(&source);
734 736  
735 737 out:
736 738 return ret;
... ... @@ -931,8 +931,11 @@
931 931 check_range(mm, mm->mmap->vm_start, mm->task_size, &nmask,
932 932 flags | MPOL_MF_DISCONTIG_OK, &pagelist);
933 933  
934   - if (!list_empty(&pagelist))
  934 + if (!list_empty(&pagelist)) {
935 935 err = migrate_pages(&pagelist, new_node_page, dest, 0);
  936 + if (err)
  937 + putback_lru_pages(&pagelist);
  938 + }
936 939  
937 940 return err;
938 941 }
939 942  
... ... @@ -1147,9 +1150,12 @@
1147 1150  
1148 1151 err = mbind_range(mm, start, end, new);
1149 1152  
1150   - if (!list_empty(&pagelist))
  1153 + if (!list_empty(&pagelist)) {
1151 1154 nr_failed = migrate_pages(&pagelist, new_vma_page,
1152 1155 (unsigned long)vma, 0);
  1156 + if (nr_failed)
  1157 + putback_lru_pages(&pagelist);
  1158 + }
1153 1159  
1154 1160 if (!err && nr_failed && (flags & MPOL_MF_STRICT))
1155 1161 err = -EIO;
... ... @@ -883,8 +883,9 @@
883 883 *
884 884 * The function returns after 10 attempts or if no pages
885 885 * are movable anymore because to has become empty
886   - * or no retryable pages exist anymore. All pages will be
887   - * returned to the LRU or freed.
  886 + * or no retryable pages exist anymore.
  887 + * Caller should call putback_lru_pages to return pages to the LRU
  888 + * or free list.
888 889 *
889 890 * Return: Number of pages not migrated or error code.
890 891 */
... ... @@ -931,8 +932,6 @@
931 932 if (!swapwrite)
932 933 current->flags &= ~PF_SWAPWRITE;
933 934  
934   - putback_lru_pages(from);
935   -
936 935 if (rc)
937 936 return rc;
938 937  
939 938  
... ... @@ -1087,9 +1086,12 @@
1087 1086 }
1088 1087  
1089 1088 err = 0;
1090   - if (!list_empty(&pagelist))
  1089 + if (!list_empty(&pagelist)) {
1091 1090 err = migrate_pages(&pagelist, new_page_node,
1092 1091 (unsigned long)pm, 0);
  1092 + if (err)
  1093 + putback_lru_pages(&pagelist);
  1094 + }
1093 1095  
1094 1096 up_read(&mm->mmap_sem);
1095 1097 return err;