Commit 7ca8783a authored by Wei Yang's avatar Wei Yang Committed by Linus Torvalds
Browse files

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: default avatarWei Yang <richardw.yang@linux.intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Reviewed-by: default avatarDavid Hildenbrand <david@redhat.com>
Acked-by: default avatarMichal Hocko <mhocko@suse.com>
Link: http://lkml.kernel.org/r/20200214003017.25558-3-richardw.yang@linux.intel.com


Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 4afdacec
Loading
Loading
Loading
Loading
+29 −32
Original line number Diff line number Diff line
@@ -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: