mm/migrate.c: wrap do_move_pages_to_node() and store_status()

Usually, do_move_pages_to_node() and store_status() are used in
combination.  We have three similar call sites.

Let's provide a wrapper for both function calls -
move_pages_and_store_status - to make the calling code easier to maintain
and fix (as noted by Yang Shi, the return value handling of
do_move_pages_to_node() has a flaw).

[david@redhat.com rephrase changelog]
Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: David Hildenbrand <david@redhat.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Link: http://lkml.kernel.org/r/20200214003017.25558-3-richardw.yang@linux.intel.com
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Wei Yang 2020-04-06 20:04:12 -07:00 committed by Linus Torvalds
parent 4afdacec2e
commit 7ca8783ad8
1 changed files with 29 additions and 32 deletions

View File

@ -1602,6 +1602,29 @@ out:
return err;
}
static int move_pages_and_store_status(struct mm_struct *mm, int node,
struct list_head *pagelist, int __user *status,
int start, int i, unsigned long nr_pages)
{
int err;
err = do_move_pages_to_node(mm, pagelist, node);
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 to incude the rest of the
* nr_pages that have not been attempted as
* well.
*/
if (err > 0)
err += nr_pages - i - 1;
return err;
}
return store_status(status, start, node, i - start);
}
/*
* Migrate an array of page address onto an array of nodes and fill
* the corresponding array of status.
@ -1645,21 +1668,8 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
current_node = node;
start = i;
} else if (node != current_node) {
err = do_move_pages_to_node(mm, &pagelist, current_node);
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 to incude the rest of the
* nr_pages that have not been attempted as
* well.
*/
if (err > 0)
err += nr_pages - i - 1;
goto out;
}
err = store_status(status, start, current_node, i - start);
err = move_pages_and_store_status(mm, current_node,
&pagelist, status, start, i, nr_pages);
if (err)
goto out;
start = i;
@ -1688,13 +1698,8 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
if (err)
goto out_flush;
err = do_move_pages_to_node(mm, &pagelist, current_node);
if (err) {
if (err > 0)
err += nr_pages - i - 1;
goto out;
}
err = store_status(status, start, current_node, i - start);
err = move_pages_and_store_status(mm, current_node, &pagelist,
status, start, i, nr_pages);
if (err)
goto out;
current_node = NUMA_NO_NODE;
@ -1704,16 +1709,8 @@ out_flush:
return err;
/* 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 all pages have been
* attempted.
* - If the above loop is aborted it means a fatal error
* happened, should return ret.
*/
if (!err1)
err1 = store_status(status, start, current_node, i - start);
err1 = move_pages_and_store_status(mm, current_node, &pagelist,
status, start, i, nr_pages);
if (err >= 0)
err = err1;
out: