linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] memory-hotplug: improve rezoning capability
@ 2016-05-09 17:53 Reza Arbab
  2016-05-09 17:53 ` [PATCH 1/3] memory-hotplug: add move_pfn_range() Reza Arbab
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Reza Arbab @ 2016-05-09 17:53 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Andrew Morton, Daniel Kiper, Dan Williams,
	Vlastimil Babka, Tang Chen, Joonsoo Kim, David Vrabel,
	Vitaly Kuznetsov, David Rientjes, Andrew Banman, Chen Yucong
  Cc: linux-mm, linux-kernel

While it is currently possible to rezone memory when it is onlined, there are
implicit assumptions about the zones:

* To "online_kernel" a block into ZONE_NORMAL, it must currently
  be in ZONE_MOVABLE.

* To "online_movable" a block into ZONE_MOVABLE, it must currently
  be in (ZONE_MOVABLE - 1).

So on powerpc, where new memory is hotplugged into ZONE_DMA, these operations
do not work.

This patchset replaces the qualifications above with a more general
validation of zone movement.

Reza Arbab (3):
  memory-hotplug: add move_pfn_range()
  memory-hotplug: more general validation of zone during online
  memory-hotplug: use zone_can_shift() for sysfs valid_zones attribute

 drivers/base/memory.c          | 28 ++++++++++-------
 include/linux/memory_hotplug.h |  2 ++
 mm/memory_hotplug.c            | 70 ++++++++++++++++++++++++++++++++++--------
 3 files changed, 77 insertions(+), 23 deletions(-)

-- 
1.8.3.1

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

* [PATCH 1/3] memory-hotplug: add move_pfn_range()
  2016-05-09 17:53 [PATCH 0/3] memory-hotplug: improve rezoning capability Reza Arbab
@ 2016-05-09 17:53 ` Reza Arbab
  2016-05-10 16:47   ` Yasuaki Ishimatsu
  2016-05-09 17:53 ` [PATCH 2/3] memory-hotplug: more general validation of zone during online Reza Arbab
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 14+ messages in thread
From: Reza Arbab @ 2016-05-09 17:53 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Andrew Morton, Daniel Kiper, Dan Williams,
	Vlastimil Babka, Tang Chen, Joonsoo Kim, David Vrabel,
	Vitaly Kuznetsov, David Rientjes, Andrew Banman, Chen Yucong
  Cc: linux-mm, linux-kernel, Reza Arbab

Add move_pfn_range(), a wrapper to call move_pfn_range_left() or
move_pfn_range_right().

No functional change. This will be utilized by a later patch.

Signed-off-by: Reza Arbab <arbab@linux.vnet.ibm.com>
---
 mm/memory_hotplug.c | 38 ++++++++++++++++++++++++++++----------
 1 file changed, 28 insertions(+), 10 deletions(-)

diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index aa34431..6b4b005 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -434,6 +434,25 @@ out_fail:
 	return -1;
 }
 
