Since commit a49bd4d71637 ("mm, numa: rework do_pages_move"), the semantic of move_pages() was changed to return the number of non-migrated pages (failed to migration) and the call would be aborted immediately if migrate_pages() returns positive value. But it didn't report the number of pages that we even haven't attempted to migrate. So, fix it by including non-attempted pages in the return value. Fixes: a49bd4d71637 ("mm, numa: rework do_pages_move") Suggested-by: Michal Hocko <mhocko@xxxxxxxx> Cc: Wei Yang <richardw.yang@xxxxxxxxxxxxxxx> Cc: <stable@xxxxxxxxxxxxxxx> [4.17+] Signed-off-by: Yang Shi <yang.shi@xxxxxxxxxxxxxxxxx> --- v2: Rebased on top of the latest mainline kernel per Andrew mm/migrate.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/mm/migrate.c b/mm/migrate.c index 86873b6..9b8eb5d 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -1627,8 +1627,18 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes, start = i; } else if (node != current_node) { err = do_move_pages_to_node(mm, &pagelist, current_node); - if (err) + if (err) { + /* + * Positive err means the number of failed + * pages to migrate. Since we are going to + * abort and return the number of non-migrated + * pages, so need incude the rest of the + * nr_pages that have not attempted as well. + */ + if (err > 0) + err += nr_pages - i - 1; goto out; + } err = store_status(status, start, current_node, i - start); if (err) goto out; @@ -1659,8 +1669,11 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes, goto out_flush; err = do_move_pages_to_node(mm, &pagelist, current_node); - if (err) + if (err) { + if (err > 0) + err += nr_pages - i - 1; goto out; + } if (i > start) { err = store_status(status, start, current_node, i - start); if (err) @@ -1674,6 +1687,13 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes, /* Make sure we do not overwrite the existing error */ err1 = do_move_pages_to_node(mm, &pagelist, current_node); + /* + * Don't have to report non-attempted pages here since: + * - If the above loop is done gracefully there is not non-attempted + * page. + * - If the above loop is aborted to it means more fatal error + * happened, should return err. + */ if (!err1) err1 = store_status(status, start, current_node, i - start); if (!err) -- 1.8.3.1