Re: [PATCH 2/3] memory-hotplug: more general validation of zone during online

2016-05-13 Thread Yasuaki Ishimatsu

On Mon,  9 May 2016 12:53:38 -0500
Reza Arbab  wrote:

> When memory is onlined, we are only able to rezone from ZONE_MOVABLE to
> ZONE_KERNEL, or from (ZONE_MOVABLE - 1) to ZONE_MOVABLE.
> 
> To be more flexible, use the following criteria instead; to online memory
> from zone X into zone Y,
> 
> * Any zones between X and Y must be unused.
> * If X is lower than Y, the onlined memory must lie at the end of X.
> * If X is higher than Y, the onlined memory must lie at the start of X.
> 
> Add zone_can_shift() to make this determination.
> 
> Signed-off-by: Reza Arbab 
> ---

Looks good to me.

Reviewd-by: Yasuaki Ishimatsu 

Thanks,
Yasuaki Ishimatsu

>  include/linux/memory_hotplug.h |  2 ++
>  mm/memory_hotplug.c| 42 
> +++---
>  2 files changed, 37 insertions(+), 7 deletions(-)
> 
> diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
> index adbef58..7bff0f9 100644
> --- a/include/linux/memory_hotplug.h
> +++ b/include/linux/memory_hotplug.h
> @@ -284,5 +284,7 @@ extern void sparse_remove_one_section(struct zone *zone, 
> struct mem_section *ms,
>   unsigned long map_offset);
>  extern struct page *sparse_decode_mem_map(unsigned long coded_mem_map,
> unsigned long pnum);
> +extern int zone_can_shift(unsigned long pfn, unsigned long nr_pages,
> +   enum zone_type target);
>  
>  #endif /* __LINUX_MEMORY_HOTPLUG_H */
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index 6b4b005..b63cc28 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -1032,6 +1032,37 @@ static void node_states_set_node(int node, struct 
> memory_notify *arg)
>   node_set_state(node, N_MEMORY);
>  }
>  
> +int zone_can_shift(unsigned long pfn, unsigned long nr_pages,
> +enum zone_type target)
> +{
> + struct zone *zone = page_zone(pfn_to_page(pfn));
> + enum zone_type idx = zone_idx(zone);
> + int i;
> +
> + if (idx < target) {
> + /* pages must be at end of current zone */
> + if (pfn + nr_pages != zone_end_pfn(zone))
> + return 0;
> +
> + /* no zones in use between current zone and target */
> + for (i = idx + 1; i < target; i++)
> + if (zone_is_initialized(zone - idx + i))
> + return 0;
> + }
> +
> + if (target < idx) {
> + /* pages must be at beginning of current zone */
> + if (pfn != zone->zone_start_pfn)
> + return 0;
> +
> + /* no zones in use between current zone and target */
> + for (i = target + 1; i < idx; i++)
> + if (zone_is_initialized(zone - idx + i))
> + return 0;
> + }
> +
> + return target - idx;
> +}
>  
>  /* Must be protected by mem_hotplug_begin() */
>  int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int 
> online_type)
> @@ -1057,13 +1088,10 @@ int __ref online_pages(unsigned long pfn, unsigned 
> long nr_pages, int online_typ
>   !can_online_high_movable(zone))
>   return -EINVAL;
>  
> - if (online_type == MMOP_ONLINE_KERNEL &&
> - zone_idx(zone) == ZONE_MOVABLE)
> - zone_shift = -1;
> -
> - if (online_type == MMOP_ONLINE_MOVABLE &&
> - zone_idx(zone) == ZONE_MOVABLE - 1)
> - zone_shift = 1;
> + if (online_type == MMOP_ONLINE_KERNEL)
> + zone_shift = zone_can_shift(pfn, nr_pages, ZONE_NORMAL);
> + else if (online_type == MMOP_ONLINE_MOVABLE)
> + zone_shift = zone_can_shift(pfn, nr_pages, ZONE_MOVABLE);
>  
>   zone = move_pfn_range(zone_shift, pfn, pfn + nr_pages);
>   if (!zone)
> -- 
> 1.8.3.1
> 
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majord...@kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: mailto:"d...@kvack.org;> em...@kvack.org 


