2011-06-23 01:13:09

by David Rientjes

[permalink] [raw]
Subject: [patch 1/2] mm, hotplug: fix error handling in mem_online_node()

The error handling in mem_online_node() is incorrect: hotadd_new_pgdat()
returns NULL if the new pgdat could not have been allocated and a pointer
to it otherwise.

mem_online_node() should fail if hotadd_new_pgdat() fails, not the
inverse. This fixes an issue when memoryless nodes are not onlined and
their sysfs interface is not registered when their first cpu is brought
up.

Signed-off-by: David Rientjes <[email protected]>
---
mm/memory_hotplug.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -521,7 +521,7 @@ int mem_online_node(int nid)

lock_memory_hotplug();
pgdat = hotadd_new_pgdat(nid, 0);
- if (pgdat) {
+ if (!pgdat) {
ret = -ENOMEM;
goto out;
}


2011-06-23 01:13:14

by David Rientjes

[permalink] [raw]
Subject: [patch 2/2] mm, hotplug: protect zonelist building with zonelists_mutex

959ecc48fc75 ("mm/memory_hotplug.c: fix building of node hotplug
zonelist") does not protect the build_all_zonelists() call with
zonelists_mutex as needed. This can lead to races in constructing
zonelist ordering if a concurrent build is underway. Protecting this with
lock_memory_hotplug() is insufficient since zonelists can be rebuild
though sysfs as well.

Signed-off-by: David Rientjes <[email protected]>
---
mm/memory_hotplug.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -498,7 +498,9 @@ static pg_data_t __ref *hotadd_new_pgdat(int nid, u64 start)
* The node we allocated has no zone fallback lists. For avoiding
* to access not-initialized zonelist, build here.
*/
+ mutex_lock(&zonelists_mutex);
build_all_zonelists(NULL);
+ mutex_unlock(&zonelists_mutex);

return pgdat;
}

2011-06-23 01:31:25

by KOSAKI Motohiro

[permalink] [raw]
Subject: Re: [patch 1/2] mm, hotplug: fix error handling in mem_online_node()

(2011/06/23 10:13), David Rientjes wrote:
> The error handling in mem_online_node() is incorrect: hotadd_new_pgdat()
> returns NULL if the new pgdat could not have been allocated and a pointer
> to it otherwise.
>
> mem_online_node() should fail if hotadd_new_pgdat() fails, not the
> inverse. This fixes an issue when memoryless nodes are not onlined and
> their sysfs interface is not registered when their first cpu is brought
> up.
>
> Signed-off-by: David Rientjes <[email protected]>

Nice catch.

The fault was introduced by commit cf23422b9d76(cpu/mem hotplug: enable CPUs
online before local memory online) iow v2.6.35.

Reviewed-by: KOSAKI Motohiro <[email protected]>


> ---
> mm/memory_hotplug.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -521,7 +521,7 @@ int mem_online_node(int nid)
>
> lock_memory_hotplug();
> pgdat = hotadd_new_pgdat(nid, 0);
> - if (pgdat) {
> + if (!pgdat) {
> ret = -ENOMEM;
> goto out;
> }
>
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to [email protected]. For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
> Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
>
>

2011-06-23 01:35:07

by KOSAKI Motohiro

[permalink] [raw]
Subject: Re: [patch 2/2] mm, hotplug: protect zonelist building with zonelists_mutex

(2011/06/23 10:13), David Rientjes wrote:
> 959ecc48fc75 ("mm/memory_hotplug.c: fix building of node hotplug
> zonelist") does not protect the build_all_zonelists() call with
> zonelists_mutex as needed. This can lead to races in constructing
> zonelist ordering if a concurrent build is underway. Protecting this with
> lock_memory_hotplug() is insufficient since zonelists can be rebuild
> though sysfs as well.
>
> Signed-off-by: David Rientjes <[email protected]>

Indeed.

Reviewed-by: KOSAKI Motohiro <[email protected]>

> ---
> mm/memory_hotplug.c | 2 ++
> 1 files changed, 2 insertions(+), 0 deletions(-)
>
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -498,7 +498,9 @@ static pg_data_t __ref *hotadd_new_pgdat(int nid, u64 start)
> * The node we allocated has no zone fallback lists. For avoiding
> * to access not-initialized zonelist, build here.
> */
> + mutex_lock(&zonelists_mutex);
> build_all_zonelists(NULL);
> + mutex_unlock(&zonelists_mutex);
>
> return pgdat;
> }
>
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to [email protected]. For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
> Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
>
>