linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [Patch v3 0/4] cleanup on do_pages_move()
@ 2020-01-26 10:26 Wei Yang
  2020-01-26 10:26 ` [Patch v3 1/4] mm/migrate.c: not necessary to check start and i Wei Yang
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Wei Yang @ 2020-01-26 10:26 UTC (permalink / raw)
  To: akpm; +Cc: mhocko, yang.shi, rientjes, linux-mm, linux-kernel, Wei Yang

The logic in do_pages_move() is a little mess for audience to read and has
some potential error on handling the return value. Especially there are
three calls on do_move_pages_to_node() and store_status() with almost the
same form.

This patch set tries to make the code a little friendly for audience by
consolidate the calls.

v3:
  * rebase on top of Yang Shi's fix "mm: move_pages: report the number of
    non-attempted pages"
v2:
  * remove some unnecessary cleanup


Wei Yang (4):
  mm/migrate.c: not necessary to check start and i
  mm/migrate.c: wrap do_move_pages_to_node() and store_status()
  mm/migrate.c: check pagelist in move_pages_and_store_status()
  mm/migrate.c: handle same node and add failure in the same way

 mm/migrate.c | 90 ++++++++++++++++++++++++----------------------------
 1 file changed, 42 insertions(+), 48 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Patch v3 1/4] mm/migrate.c: not necessary to check start and i
  2020-01-26 10:26 [Patch v3 0/4] cleanup on do_pages_move() Wei Yang
@ 2020-01-26 10:26 ` Wei Yang
  2020-01-26 10:26 ` [Patch v3 2/4] mm/migrate.c: wrap do_move_pages_to_node() and store_status() Wei Yang
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Wei Yang @ 2020-01-26 10:26 UTC (permalink / raw)
  To: akpm; +Cc: mhocko, yang.shi, rientjes, linux-mm, linux-kernel, Wei Yang

Till here, i must no less than start. And if i equals to start,
store_status() would always return 0.

Remove some unnecessary check to make it easy to read and prepare for
further cleanup.

Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
Acked-by: Michal Hocko <mhocko@suse.com>
---
 mm/migrate.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/mm/migrate.c b/mm/migrate.c
index 6a6c8f247bce..ae3db45c6a42 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1674,11 +1674,9 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
 				err += nr_pages - i - 1;
 			goto out;
 		}
-		if (i > start) {
-			err = store_status(status, start, current_node, i - start);
-			if (err)
-				goto out;
-		}
+		err = store_status(status, start, current_node, i - start);
+		if (err)
+			goto out;
 		current_node = NUMA_NO_NODE;
 	}
 out_flush:
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Patch v3 2/4] mm/migrate.c: wrap do_move_pages_to_node() and store_status()
  2020-01-26 10:26 [Patch v3 0/4] cleanup on do_pages_move() Wei Yang
  2020-01-26 10:26 ` [Patch v3 1/4] mm/migrate.c: not necessary to check start and i Wei Yang
@ 2020-01-26 10:26 ` Wei Yang
  2020-01-27  9:36   ` Michal Hocko
  2020-01-26 10:26 ` [Patch v3 3/4] mm/migrate.c: check pagelist in move_pages_and_store_status() Wei Yang
  2020-01-26 10:26 ` [Patch v3 4/4] mm/migrate.c: handle same node and add failure in the same way Wei Yang
  3 siblings, 1 reply; 7+ messages in thread
From: Wei Yang @ 2020-01-26 10:26 UTC (permalink / raw)
  To: akpm; +Cc: mhocko, yang.shi, rientjes, linux-mm, linux-kernel, Wei Yang

Usually do_move_pages_to_node() and store_status() is a pair. There are
three places call this pair of functions with almost the same form.

This patch just wrap it to make it friendly to audience and also
consolidate the move and store action into one place.

Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
---
 mm/migrate.c | 61 ++++++++++++++++++++++++++--------------------------
 1 file changed, 30 insertions(+), 31 deletions(-)

diff --git a/mm/migrate.c b/mm/migrate.c
index ae3db45c6a42..e816c8990296 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1583,6 +1583,29 @@ static int add_page_for_migration(struct mm_struct *mm, unsigned long addr,
 	return err;
 }
 
+static int move_pages_and_store_status(struct mm_struct *mm, int node,
+		struct list_head *pagelist, int __user *status,
+		unsigned long nr_pages, int start, int i)
+{
+	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 incude the rest of the
+		 * nr_pages that have not attempted as well.
+		 */
+		if (err > 0)
+			err += nr_pages - i - 1;
+		return err;
+	}
+	err = store_status(status, start, node, i - start);
+	return err;
+}
+
 /*
  * Migrate an array of page address onto an array of nodes and fill
  * the corresponding array of status.
@@ -1626,20 +1649,9 @@ 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 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);
+			err = move_pages_and_store_status(mm, current_node,
+					&pagelist, status, nr_pages,
+					start, i);
 			if (err)
 				goto out;
 			start = i;
@@ -1668,13 +1680,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, nr_pages, start, i);
 		if (err)
 			goto out;
 		current_node = NUMA_NO_NODE;
@@ -1684,16 +1691,8 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
 		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 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);
+	err1 = move_pages_and_store_status(mm, current_node, &pagelist,
+			status, nr_pages, start, i);
 	if (err >= 0)
 		err = err1;
 out:
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Patch v3 3/4] mm/migrate.c: check pagelist in move_pages_and_store_status()
  2020-01-26 10:26 [Patch v3 0/4] cleanup on do_pages_move() Wei Yang
  2020-01-26 10:26 ` [Patch v3 1/4] mm/migrate.c: not necessary to check start and i Wei Yang
  2020-01-26 10:26 ` [Patch v3 2/4] mm/migrate.c: wrap do_move_pages_to_node() and store_status() Wei Yang
@ 2020-01-26 10:26 ` Wei Yang
  2020-01-26 10:26 ` [Patch v3 4/4] mm/migrate.c: handle same node and add failure in the same way Wei Yang
  3 siblings, 0 replies; 7+ messages in thread
From: Wei Yang @ 2020-01-26 10:26 UTC (permalink / raw)
  To: akpm; +Cc: mhocko, yang.shi, rientjes, linux-mm, linux-kernel, Wei Yang

When pagelist is empty, it is not necessary to do the move and store.
Also it consolidate the empty list check in one place.

Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
Acked-by: Michal Hocko <mhocko@suse.com>
---
 mm/migrate.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/mm/migrate.c b/mm/migrate.c
index e816c8990296..b123ced445b7 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1499,9 +1499,6 @@ static int do_move_pages_to_node(struct mm_struct *mm,
 {
 	int err;
 
-	if (list_empty(pagelist))
-		return 0;
-
 	err = migrate_pages(pagelist, alloc_new_node_page, NULL, node,
 			MIGRATE_SYNC, MR_SYSCALL);
 	if (err)
@@ -1589,6 +1586,9 @@ static int move_pages_and_store_status(struct mm_struct *mm, int node,
 {
 	int err;
 
+	if (list_empty(pagelist))
+		return 0;
+
 	err = do_move_pages_to_node(mm, pagelist, node);
 	if (err) {
 		/*
@@ -1687,9 +1687,6 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
 		current_node = NUMA_NO_NODE;
 	}
 out_flush:
-	if (list_empty(&pagelist))
-		return err;
-
 	/* Make sure we do not overwrite the existing error */
 	err1 = move_pages_and_store_status(mm, current_node, &pagelist,
 			status, nr_pages, start, i);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Patch v3 4/4] mm/migrate.c: handle same node and add failure in the same way
  2020-01-26 10:26 [Patch v3 0/4] cleanup on do_pages_move() Wei Yang
                   ` (2 preceding siblings ...)
  2020-01-26 10:26 ` [Patch v3 3/4] mm/migrate.c: check pagelist in move_pages_and_store_status() Wei Yang
@ 2020-01-26 10:26 ` Wei Yang
  3 siblings, 0 replies; 7+ messages in thread
From: Wei Yang @ 2020-01-26 10:26 UTC (permalink / raw)
  To: akpm; +Cc: mhocko, yang.shi, rientjes, linux-mm, linux-kernel, Wei Yang

When page is not queued for migration, there are two possible cases:

  * page already on the target node
  * failed to add to migration queue

Current code handle them differently, this leads to a behavior
inconsistency.

Usually for each page's status, we just do store for once. While for the
page already on the target node, we might store the node information for
twice:

  * once when we found the page is on the target node
  * second when moving the pages to target node successfully after above
    action

The reason is even we don't add the page to pagelist, but store_status()
does store in a range which still contains the page.

This patch handles these two cases in the same way to reduce this
inconsistency and also make the code a little easier to read.

Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
Acked-by: Michal Hocko <mhocko@suse.com>
---
 mm/migrate.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/mm/migrate.c b/mm/migrate.c
index b123ced445b7..bb4f45b120fd 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1665,18 +1665,18 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
 		err = add_page_for_migration(mm, addr, current_node,
 				&pagelist, flags & MPOL_MF_MOVE_ALL);
 
-		if (!err) {
-			/* The page is already on the target node */
-			err = store_status(status, i, current_node, 1);
-			if (err)
-				goto out_flush;
-			continue;
-		} else if (err > 0) {
+		if (err > 0) {
 			/* The page is successfully queued for migration */
 			continue;
 		}
 
-		err = store_status(status, i, err, 1);
+		/*
+		 * Two possible cases for err here:
+		 * == 0: page is already on the target node, then store
+		 *       current_node to status
+		 * <  0: failed to add page to list, then store err to status
+		 */
+		err = store_status(status, i, err ? : current_node, 1);
 		if (err)
 			goto out_flush;
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [Patch v3 2/4] mm/migrate.c: wrap do_move_pages_to_node() and store_status()
  2020-01-26 10:26 ` [Patch v3 2/4] mm/migrate.c: wrap do_move_pages_to_node() and store_status() Wei Yang
@ 2020-01-27  9:36   ` Michal Hocko
  2020-01-28  0:31     ` Wei Yang
  0 siblings, 1 reply; 7+ messages in thread
From: Michal Hocko @ 2020-01-27  9:36 UTC (permalink / raw)
  To: Wei Yang; +Cc: akpm, yang.shi, rientjes, linux-mm, linux-kernel

On Sun 26-01-20 18:26:21, Wei Yang wrote:
> Usually do_move_pages_to_node() and store_status() is a pair. There are
> three places call this pair of functions with almost the same form.
> 
> This patch just wrap it to make it friendly to audience and also
> consolidate the move and store action into one place.
> 
> Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>

I believe I have already acked this one. Anyway
Acked-by: Michal Hocko <mhocko@suse.com>