+static struct zone * __meminit move_pfn_range(int zone_shift,
+		unsigned long start_pfn, unsigned long end_pfn)
+{
+	struct zone *zone = page_zone(pfn_to_page(start_pfn));
+	int ret = 0;
+
+	if (zone_shift < 0)
+		ret = move_pfn_range_left(zone + zone_shift, zone,
+					  start_pfn, end_pfn);
+	else if (zone_shift)
+		ret = move_pfn_range_right(zone, zone + zone_shift,
+					   start_pfn, end_pfn);
+
+	if (ret)
+		return NULL;
+
+	return zone + zone_shift;
+}
+
 static void __meminit grow_pgdat_span(struct pglist_data *pgdat, unsigned long start_pfn,
 				      unsigned long end_pfn)
 {
@@ -1024,6 +1043,7 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_typ
 	int nid;
 	int ret;
 	struct memory_notify arg;
+	int zone_shift = 0;
 
 	/*
 	 * This doesn't need a lock to do pfn_to_page().
@@ -1038,18 +1058,16 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_typ
 		return -EINVAL;
 
 	if (online_type == MMOP_ONLINE_KERNEL &&
-	    zone_idx(zone) == ZONE_MOVABLE) {
-		if (move_pfn_range_left(zone - 1, zone, pfn, pfn + nr_pages))
-			return -EINVAL;
-	}
+	    zone_idx(zone) == ZONE_MOVABLE)
+		zone_shift = -1;
+
 	if (online_type == MMOP_ONLINE_MOVABLE &&
-	    zone_idx(zone) == ZONE_MOVABLE - 1) {
-		if (move_pfn_range_right(zone, zone + 1, pfn, pfn + nr_pages))
-			return -EINVAL;
-	}
+	    zone_idx(zone) == ZONE_MOVABLE - 1)
+		zone_shift = 1;
 
-	/* Previous code may changed the zone of the pfn range */
-	zone = page_zone(pfn_to_page(pfn));
+	zone = move_pfn_range(zone_shift, pfn, pfn + nr_pages);
+	if (!zone)
+		return -EINVAL;
 
 	arg.start_pfn = pfn;
 	arg.nr_pages = nr_pages;
-- 
1.8.3.1

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

* [PATCH 2/3] memory-hotplug: more general validation of zone during online
  2016-05-09 17:53 [PATCH 0/3] memory-hotplug: improve rezoning capability Reza Arbab
  2016-05-09 17:53 ` [PATCH 1/3] memory-hotplug: add move_pfn_range() Reza Arbab
@ 2016-05-09 17:53 ` Reza Arbab
  2016-05-10 18:08   ` Yasuaki Ishimatsu
  2016-05-13 17:26   ` Yasuaki Ishimatsu
  2016-05-09 17:53 ` [PATCH 3/3] memory-hotplug: use zone_can_shift() for sysfs valid_zones attribute Reza Arbab
  2016-05-09 20:11 ` [PATCH 0/3] memory-hotplug: improve rezoning capability Andrew Morton
  3 siblings, 2 replies; 14+ messages in thread
From: Reza Arbab @ 2016-05-09 17:53 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Andrew Morton, Daniel Kiper, Dan Williams,
	Vlastimil Babka, Tang Chen, Joonsoo Kim, David Vrabel,
	Vitaly Kuznetsov, David Rientjes, Andrew Banman, Chen Yucong
  Cc: linux-mm, linux-kernel, Reza Arbab

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 <arbab@linux.vnet.ibm.com>
---
 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

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

* [PATCH 3/3] memory-hotplug: use zone_can_shift() for sysfs valid_zones attribute
  2016-05-09 17:53 [PATCH 0/3] memory-hotplug: improve rezoning capability Reza Arbab
  2016-05-09 17:53 ` [PATCH 1/3] memory-hotplug: add move_pfn_range() Reza Arbab
  2016-05-09 17:53 ` [PATCH 2/3] memory-hotplug: more general validation of zone during online Reza Arbab
@ 2016-05-09 17:53 ` Reza Arbab
  2016-05-13 17:38   ` Yasuaki Ishimatsu
  2016-05-09 20:11 ` [PATCH 0/3] memory-hotplug: improve rezoning capability Andrew Morton
  3 siblings, 1 reply; 14+ messages in thread
From: Reza Arbab @ 2016-05-09 17:53 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Andrew Morton, Daniel Kiper, Dan Williams,
	Vlastimil Babka, Tang Chen, Joonsoo Kim, David Vrabel,
	Vitaly Kuznetsov, David Rientjes, Andrew Banman, Chen Yucong
  Cc: linux-mm, linux-kernel, Reza Arbab

Since zone_can_shift() is being used to validate the target zone during
onlining, it should also be used to determine the content of valid_zones.

Signed-off-by: Reza Arbab <arbab@linux.vnet.ibm.com>
---
 drivers/base/memory.c | 28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 31e9c61..8e385ea 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -389,6 +389,7 @@ static ssize_t show_valid_zones(struct device *dev,
 	unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
 	struct page *first_page;
 	struct zone *zone;
+	int zone_shift = 0;
 
 	start_pfn = section_nr_to_pfn(mem->start_section_nr);
 	end_pfn = start_pfn + nr_pages;
@@ -400,21 +401,26 @@ static ssize_t show_valid_zones(struct device *dev,
 
 	zone = page_zone(first_page);
 
-	if (zone_idx(zone) == ZONE_MOVABLE - 1) {
-		/*The mem block is the last memoryblock of this zone.*/
-		if (end_pfn == zone_end_pfn(zone))
-			return sprintf(buf, "%s %s\n",
-					zone->name, (zone + 1)->name);
+	/* MMOP_ONLINE_KEEP */
+	sprintf(buf, "%s", zone->name);
+
+	/* MMOP_ONLINE_KERNEL */
+	zone_shift = zone_can_shift(start_pfn, nr_pages, ZONE_NORMAL);
+	if (zone_shift) {
+		strcat(buf, " ");
+		strcat(buf, (zone + zone_shift)->name);
 	}
 
-	if (zone_idx(zone) == ZONE_MOVABLE) {
-		/*The mem block is the first memoryblock of ZONE_MOVABLE.*/
-		if (start_pfn == zone->zone_start_pfn)
-			return sprintf(buf, "%s %s\n",
-					zone->name, (zone - 1)->name);
+	/* MMOP_ONLINE_MOVABLE */
+	zone_shift = zone_can_shift(start_pfn, nr_pages, ZONE_MOVABLE);
+	if (zone_shift) {
+		strcat(buf, " ");
+		strcat(buf, (zone + zone_shift)->name);
 	}
 
-	return sprintf(buf, "%s\n", zone->name);
+	strcat(buf, "\n");
+
+	return strlen(buf);
 }
 static DEVICE_ATTR(valid_zones, 0444, show_valid_zones, NULL);
 #endif
-- 
1.8.3.1

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

* Re: [PATCH 0/3] memory-hotplug: improve rezoning capability
  2016-05-09 17:53 [PATCH 0/3] memory-hotplug: improve rezoning capability Reza Arbab
                   ` (2 preceding siblings ...)
  2016-05-09 17:53 ` [PATCH 3/3] memory-hotplug: use zone_can_shift() for sysfs valid_zones attribute Reza Arbab
@ 2016-05-09 20:11 ` Andrew Morton
  2016-05-09 20:13   ` Andrew Morton
  3 siblings, 1 reply; 14+ messages in thread
From: Andrew Morton @ 2016-05-09 20:11 UTC (permalink / raw)
  To: Reza Arbab
  Cc: Greg Kroah-Hartman, Daniel Kiper, Dan Williams, Vlastimil Babka,
	Tang Chen, Joonsoo Kim, David Vrabel, Vitaly Kuznetsov,
	David Rientjes, Andrew Banman, Chen Yucong, linux-mm,
	linux-kernel, Yasunori Goto, Yasuaki Ishimatsu, Zhang Zhen,
	Shaohua Li

On Mon,  9 May 2016 12:53:36 -0500 Reza Arbab <arbab@linux.vnet.ibm.com> wrote:

> While it is currently possible to rezone memory when it is onlined, there are
> implicit assumptions about the zones:
> 
> * To "online_kernel" a block into ZONE_NORMAL, it must currently
>   be in ZONE_MOVABLE.
> 
> * To "online_movable" a block into ZONE_MOVABLE, it must currently
>   be in (ZONE_MOVABLE - 1).
> 
> So on powerpc, where new memory is hotplugged into ZONE_DMA, these operations
> do not work.
> 
> This patchset replaces the qualifications above with a more general
> validation of zone movement.
> 

The patches look good from a first scan.  It's late for 4.6 so I'll
queue them for 4.7-rc1, unless there are convincing reasons otherwise?

Hopefully the other memory-hotplug developers will be able to find time
to review these.

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

* Re: [PATCH 0/3] memory-hotplug: improve rezoning capability
  2016-05-09 20:11 ` [PATCH 0/3] memory-hotplug: improve rezoning capability Andrew Morton
@ 2016-05-09 20:13   ` Andrew Morton
  0 siblings, 0 replies; 14+ messages in thread
From: Andrew Morton @ 2016-05-09 20:13 UTC (permalink / raw)
  To: Reza Arbab, Greg Kroah-Hartman, Daniel Kiper, Dan Williams,
	Vlastimil Babka, Tang Chen, Joonsoo Kim, David Vrabel,
	Vitaly Kuznetsov, David Rientjes, Andrew Banman, Chen Yucong,
	linux-mm, linux-kernel, Yasunori Goto, Yasuaki Ishimatsu,
	Zhang Zhen, Shaohua Li

On Mon, 9 May 2016 13:11:58 -0700 Andrew Morton <akpm@linux-foundation.org> wrote:

> On Mon,  9 May 2016 12:53:36 -0500 Reza Arbab <arbab@linux.vnet.ibm.com> wrote:
> 
> > While it is currently possible to rezone memory when it is onlined, there are
> > implicit assumptions about the zones:
> > 
> > * To "online_kernel" a block into ZONE_NORMAL, it must currently
> >   be in ZONE_MOVABLE.
> > 
> > * To "online_movable" a block into ZONE_MOVABLE, it must currently
> >   be in (ZONE_MOVABLE - 1).
> > 
> > So on powerpc, where new memory is hotplugged into ZONE_DMA, these operations
> > do not work.
> > 
> > This patchset replaces the qualifications above with a more general
> > validation of zone movement.
> > 
> 
> The patches look good from a first scan.  It's late for 4.6 so I'll
> queue them for 4.7-rc1, unless there are convincing reasons otherwise?

err, make that 4.8-rc1.

> Hopefully the other memory-hotplug developers will be able to find time
> to review these.

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

* Re: [PATCH 1/3] memory-hotplug: add move_pfn_range()
  2016-05-09 17:53 ` [PATCH 1/3] memory-hotplug: add move_pfn_range() Reza Arbab
@ 2016-05-10 16:47   ` Yasuaki Ishimatsu
  0 siblings, 0 replies; 14+ messages in thread
From: Yasuaki Ishimatsu @ 2016-05-10 16:47 UTC (permalink / raw)
  To: Reza Arbab
  Cc: Greg Kroah-Hartman, Andrew Morton, Daniel Kiper, Dan Williams,
	Vlastimil Babka, Tang Chen, Joonsoo Kim, David Vrabel,
	Vitaly Kuznetsov, David Rientjes, Andrew Banman, Chen Yucong,
	linux-mm, linux-kernel


On Mon,  9 May 2016 12:53:37 -0500
Reza Arbab <arbab@linux.vnet.ibm.com> wrote:

> Add move_pfn_range(), a wrapper to call move_pfn_range_left() or
> move_pfn_range_right().
> 
> No functional change. This will be utilized by a later patch.
> 
> Signed-off-by: Reza Arbab <arbab@linux.vnet.ibm.com>

Looks good to me.
Reviewed-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>

Thanks,
Yasuaki Ishimatsu

> ---
>  mm/memory_hotplug.c | 38 ++++++++++++++++++++++++++++----------
>  1 file changed, 28 insertions(+), 10 deletions(-)
> 
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index aa34431..6b4b005 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -434,6 +434,25 @@ out_fail:
>  	return -1;
>  }
>  
> +static struct zone * __meminit move_pfn_range(int zone_shift,
> +		unsigned long start_pfn, unsigned long end_pfn)
> +{
> +	struct zone *zone = page_zone(pfn_to_page(start_pfn));
> +	int ret = 0;
> +
> +	if (zone_shift < 0)
> +		ret = move_pfn_range_left(zone + zone_shift, zone,
> +					  start_pfn, end_pfn);
> +	else if (zone_shift)
> +		ret = move_pfn_range_right(zone, zone + zone_shift,
> +					   start_pfn, end_pfn);
> +
> +	if (ret)
> +		return NULL;
> +
> +	return zone + zone_shift;
> +}
> +
>  static void __meminit grow_pgdat_span(struct pglist_data *pgdat, unsigned long start_pfn,
>  				      unsigned long end_pfn)
>  {
> @@ -1024,6 +1043,7 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_typ
>  	int nid;
>  	int ret;
>  	struct memory_notify arg;
> +	int zone_shift = 0;
>  
>  	/*
>  	 * This doesn't need a lock to do pfn_to_page().
> @@ -1038,18 +1058,16 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_typ
>  		return -EINVAL;
>  
>  	if (online_type == MMOP_ONLINE_KERNEL &&
> -	    zone_idx(zone) == ZONE_MOVABLE) {
> -		if (move_pfn_range_left(zone - 1, zone, pfn, pfn + nr_pages))
> -			return -EINVAL;
> -	}
> +	    zone_idx(zone) == ZONE_MOVABLE)
> +		zone_shift = -1;
> +
>  	if (online_type == MMOP_ONLINE_MOVABLE &&
> -	    zone_idx(zone) == ZONE_MOVABLE - 1) {
> -		if (move_pfn_range_right(zone, zone + 1, pfn, pfn + nr_pages))
> -			return -EINVAL;
> -	}
> +	    zone_idx(zone) == ZONE_MOVABLE - 1)
> +		zone_shift = 1;
>  
> -	/* Previous code may changed the zone of the pfn range */
> -	zone = page_zone(pfn_to_page(pfn));
> +	zone = move_pfn_range(zone_shift, pfn, pfn + nr_pages);
> +	if (!zone)
> +		return -EINVAL;
>  
>  	arg.start_pfn = pfn;
>  	arg.nr_pages = nr_pages;
> -- 
> 1.8.3.1
> 
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majordomo@kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 2/3] memory-hotplug: more general validation of zone during online
  2016-05-09 17:53 ` [PATCH 2/3] memory-hotplug: more general validation of zone during online Reza Arbab
@ 2016-05-10 18:08   ` Yasuaki Ishimatsu
  2016-05-10 20:39     ` Reza Arbab
  2016-05-13 17:26   ` Yasuaki Ishimatsu
  1 sibling, 1 reply; 14+ messages in thread
From: Yasuaki Ishimatsu @ 2016-05-10 18:08 UTC (permalink / raw)
  To: Reza Arbab
  Cc: Greg Kroah-Hartman, Andrew Morton, Daniel Kiper, Dan Williams,
	Vlastimil Babka, Tang Chen, Joonsoo Kim, David Vrabel,
	Vitaly Kuznetsov, David Rientjes, Andrew Banman, Chen Yucong,
	linux-mm, linux-kernel, Yasuaki Ishimatsu


On Mon,  9 May 2016 12:53:38 -0500
Reza Arbab <arbab@linux.vnet.ibm.com> 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 <arbab@linux.vnet.ibm.com>
> ---
>  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 majordomo@kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 2/3] memory-hotplug: more general validation of zone during online
  2016-05-10 18:08   ` Yasuaki Ishimatsu
@ 2016-05-10 20:39     ` Reza Arbab
  2016-05-11 15:17       ` Yasuaki Ishimatsu
  0 siblings, 1 reply; 14+ messages in thread
From: Reza Arbab @ 2016-05-10 20:39 UTC (permalink / raw)
  To: Yasuaki Ishimatsu
  Cc: Greg Kroah-Hartman, Andrew Morton, Daniel Kiper, Dan Williams,
	Vlastimil Babka, Tang Chen, Joonsoo Kim, David Vrabel,
	Vitaly Kuznetsov, David Rientjes, Andrew Banman, Chen Yucong,
	linux-mm, linux-kernel, Yasuaki Ishimatsu

On Tue, May 10, 2016 at 11:08:56AM -0700, Yasuaki Ishimatsu wrote:
>On Mon,  9 May 2016 12:53:38 -0500
>Reza Arbab <arbab@linux.vnet.ibm.com> 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

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

* Re: [PATCH 2/3] memory-hotplug: more general validation of zone during online
  2016-05-10 20:39     ` Reza Arbab
@ 2016-05-11 15:17       ` Yasuaki Ishimatsu
  2016-05-11 19:23         ` Reza Arbab
  0 siblings, 1 reply; 14+ messages in thread
From: Yasuaki Ishimatsu @ 2016-05-11 15:17 UTC (permalink / raw)
  To: Reza Arbab
  Cc: Greg Kroah-Hartman, Andrew Morton, Daniel Kiper, Dan Williams,
	Vlastimil Babka, Tang Chen, Joonsoo Kim, David Vrabel,
	Vitaly Kuznetsov, David Rientjes, Andrew Banman, Chen Yucong,
	linux-mm, linux-kernel, Yasuaki Ishimatsu


On Tue, 10 May 2016 15:39:43 -0500
Reza Arbab <arbab@linux.vnet.ibm.com> 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 <arbab@linux.vnet.ibm.com> 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)
> +{
<snip>
> +	if (idx < target) {
> +		/* pages must be at end of current zone */
> +		if (pfn + nr_pages != zone_end_pfn(zone))
> +			return 0;
<snip>
> +	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 0x180000000-0x1FFFFFFFF
can be changed from ZONE_NORMAL to ZONE_MOVABLE. But memory address 0x80000000-0xFFFFFFFF
can not be changed from ZONE_NORMAL to ZONE_MOVABLE since it does not meet
above condition.

Memory address
  0x80000000 -  0xFFFFFFFF
 0x180000000 - 0x1FFFFFFFF

Thanks,
Yasuaki Ishimatsu

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

* Re: [PATCH 2/3] memory-hotplug: more general validation of zone during online
  2016-05-11 15:17       ` Yasuaki Ishimatsu
@ 2016-05-11 19:23         ` Reza Arbab
  2016-05-13 17:24           ` Yasuaki Ishimatsu
  0 siblings, 1 reply; 14+ messages in thread
From: Reza Arbab @ 2016-05-11 19:23 UTC (permalink / raw)
  To: Yasuaki Ishimatsu
  Cc: Greg Kroah-Hartman, Andrew Morton, Daniel Kiper, Dan Williams,
	Vlastimil Babka, Tang Chen, Joonsoo Kim, David Vrabel,
	Vitaly Kuznetsov, David Rientjes, Andrew Banman, Chen Yucong,
	linux-mm, linux-kernel, Yasuaki Ishimatsu

On Wed, May 11, 2016 at 08:17:41AM -0700, Yasuaki Ishimatsu wrote:
>On Tue, 10 May 2016 15:39:43 -0500
>Reza Arbab <arbab@linux.vnet.ibm.com> wrote:
><snip>
>> +	if (idx < target) {
>> +		/* pages must be at end of current zone */
>> +		if (pfn + nr_pages != zone_end_pfn(zone))
>> +			return 0;
><snip>
>> +	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 0x180000000-0x1FFFFFFFF
>can be changed from ZONE_NORMAL to ZONE_MOVABLE. But memory address 0x80000000-0xFFFFFFFF
>can not be changed from ZONE_NORMAL to ZONE_MOVABLE since it does not meet
>above condition.
>
>Memory address
>  0x80000000 -  0xFFFFFFFF
> 0x180000000 - 0x1FFFFFFFF

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

<snip>
+	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;
<snip>
+	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

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

* Re: [PATCH 2/3] memory-hotplug: more general validation of zone during online
  2016-05-11 19:23         ` Reza Arbab
@ 2016-05-13 17:24           ` Yasuaki Ishimatsu
  0 siblings, 0 replies; 14+ messages in thread
From: Yasuaki Ishimatsu @ 2016-05-13 17:24 UTC (permalink / raw)
  To: Reza Arbab
  Cc: Greg Kroah-Hartman, Andrew Morton, Daniel Kiper, Dan Williams,
	Vlastimil Babka, Tang Chen, Joonsoo Kim, David Vrabel,
	Vitaly Kuznetsov, David Rientjes, Andrew Banman, Chen Yucong,
	linux-mm, linux-kernel, Yasuaki Ishimatsu


On Wed, 11 May 2016 14:23:26 -0500
Reza Arbab <arbab@linux.vnet.ibm.com> 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 <arbab@linux.vnet.ibm.com> wrote:
> ><snip>
> >> +	if (idx < target) {
> >> +		/* pages must be at end of current zone */
> >> +		if (pfn + nr_pages != zone_end_pfn(zone))
> >> +			return 0;
> ><snip>
> >> +	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 0x180000000-0x1FFFFFFFF
> >can be changed from ZONE_NORMAL to ZONE_MOVABLE. But memory address 0x80000000-0xFFFFFFFF
> >can not be changed from ZONE_NORMAL to ZONE_MOVABLE since it does not meet
> >above condition.
> >
> >Memory address
> >  0x80000000 -  0xFFFFFFFF
> > 0x180000000 - 0x1FFFFFFFF
> 
> Ah, I see. What do you think of this instead?
> 
> <snip>
> +	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;
> <snip>
> +	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 majordomo@kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 2/3] memory-hotplug: more general validation of zone during online
  2016-05-09 17:53 ` [PATCH 2/3] memory-hotplug: more general validation of zone during online Reza Arbab
  2016-05-10 18:08   ` Yasuaki Ishimatsu
@ 2016-05-13 17:26   ` Yasuaki Ishimatsu
  1 sibling, 0 replies; 14+ messages in thread
From: Yasuaki Ishimatsu @ 2016-05-13 17:26 UTC (permalink / raw)
  To: Reza Arbab
  Cc: Greg Kroah-Hartman, Andrew Morton, Daniel Kiper, Dan Williams,
	Vlastimil Babka, Tang Chen, Joonsoo Kim, David Vrabel,
	Vitaly Kuznetsov, David Rientjes, Andrew Banman, Chen Yucong,
	linux-mm, linux-kernel


On Mon,  9 May 2016 12:53:38 -0500
Reza Arbab <arbab@linux.vnet.ibm.com> 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 <arbab@linux.vnet.ibm.com>
> ---

Looks good to me.

Reviewd-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>

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 majordomo@kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 3/3] memory-hotplug: use zone_can_shift() for sysfs valid_zones attribute
  2016-05-09 17:53 ` [PATCH 3/3] memory-hotplug: use zone_can_shift() for sysfs valid_zones attribute Reza Arbab
@ 2016-05-13 17:38   ` Yasuaki Ishimatsu
  0 siblings, 0 replies; 14+ messages in thread
From: Yasuaki Ishimatsu @ 2016-05-13 17:38 UTC (permalink / raw)
  To: Reza Arbab
  Cc: Greg Kroah-Hartman, Andrew Morton, Daniel Kiper, Dan Williams,
	Vlastimil Babka, Tang Chen, Joonsoo Kim, David Vrabel,
	Vitaly Kuznetsov, David Rientjes, Andrew Banman, Chen Yucong,
	linux-mm, linux-kernel


On Mon,  9 May 2016 12:53:39 -0500
Reza Arbab <arbab@linux.vnet.ibm.com> wrote:

> Since zone_can_shift() is being used to validate the target zone during
> onlining, it should also be used to determine the content of valid_zones.
> 
> Signed-off-by: Reza Arbab <arbab@linux.vnet.ibm.com>
> ---

Looks good to me.

Reviewd-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>

Thanks,
Yasuaki Ishimatsu

>  drivers/base/memory.c | 28 +++++++++++++++++-----------
>  1 file changed, 17 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/base/memory.c b/drivers/base/memory.c
> index 31e9c61..8e385ea 100644
> --- a/drivers/base/memory.c
> +++ b/drivers/base/memory.c
> @@ -389,6 +389,7 @@ static ssize_t show_valid_zones(struct device *dev,
>  	unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
>  	struct page *first_page;
>  	struct zone *zone;
> +	int zone_shift = 0;
>  
>  	start_pfn = section_nr_to_pfn(mem->start_section_nr);
>  	end_pfn = start_pfn + nr_pages;
> @@ -400,21 +401,26 @@ static ssize_t show_valid_zones(struct device *dev,
>  
>  	zone = page_zone(first_page);
>  
> -	if (zone_idx(zone) == ZONE_MOVABLE - 1) {
> -		/*The mem block is the last memoryblock of this zone.*/
> -		if (end_pfn == zone_end_pfn(zone))
> -			return sprintf(buf, "%s %s\n",
> -					zone->name, (zone + 1)->name);
> +	/* MMOP_ONLINE_KEEP */
> +	sprintf(buf, "%s", zone->name);
> +
> +	/* MMOP_ONLINE_KERNEL */
> +	zone_shift = zone_can_shift(start_pfn, nr_pages, ZONE_NORMAL);
> +	if (zone_shift) {
> +		strcat(buf, " ");
> +		strcat(buf, (zone + zone_shift)->name);
>  	}
>  
> -	if (zone_idx(zone) == ZONE_MOVABLE) {
> -		/*The mem block is the first memoryblock of ZONE_MOVABLE.*/
> -		if (start_pfn == zone->zone_start_pfn)
> -			return sprintf(buf, "%s %s\n",
> -					zone->name, (zone - 1)->name);
> +	/* MMOP_ONLINE_MOVABLE */
> +	zone_shift = zone_can_shift(start_pfn, nr_pages, ZONE_MOVABLE);
> +	if (zone_shift) {
> +		strcat(buf, " ");
> +		strcat(buf, (zone + zone_shift)->name);
>  	}
>  
> -	return sprintf(buf, "%s\n", zone->name);
> +	strcat(buf, "\n");
> +
> +	return strlen(buf);
>  }
>  static DEVICE_ATTR(valid_zones, 0444, show_valid_zones, NULL);
>  #endif
> -- 
> 1.8.3.1
> 
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majordomo@kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

end of thread, other threads:[~2016-05-13 17:38 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-09 17:53 [PATCH 0/3] memory-hotplug: improve rezoning capability Reza Arbab
2016-05-09 17:53 ` [PATCH 1/3] memory-hotplug: add move_pfn_range() Reza Arbab
2016-05-10 16:47   ` Yasuaki Ishimatsu
2016-05-09 17:53 ` [PATCH 2/3] memory-hotplug: more general validation of zone during online Reza Arbab
2016-05-10 18:08   ` Yasuaki Ishimatsu
2016-05-10 20:39     ` Reza Arbab
2016-05-11 15:17       ` Yasuaki Ishimatsu
2016-05-11 19:23         ` Reza Arbab
2016-05-13 17:24           ` Yasuaki Ishimatsu
2016-05-13 17:26   ` Yasuaki Ishimatsu
2016-05-09 17:53 ` [PATCH 3/3] memory-hotplug: use zone_can_shift() for sysfs valid_zones attribute Reza Arbab
2016-05-13 17:38   ` Yasuaki Ishimatsu
2016-05-09 20:11 ` [PATCH 0/3] memory-hotplug: improve rezoning capability Andrew Morton
2016-05-09 20:13   ` Andrew Morton

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).