summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Hildenbrand <david@redhat.com>2019-12-16 11:30:58 +0100
committerMichael Ellerman <mpe@ellerman.id.au>2019-12-16 23:15:16 +1100
commite352f576d345e5bf1fb62c8559851448a6c1d9cd (patch)
treecc0c93e9690b6861f48607c1905675ff72ce83a4
parent0601546f23fb70d84b807e73cfe8e789d054c98d (diff)
powerpc/pseries/cmm: fix managed page counts when migrating pages between zones
Commit 63341ab03706 (virtio-balloon: fix managed page counts when migrating pages between zones) fixed a long existing BUG in the virtio-balloon driver when pages would get migrated between zones. I did not try to reproduce on powerpc, but looking at the code, the same should apply to powerpc/cmm ever since it started using the balloon compaction infrastructure (luckily just recently). In case we have to migrate a ballon page to a newpage of another zone, the managed page count of both zones is wrong. Paired with memory offlining (which will adjust the managed page count), we can trigger kernel crashes and all kinds of different symptoms. Fix it by properly adjusting the managed page count when migrating if the zone changed. We'll temporarily modify the totalram page count. If this ever becomes a problem, we can fine tune by providing helpers that don't touch the totalram pages (e.g., adjust_zone_managed_page_count()). Fixes: fe030c9b85e6 ("powerpc/pseries/cmm: Implement balloon compaction") Signed-off-by: David Hildenbrand <david@redhat.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20191216103058.4958-1-david@redhat.com
-rw-r--r--arch/powerpc/platforms/pseries/cmm.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/pseries/cmm.c b/arch/powerpc/platforms/pseries/cmm.c
index 91571841df8a..9dba7e880885 100644
--- a/arch/powerpc/platforms/pseries/cmm.c
+++ b/arch/powerpc/platforms/pseries/cmm.c
@@ -539,6 +539,16 @@ static int cmm_migratepage(struct balloon_dev_info *b_dev_info,
/* balloon page list reference */
get_page(newpage);
+ /*
+ * When we migrate a page to a different zone, we have to fixup the
+ * count of both involved zones as we adjusted the managed page count
+ * when inflating.
+ */
+ if (page_zone(page) != page_zone(newpage)) {
+ adjust_managed_page_count(page, 1);
+ adjust_managed_page_count(newpage, -1);
+ }
+
spin_lock_irqsave(&b_dev_info->pages_lock, flags);
balloon_page_insert(b_dev_info, newpage);
balloon_page_delete(page);