diff mbox series

[v1,5/6] mm/page_alloc: restrict ZONE_MOVABLE optimization in has_unmovable_pages() to memory offlining

Message ID 20200630142639.22770-6-david@redhat.com (mailing list archive)
State New, archived
Headers show
Series mm / virtio-mem: support ZONE_MOVABLE | expand

Commit Message

David Hildenbrand June 30, 2020, 2:26 p.m. UTC
We can already have pages that can be offlined but not allocated in
ZONE_MOVABLE - PageHWPoison pages. While these pages can be skipped when
offlining ("moving them to /dev/null"), we cannot move them when
allocating.

virtio-mem managed memory is similar. The logical memory holes
corresponding to unplug memory ranges can be skipped when offlining,
however, the pages cannot be moved. Currently, virtio-mem special-cases
ZONE_MOVABLE, such that:
- partially plugged memory blocks it added to Linux cannot be onlined to
  ZONE_MOVABLE
- when unplugging memory, it will never consider memory blocks that were
  onlined to ZONE_MOVABLE

We also want to support ZONE_MOVABLE in virtio-mem for both cases. Note
that virtio-mem does not blindly try to unplug random pages within its
managed memory region. It always plugs memory left-to-right and tries to
unplug memory right-to-left - in roughly MAX_ORDER - 1 granularity. In
theory, the movable ZONE part would only shrink when unplugging memory
from ZONE_MOVABLE.

Let's perform the ZONE_MOVABLE optimization only for memory offlining,
such that we reduce the number of false positives from
has_unmovable_pages() in case of alloc_contig_range() on ZONE_MOVABLE.

Note: We currently don't seem to have any user of alloc_contig_range()
that actually uses ZONE_MOVABLE. This change is mostly valuable for the
documentation.

Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
 mm/page_alloc.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

Comments

David Hildenbrand July 27, 2020, 12:23 p.m. UTC | #1
On 30.06.20 16:26, David Hildenbrand wrote:
> We can already have pages that can be offlined but not allocated in
> ZONE_MOVABLE - PageHWPoison pages. While these pages can be skipped when
> offlining ("moving them to /dev/null"), we cannot move them when
> allocating.
> 
> virtio-mem managed memory is similar. The logical memory holes
> corresponding to unplug memory ranges can be skipped when offlining,
> however, the pages cannot be moved. Currently, virtio-mem special-cases
> ZONE_MOVABLE, such that:
> - partially plugged memory blocks it added to Linux cannot be onlined to
>   ZONE_MOVABLE
> - when unplugging memory, it will never consider memory blocks that were
>   onlined to ZONE_MOVABLE
> 
> We also want to support ZONE_MOVABLE in virtio-mem for both cases. Note
> that virtio-mem does not blindly try to unplug random pages within its
> managed memory region. It always plugs memory left-to-right and tries to
> unplug memory right-to-left - in roughly MAX_ORDER - 1 granularity. In
> theory, the movable ZONE part would only shrink when unplugging memory
> from ZONE_MOVABLE.
> 
> Let's perform the ZONE_MOVABLE optimization only for memory offlining,
> such that we reduce the number of false positives from
> has_unmovable_pages() in case of alloc_contig_range() on ZONE_MOVABLE.
> 
> Note: We currently don't seem to have any user of alloc_contig_range()
> that actually uses ZONE_MOVABLE. This change is mostly valuable for the
> documentation.
> 
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Michal Hocko <mhocko@suse.com>
> Cc: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
>  mm/page_alloc.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index bd3ebf08f09b9..45077d74d975d 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -8237,9 +8237,12 @@ struct page *has_unmovable_pages(struct zone *zone, struct page *page,
>  		/*
>  		 * If the zone is movable and we have ruled out all reserved
>  		 * pages then it should be reasonably safe to assume the rest
> -		 * is movable.
> +		 * is movable. As we can have some pages in the movable zone
> +		 * that are only considered movable for memory offlining (esp.,
> +		 * PageHWPoison and PageOffline that will be skipped), we
> +		 * perform this optimization only for memory offlining.
>  		 */
> -		if (zone_idx(zone) == ZONE_MOVABLE)
> +		if ((flags & MEMORY_OFFLINE) && zone_idx(zone) == ZONE_MOVABLE)
>  			continue;
>  
>  		/*
> 

So, as we don't have any alloc_contig_range() users that use
ZONE_MOVABLE for now, and virtio-mem will be the only one for now (which
accounts for 50% of the special cases - PG_offline), I think we might
drop this patch.

Worst think is that if we ever have other alloc_contig_range() users,
that we return "false" from has_unmovable_pages() and fail later when
trying to migrate/isolate all pages. This should, however, only happen
in rare cases (and there are already other cases where we have basically
unmovable data - long-term pinnings).

On the plus side, keeping the ZONE_MOVABLE optimizations here also
allows virtio-mem to better tolerate unstable page flags when trying to
alloc_contig_range().

Thoughts?
diff mbox series

Patch

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index bd3ebf08f09b9..45077d74d975d 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -8237,9 +8237,12 @@  struct page *has_unmovable_pages(struct zone *zone, struct page *page,
 		/*
 		 * If the zone is movable and we have ruled out all reserved
 		 * pages then it should be reasonably safe to assume the rest
-		 * is movable.
+		 * is movable. As we can have some pages in the movable zone
+		 * that are only considered movable for memory offlining (esp.,
+		 * PageHWPoison and PageOffline that will be skipped), we
+		 * perform this optimization only for memory offlining.
 		 */
-		if (zone_idx(zone) == ZONE_MOVABLE)
+		if ((flags & MEMORY_OFFLINE) && zone_idx(zone) == ZONE_MOVABLE)
 			continue;
 
 		/*