Skip to content

Commit bb7645c

Browse files
jgross1gregkh
authored andcommitted
mm, page_alloc: fix build_zonerefs_node()
commit e553f62 upstream. Since commit 6aa303d ("mm, vmscan: only allocate and reclaim from zones with pages managed by the buddy allocator") only zones with free memory are included in a built zonelist. This is problematic when e.g. all memory of a zone has been ballooned out when zonelists are being rebuilt. The decision whether to rebuild the zonelists when onlining new memory is done based on populated_zone() returning 0 for the zone the memory will be added to. The new zone is added to the zonelists only, if it has free memory pages (managed_zone() returns a non-zero value) after the memory has been onlined. This implies, that onlining memory will always free the added pages to the allocator immediately, but this is not true in all cases: when e.g. running as a Xen guest the onlined new memory will be added only to the ballooned memory list, it will be freed only when the guest is being ballooned up afterwards. Another problem with using managed_zone() for the decision whether a zone is being added to the zonelists is, that a zone with all memory used will in fact be removed from all zonelists in case the zonelists happen to be rebuilt. Use populated_zone() when building a zonelist as it has been done before that commit. There was a report that QubesOS (based on Xen) is hitting this problem. Xen has switched to use the zone device functionality in kernel 5.9 and QubesOS wants to use memory hotplugging for guests in order to be able to start a guest with minimal memory and expand it as needed. This was the report leading to the patch. Link: https://lkml.kernel.org/r/[email protected] Fixes: 6aa303d ("mm, vmscan: only allocate and reclaim from zones with pages managed by the buddy allocator") Signed-off-by: Juergen Gross <[email protected]> Reported-by: Marek Marczykowski-Górecki <[email protected]> Acked-by: Michal Hocko <[email protected]> Acked-by: David Hildenbrand <[email protected]> Cc: Marek Marczykowski-Górecki <[email protected]> Reviewed-by: Wei Yang <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent b6d17c6 commit bb7645c

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

mm/page_alloc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6092,7 +6092,7 @@ static int build_zonerefs_node(pg_data_t *pgdat, struct zoneref *zonerefs)
60926092
do {
60936093
zone_type--;
60946094
zone = pgdat->node_zones + zone_type;
6095-
if (managed_zone(zone)) {
6095+
if (populated_zone(zone)) {
60966096
zoneref_set_zone(zone, &zonerefs[nr_zones++]);
60976097
check_highest_zone(zone_type);
60986098
}

0 commit comments

Comments
 (0)