Re: [PATCH 2/3] memory-hotplug: more general validation of zone during online

2016-05-13 Thread Yasuaki Ishimatsu

On Mon,  9 May 2016 12:53:38 -0500
Reza Arbab  wrote:

> When memory is onlined, we are only able to rezone from ZONE_MOVABLE to
> ZONE_KERNEL, or from (ZONE_MOVABLE - 1) to ZONE_MOVABLE.
> 
> To be more flexible, use the following criteria instead; to online memory
> from zone X into zone Y,
> 
> * Any zones between X and Y must be unused.
> * If X is lower than Y, the onlined memory must lie at the end of X.
> * If X is higher than Y, the onlined memory must lie at the start of X.
> 
> Add zone_can_shift() to make this determination.
> 
> Signed-off-by: Reza Arbab 
> ---

Looks good to me.

Reviewd-by: Yasuaki Ishimatsu 

Thanks,
Yasuaki Ishimatsu

>  include/linux/memory_hotplug.h |  2 ++
>  mm/memory_hotplug.c| 42 
> +++---
>  2 files changed, 37 insertions(+), 7 deletions(-)
> 
> diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
> index adbef58..7bff0f9 100644
> --- a/include/linux/memory_hotplug.h
> +++ b/include/linux/memory_hotplug.h
> @@ -284,5 +284,7 @@ extern void sparse_remove_one_section(struct zone *zone, 
> struct mem_section *ms,
>   unsigned long map_offset);
>  extern struct page *sparse_decode_mem_map(unsigned long coded_mem_map,
> unsigned long pnum);
> +extern int zone_can_shift(unsigned long pfn, unsigned long nr_pages,
> +   enum zone_type target);
>  
>  #endif /* __LINUX_MEMORY_HOTPLUG_H */
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index 6b4b005..b63cc28 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -1032,6 +1032,37 @@ static void node_states_set_node(int node, struct 
> memory_notify *arg)
>   node_set_state(node, N_MEMORY);
>  }
>  
> +int zone_can_shift(unsigned long pfn, unsigned long nr_pages,
> +enum zone_type target)
> +{
> + struct zone *zone = page_zone(pfn_to_page(pfn));
> + enum zone_type idx = zone_idx(zone);
> + int i;
> +
> + if (idx < target) {
> + /* pages must be at end of current zone */
> + if (pfn + nr_pages != zone_end_pfn(zone))
> + return 0;
> +
> + /* no zones in use between current zone and target */
> + for (i = idx + 1; i < target; i++)
> + if (zone_is_initialized(zone - idx + i))
> + return 0;
> + }
> +
> + if (target < idx) {
> + /* pages must be at beginning of current zone */
> + if (pfn != zone->zone_start_pfn)
> + return 0;
> +
> + /* no zones in use between current zone and target */
> + for (i = target + 1; i < idx; i++)
> + if (zone_is_initialized(zone - idx + i))
> + return 0;
> + }
> +
> + return target - idx;
> +}
>  
>  /* Must be protected by mem_hotplug_begin() */
>  int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int 
> online_type)
> @@ -1057,13 +1088,10 @@ int __ref online_pages(unsigned long pfn, unsigned 
> long nr_pages, int online_typ
>   !can_online_high_movable(zone))
>   return -EINVAL;
>  
> - if (online_type == MMOP_ONLINE_KERNEL &&
> - zone_idx(zone) == ZONE_MOVABLE)
> - zone_shift = -1;
> -
> - if (online_type == MMOP_ONLINE_MOVABLE &&
> - zone_idx(zone) == ZONE_MOVABLE - 1)
> - zone_shift = 1;
> + if (online_type == MMOP_ONLINE_KERNEL)
> + zone_shift = zone_can_shift(pfn, nr_pages, ZONE_NORMAL);
> + else if (online_type == MMOP_ONLINE_MOVABLE)
> + zone_shift = zone_can_shift(pfn, nr_pages, ZONE_MOVABLE);
>  
>   zone = move_pfn_range(zone_shift, pfn, pfn + nr_pages);
>   if (!zone)
> -- 
> 1.8.3.1
> 
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majord...@kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: mailto:"d...@kvack.org;> em...@kvack.org 