> ---
>  mm/migrate.c | 61 ++++++++++++++++++++++++++--------------------------
>  1 file changed, 30 insertions(+), 31 deletions(-)
> 
> diff --git a/mm/migrate.c b/mm/migrate.c
> index ae3db45c6a42..e816c8990296 100644
> --- a/mm/migrate.c
> +++ b/mm/migrate.c
> @@ -1583,6 +1583,29 @@ static int add_page_for_migration(struct mm_struct *mm, unsigned long addr,
>  	return err;
>  }
>  
> +static int move_pages_and_store_status(struct mm_struct *mm, int node,
> +		struct list_head *pagelist, int __user *status,
> +		unsigned long nr_pages, int start, int i)
> +{
> +	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 incude the rest of the
> +		 * nr_pages that have not attempted as well.
> +		 */
> +		if (err > 0)
> +			err += nr_pages - i - 1;
> +		return err;
> +	}
> +	err = store_status(status, start, node, i - start);
> +	return err;
> +}
> +
>  /*
>   * Migrate an array of page address onto an array of nodes and fill
>   * the corresponding array of status.
> @@ -1626,20 +1649,9 @@ 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 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);
> +			err = move_pages_and_store_status(mm, current_node,
> +					&pagelist, status, nr_pages,
> +					start, i);
>  			if (err)
>  				goto out;
>  			start = i;
> @@ -1668,13 +1680,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, nr_pages, start, i);
>  		if (err)
>  			goto out;
>  		current_node = NUMA_NO_NODE;
> @@ -1684,16 +1691,8 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
>  		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 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);
> +	err1 = move_pages_and_store_status(mm, current_node, &pagelist,
> +			status, nr_pages, start, i);
>  	if (err >= 0)
>  		err = err1;
>  out:
> -- 
> 2.17.1

-- 
Michal Hocko
SUSE Labs

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Patch v3 2/4] mm/migrate.c: wrap do_move_pages_to_node() and store_status()
  2020-01-27  9:36   ` Michal Hocko
@ 2020-01-28  0:31     ` Wei Yang
  0 siblings, 0 replies; 7+ messages in thread
From: Wei Yang @ 2020-01-28  0:31 UTC (permalink / raw)
  To: Michal Hocko; +Cc: Wei Yang, akpm, yang.shi, rientjes, linux-mm, linux-kernel

On Mon, Jan 27, 2020 at 10:36:42AM +0100, Michal Hocko wrote:
>On Sun 26-01-20 18:26:21, Wei Yang wrote:
>> Usually do_move_pages_to_node() and store_status() is a pair. There are
>> three places call this pair of functions with almost the same form.
>> 
>> This patch just wrap it to make it friendly to audience and also
>> consolidate the move and store action into one place.
>> 
>> Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
>
>I believe I have already acked this one. Anyway
>Acked-by: Michal Hocko <mhocko@suse.com>
>

Yep, since some change from original code, I dropped your ack.

Thanks

>> ---
>>  mm/migrate.c | 61 ++++++++++++++++++++++++++--------------------------
>>  1 file changed, 30 insertions(+), 31 deletions(-)
>> 
>> diff --git a/mm/migrate.c b/mm/migrate.c
>> index ae3db45c6a42..e816c8990296 100644
>> --- a/mm/migrate.c
>> +++ b/mm/migrate.c
>> @@ -1583,6 +1583,29 @@ static int add_page_for_migration(struct mm_struct *mm, unsigned long addr,
>>  	return err;
>>  }
>>  
>> +static int move_pages_and_store_status(struct mm_struct *mm, int node,
>> +		struct list_head *pagelist, int __user *status,
>> +		unsigned long nr_pages, int start, int i)
>> +{
>> +	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 incude the rest of the
>> +		 * nr_pages that have not attempted as well.
>> +		 */
>> +		if (err > 0)
>> +			err += nr_pages - i - 1;
>> +		return err;
>> +	}
>> +	err = store_status(status, start, node, i - start);
>> +	return err;
>> +}
>> +
>>  /*
>>   * Migrate an array of page address onto an array of nodes and fill
>>   * the corresponding array of status.
>> @@ -1626,20 +1649,9 @@ 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 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);
>> +			err = move_pages_and_store_status(mm, current_node,
>> +					&pagelist, status, nr_pages,
>> +					start, i);
>>  			if (err)
>>  				goto out;
>>  			start = i;
>> @@ -1668,13 +1680,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, nr_pages, start, i);
>>  		if (err)
>>  			goto out;
>>  		current_node = NUMA_NO_NODE;
>> @@ -1684,16 +1691,8 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
>>  		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 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);
>> +	err1 = move_pages_and_store_status(mm, current_node, &pagelist,
>> +			status, nr_pages, start, i);
>>  	if (err >= 0)
>>  		err = err1;
>>  out:
>> -- 
>> 2.17.1
>
>-- 
>Michal Hocko
>SUSE Labs

-- 
Wei Yang
Help you, Help me

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-01-28  0:31 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-26 10:26 [Patch v3 0/4] cleanup on do_pages_move() Wei Yang
2020-01-26 10:26 ` [Patch v3 1/4] mm/migrate.c: not necessary to check start and i Wei Yang
2020-01-26 10:26 ` [Patch v3 2/4] mm/migrate.c: wrap do_move_pages_to_node() and store_status() Wei Yang
2020-01-27  9:36   ` Michal Hocko
2020-01-28  0:31     ` Wei Yang
2020-01-26 10:26 ` [Patch v3 3/4] mm/migrate.c: check pagelist in move_pages_and_store_status() Wei Yang
2020-01-26 10:26 ` [Patch v3 4/4] mm/migrate.c: handle same node and add failure in the same way Wei Yang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).