Re: [PATCH 2/3] memory-hotplug: more general validation of zone during online

2016-05-13 Thread Yasuaki Ishimatsu

On Wed, 11 May 2016 14:23:26 -0500
Reza Arbab  wrote:

> On Wed, May 11, 2016 at 08:17:41AM -0700, Yasuaki Ishimatsu wrote:
> >On Tue, 10 May 2016 15:39:43 -0500
> >Reza Arbab  wrote:
> >
> >> +  if (idx < target) {
> >> +  /* pages must be at end of current zone */
> >> +  if (pfn + nr_pages != zone_end_pfn(zone))
> >> +  return 0;
> >
> >> +  if (target < idx) {
> >> +  /* pages must be at beginning of current zone */
> >> +  if (pfn != zone->zone_start_pfn)
> >> +  return 0;
> >
> >According your patch, memory address must be continuous for changing zone.
> >So if memory address is uncontinuous as follows, memory address 
> >0x18000-0x1
> >can be changed from ZONE_NORMAL to ZONE_MOVABLE. But memory address 
> >0x8000-0x
> >can not be changed from ZONE_NORMAL to ZONE_MOVABLE since it does not meet
> >above condition.
> >
> >Memory address
> >  0x8000 -  0x
> > 0x18000 - 0x1
> 
> Ah, I see. What do you think of this instead?
> 
> 
> + if (idx < target) {
> + /* must be the last pages present in current zone */
> + for (i = pfn + nr_pages; i < zone_end_pfn(zone); i++)
> + if (pfn_present(i))
> + return 0;
> 
> + if (target < idx) {
> + /* must be the first pages present in current zone */
> + for (i = zone->zone_start_pfn; i < pfn; i++)
> + if (pfn_present(i))
> + return 0;
> 
> -- 

Ahh, sorry. I completely misread your patch. And I understood that
you don't need to change your first patch.

Thank,
Yasuaki Ishimatsu

> Reza Arbab
> 
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majord...@kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: mailto:"d...@kvack.org;> em...@kvack.org 


Re: [PATCH 2/3] memory-hotplug: more general validation of zone during online

2016-05-13 Thread Yasuaki Ishimatsu

On Wed, 11 May 2016 14:23:26 -0500
Reza Arbab  wrote:

> On Wed, May 11, 2016 at 08:17:41AM -0700, Yasuaki Ishimatsu wrote:
> >On Tue, 10 May 2016 15:39:43 -0500
> >Reza Arbab  wrote:
> >
> >> +  if (idx < target) {
> >> +  /* pages must be at end of current zone */
> >> +  if (pfn + nr_pages != zone_end_pfn(zone))
> >> +  return 0;
> >
> >> +  if (target < idx) {
> >> +  /* pages must be at beginning of current zone */
> >> +  if (pfn != zone->zone_start_pfn)
> >> +  return 0;
> >
> >According your patch, memory address must be continuous for changing zone.
> >So if memory address is uncontinuous as follows, memory address 
> >0x18000-0x1
> >can be changed from ZONE_NORMAL to ZONE_MOVABLE. But memory address 
> >0x8000-0x
> >can not be changed from ZONE_NORMAL to ZONE_MOVABLE since it does not meet
> >above condition.
> >
> >Memory address
> >  0x8000 -  0x
> > 0x18000 - 0x1
> 
> Ah, I see. What do you think of this instead?
> 
> 
> + if (idx < target) {
> + /* must be the last pages present in current zone */
> + for (i = pfn + nr_pages; i < zone_end_pfn(zone); i++)
> + if (pfn_present(i))
> + return 0;
> 
> + if (target < idx) {
> + /* must be the first pages present in current zone */
> + for (i = zone->zone_start_pfn; i < pfn; i++)
> + if (pfn_present(i))
> + return 0;
> 
> -- 

Ahh, sorry. I completely misread your patch. And I understood that
you don't need to change your first patch.

Thank,
Yasuaki Ishimatsu

> Reza Arbab
> 
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majord...@kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: mailto:"d...@kvack.org;> em...@kvack.org 


Re: [PATCH 2/3] memory-hotplug: more general validation of zone during online

2016-05-11 Thread Reza Arbab

On Wed, May 11, 2016 at 08:17:41AM -0700, Yasuaki Ishimatsu wrote:

On Tue, 10 May 2016 15:39:43 -0500
Reza Arbab  wrote:


+   if (idx < target) {
+   /* pages must be at end of current zone */
+   if (pfn + nr_pages != zone_end_pfn(zone))
+   return 0;



+   if (target < idx) {
+   /* pages must be at beginning of current zone */
+   if (pfn != zone->zone_start_pfn)
+   return 0;


According your patch, memory address must be continuous for changing zone.
So if memory address is uncontinuous as follows, memory address 
0x18000-0x1
can be changed from ZONE_NORMAL to ZONE_MOVABLE. But memory address 
0x8000-0x
can not be changed from ZONE_NORMAL to ZONE_MOVABLE since it does not meet
above condition.

Memory address
 0x8000 -  0x
0x18000 - 0x1


Ah, I see. What do you think of this instead?


+   if (idx < target) {
+   /* must be the last pages present in current zone */
+   for (i = pfn + nr_pages; i < zone_end_pfn(zone); i++)
+   if (pfn_present(i))
+   return 0;

+   if (target < idx) {
+   /* must be the first pages present in current zone */
+   for (i = zone->zone_start_pfn; i < pfn; i++)
+   if (pfn_present(i))
+   return 0;

--
Reza Arbab



Re: [PATCH 2/3] memory-hotplug: more general validation of zone during online

2016-05-11 Thread Reza Arbab

On Wed, May 11, 2016 at 08:17:41AM -0700, Yasuaki Ishimatsu wrote:

On Tue, 10 May 2016 15:39:43 -0500
Reza Arbab  wrote:


+   if (idx < target) {
+   /* pages must be at end of current zone */
+   if (pfn + nr_pages != zone_end_pfn(zone))
+   return 0;



+   if (target < idx) {
+   /* pages must be at beginning of current zone */
+   if (pfn != zone->zone_start_pfn)
+   return 0;


According your patch, memory address must be continuous for changing zone.
So if memory address is uncontinuous as follows, memory address 
0x18000-0x1
can be changed from ZONE_NORMAL to ZONE_MOVABLE. But memory address 
0x8000-0x
can not be changed from ZONE_NORMAL to ZONE_MOVABLE since it does not meet
above condition.

Memory address
 0x8000 -  0x
0x18000 - 0x1


Ah, I see. What do you think of this instead?


+   if (idx < target) {
+   /* must be the last pages present in current zone */
+   for (i = pfn + nr_pages; i < zone_end_pfn(zone); i++)
+   if (pfn_present(i))
+   return 0;

+   if (target < idx) {
+   /* must be the first pages present in current zone */
+   for (i = zone->zone_start_pfn; i < pfn; i++)
+   if (pfn_present(i))
+   return 0;

--
Reza Arbab



Re: [PATCH 2/3] memory-hotplug: more general validation of zone during online

2016-05-11 Thread Yasuaki Ishimatsu

On Tue, 10 May 2016 15:39:43 -0500
Reza Arbab  wrote:

> On Tue, May 10, 2016 at 11:08:56AM -0700, Yasuaki Ishimatsu wrote:
> >On Mon,  9 May 2016 12:53:38 -0500
> >Reza Arbab  wrote:
> >> * If X is lower than Y, the onlined memory must lie at the end of X.
> >> * If X is higher than Y, the onlined memory must lie at the start of X.
> >
> >If memory address has hole, memory address gets uncotinuous. Then memory
> >cannot be changed the zone by above the two conditions. So the conditions
> >shouold be removed.
> 
> I don't understand what you mean by this. Could you give an example?

> +int zone_can_shift(unsigned long pfn, unsigned long nr_pages,
> +enum zone_type target)
> +{

> + if (idx < target) {
> + /* pages must be at end of current zone */
> + if (pfn + nr_pages != zone_end_pfn(zone))
> + return 0;

> + if (target < idx) {
> + /* pages must be at beginning of current zone */
> + if (pfn != zone->zone_start_pfn)
> + return 0;

According your patch, memory address must be continuous for changing zone.
So if memory address is uncontinuous as follows, memory address 
0x18000-0x1
can be changed from ZONE_NORMAL to ZONE_MOVABLE. But memory address 
0x8000-0x
can not be changed from ZONE_NORMAL to ZONE_MOVABLE since it does not meet
above condition.

Memory address
  0x8000 -  0x
 0x18000 - 0x1

Thanks,
Yasuaki Ishimatsu






Re: [PATCH 2/3] memory-hotplug: more general validation of zone during online

2016-05-11 Thread Yasuaki Ishimatsu

On Tue, 10 May 2016 15:39:43 -0500
Reza Arbab  wrote:

> On Tue, May 10, 2016 at 11:08:56AM -0700, Yasuaki Ishimatsu wrote:
> >On Mon,  9 May 2016 12:53:38 -0500
> >Reza Arbab  wrote:
> >> * If X is lower than Y, the onlined memory must lie at the end of X.
> >> * If X is higher than Y, the onlined memory must lie at the start of X.
> >
> >If memory address has hole, memory address gets uncotinuous. Then memory
> >cannot be changed the zone by above the two conditions. So the conditions
> >shouold be removed.
> 
> I don't understand what you mean by this. Could you give an example?

> +int zone_can_shift(unsigned long pfn, unsigned long nr_pages,
> +enum zone_type target)
> +{

> + if (idx < target) {
> + /* pages must be at end of current zone */
> + if (pfn + nr_pages != zone_end_pfn(zone))
> + return 0;

> + if (target < idx) {
> + /* pages must be at beginning of current zone */
> + if (pfn != zone->zone_start_pfn)
> + return 0;

According your patch, memory address must be continuous for changing zone.
So if memory address is uncontinuous as follows, memory address 
0x18000-0x1
can be changed from ZONE_NORMAL to ZONE_MOVABLE. But memory address 
0x8000-0x
can not be changed from ZONE_NORMAL to ZONE_MOVABLE since it does not meet
above condition.

Memory address
  0x8000 -  0x
 0x18000 - 0x1

Thanks,
Yasuaki Ishimatsu






Re: [PATCH 2/3] memory-hotplug: more general validation of zone during online

2016-05-10 Thread Reza Arbab

On Tue, May 10, 2016 at 11:08:56AM -0700, Yasuaki Ishimatsu wrote:

On Mon,  9 May 2016 12:53:38 -0500
Reza Arbab  wrote:

* If X is lower than Y, the onlined memory must lie at the end of X.
* If X is higher than Y, the onlined memory must lie at the start of X.


If memory address has hole, memory address gets uncotinuous. Then memory
cannot be changed the zone by above the two conditions. So the conditions
shouold be removed.


I don't understand what you mean by this. Could you give an example?

--
Reza Arbab



Re: [PATCH 2/3] memory-hotplug: more general validation of zone during online

2016-05-10 Thread Reza Arbab

On Tue, May 10, 2016 at 11:08:56AM -0700, Yasuaki Ishimatsu wrote:

On Mon,  9 May 2016 12:53:38 -0500
Reza Arbab  wrote:

* If X is lower than Y, the onlined memory must lie at the end of X.
* If X is higher than Y, the onlined memory must lie at the start of X.


If memory address has hole, memory address gets uncotinuous. Then memory
cannot be changed the zone by above the two conditions. So the conditions
shouold be removed.


I don't understand what you mean by this. Could you give an example?

--
Reza Arbab



Re: [PATCH 2/3] memory-hotplug: more general validation of zone during online

2016-05-10 Thread Yasuaki Ishimatsu

On Mon,  9 May 2016 12:53:38 -0500
Reza Arbab  wrote:

> When memory is onlined, we are only able to rezone from ZONE_MOVABLE to
> ZONE_KERNEL, or from (ZONE_MOVABLE - 1) to ZONE_MOVABLE.
> 
> To be more flexible, use the following criteria instead; to online memory
> from zone X into zone Y,
> 
> * Any zones between X and Y must be unused.

> * If X is lower than Y, the onlined memory must lie at the end of X.
> * If X is higher than Y, the onlined memory must lie at the start of X.

If memory address has hole, memory address gets uncotinuous. Then memory
cannot be changed the zone by above the two conditions. So the conditions
shouold be removed.

Thanks,
Yasuaki Ishimatsu

> 
> Add zone_can_shift() to make this determination.
> 
> Signed-off-by: Reza Arbab 
> ---
>  include/linux/memory_hotplug.h |  2 ++
>  mm/memory_hotplug.c| 42 
> +++---
>  2 files changed, 37 insertions(+), 7 deletions(-)
> 
> diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
> index adbef58..7bff0f9 100644
> --- a/include/linux/memory_hotplug.h
> +++ b/include/linux/memory_hotplug.h
> @@ -284,5 +284,7 @@ extern void sparse_remove_one_section(struct zone *zone, 
> struct mem_section *ms,
>   unsigned long map_offset);
>  extern struct page *sparse_decode_mem_map(unsigned long coded_mem_map,
> unsigned long pnum);
> +extern int zone_can_shift(unsigned long pfn, unsigned long nr_pages,
> +   enum zone_type target);
>  
>  #endif /* __LINUX_MEMORY_HOTPLUG_H */
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index 6b4b005..b63cc28 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -1032,6 +1032,37 @@ static void node_states_set_node(int node, struct 
> memory_notify *arg)
>   node_set_state(node, N_MEMORY);
>  }
>  
> +int zone_can_shift(unsigned long pfn, unsigned long nr_pages,
> +enum zone_type target)
> +{
> + struct zone *zone = page_zone(pfn_to_page(pfn));
> + enum zone_type idx = zone_idx(zone);
> + int i;
> +
> + if (idx < target) {
> + /* pages must be at end of current zone */
> + if (pfn + nr_pages != zone_end_pfn(zone))
> + return 0;
> +
> + /* no zones in use between current zone and target */
> + for (i = idx + 1; i < target; i++)
> + if (zone_is_initialized(zone - idx + i))
> + return 0;
> + }
> +
> + if (target < idx) {
> + /* pages must be at beginning of current zone */
> + if (pfn != zone->zone_start_pfn)
> + return 0;
> +
> + /* no zones in use between current zone and target */
> + for (i = target + 1; i < idx; i++)
> + if (zone_is_initialized(zone - idx + i))
> + return 0;
> + }
> +
> + return target - idx;
> +}
>  
>  /* Must be protected by mem_hotplug_begin() */
>  int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int 
> online_type)
> @@ -1057,13 +1088,10 @@ int __ref online_pages(unsigned long pfn, unsigned 
> long nr_pages, int online_typ
>   !can_online_high_movable(zone))
>   return -EINVAL;
>  
> - if (online_type == MMOP_ONLINE_KERNEL &&
> - zone_idx(zone) == ZONE_MOVABLE)
> - zone_shift = -1;
> -
> - if (online_type == MMOP_ONLINE_MOVABLE &&
> - zone_idx(zone) == ZONE_MOVABLE - 1)
> - zone_shift = 1;
> + if (online_type == MMOP_ONLINE_KERNEL)
> + zone_shift = zone_can_shift(pfn, nr_pages, ZONE_NORMAL);
> + else if (online_type == MMOP_ONLINE_MOVABLE)
> + zone_shift = zone_can_shift(pfn, nr_pages, ZONE_MOVABLE);
>  
>   zone = move_pfn_range(zone_shift, pfn, pfn + nr_pages);
>   if (!zone)
> -- 
> 1.8.3.1
> 
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majord...@kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: mailto:"d...@kvack.org;> em...@kvack.org 


Re: [PATCH 2/3] memory-hotplug: more general validation of zone during online

2016-05-10 Thread Yasuaki Ishimatsu

On Mon,  9 May 2016 12:53:38 -0500
Reza Arbab  wrote:

> When memory is onlined, we are only able to rezone from ZONE_MOVABLE to
> ZONE_KERNEL, or from (ZONE_MOVABLE - 1) to ZONE_MOVABLE.
> 
> To be more flexible, use the following criteria instead; to online memory
> from zone X into zone Y,
> 
> * Any zones between X and Y must be unused.

> * If X is lower than Y, the onlined memory must lie at the end of X.
> * If X is higher than Y, the onlined memory must lie at the start of X.

If memory address has hole, memory address gets uncotinuous. Then memory
cannot be changed the zone by above the two conditions. So the conditions
shouold be removed.

Thanks,
Yasuaki Ishimatsu

> 
> Add zone_can_shift() to make this determination.
> 
> Signed-off-by: Reza Arbab 
> ---
>  include/linux/memory_hotplug.h |  2 ++
>  mm/memory_hotplug.c| 42 
> +++---
>  2 files changed, 37 insertions(+), 7 deletions(-)
> 
> diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
> index adbef58..7bff0f9 100644
> --- a/include/linux/memory_hotplug.h
> +++ b/include/linux/memory_hotplug.h
> @@ -284,5 +284,7 @@ extern void sparse_remove_one_section(struct zone *zone, 
> struct mem_section *ms,
>   unsigned long map_offset);
>  extern struct page *sparse_decode_mem_map(unsigned long coded_mem_map,
> unsigned long pnum);
> +extern int zone_can_shift(unsigned long pfn, unsigned long nr_pages,
> +   enum zone_type target);
>  
>  #endif /* __LINUX_MEMORY_HOTPLUG_H */
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index 6b4b005..b63cc28 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -1032,6 +1032,37 @@ static void node_states_set_node(int node, struct 
> memory_notify *arg)
>   node_set_state(node, N_MEMORY);
>  }
>  
> +int zone_can_shift(unsigned long pfn, unsigned long nr_pages,
> +enum zone_type target)
> +{
> + struct zone *zone = page_zone(pfn_to_page(pfn));
> + enum zone_type idx = zone_idx(zone);
> + int i;
> +
> + if (idx < target) {
> + /* pages must be at end of current zone */
> + if (pfn + nr_pages != zone_end_pfn(zone))
> + return 0;
> +
> + /* no zones in use between current zone and target */
> + for (i = idx + 1; i < target; i++)
> + if (zone_is_initialized(zone - idx + i))
> + return 0;
> + }
> +
> + if (target < idx) {
> + /* pages must be at beginning of current zone */
> + if (pfn != zone->zone_start_pfn)
> + return 0;
> +
> + /* no zones in use between current zone and target */
> + for (i = target + 1; i < idx; i++)
> + if (zone_is_initialized(zone - idx + i))
> + return 0;
> + }
> +
> + return target - idx;
> +}
>  
>  /* Must be protected by mem_hotplug_begin() */
>  int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int 
> online_type)
> @@ -1057,13 +1088,10 @@ int __ref online_pages(unsigned long pfn, unsigned 
> long nr_pages, int online_typ
>   !can_online_high_movable(zone))
>   return -EINVAL;
>  
> - if (online_type == MMOP_ONLINE_KERNEL &&
> - zone_idx(zone) == ZONE_MOVABLE)
> - zone_shift = -1;
> -
> - if (online_type == MMOP_ONLINE_MOVABLE &&
> - zone_idx(zone) == ZONE_MOVABLE - 1)
> - zone_shift = 1;
> + if (online_type == MMOP_ONLINE_KERNEL)
> + zone_shift = zone_can_shift(pfn, nr_pages, ZONE_NORMAL);
> + else if (online_type == MMOP_ONLINE_MOVABLE)
> + zone_shift = zone_can_shift(pfn, nr_pages, ZONE_MOVABLE);
>  
>   zone = move_pfn_range(zone_shift, pfn, pfn + nr_pages);
>   if (!zone)
> -- 
> 1.8.3.1
> 
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majord...@kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: mailto:"d...@kvack.org;> em...@kvack.org