diff options
author | Juergen Gross <jgross@suse.com> | 2017-10-26 05:50:56 -0400 |
---|---|---|
committer | Boris Ostrovsky <boris.ostrovsky@oracle.com> | 2017-10-26 08:11:44 -0400 |
commit | 5266b8e4445cc836c46689d80a9ff539fa3bfbda (patch) | |
tree | be037f49bc59adf3a470d8807f34be4f3a4bbfc0 | |
parent | 298d275d4d9bea3524ff4bc76678c140611d8a8d (diff) |
xen: fix booting ballooned down hvm guest
Commit 96edd61dcf44362d3ef0bed1a5361e0ac7886a63 ("xen/balloon: don't
online new memory initially") introduced a regression when booting a
HVM domain with memory less than mem-max: instead of ballooning down
immediately the system would try to use the memory up to mem-max
resulting in Xen crashing the domain.
For HVM domains the current size will be reflected in Xenstore node
memory/static-max instead of memory/target.
Additionally we have to trigger the ballooning process at once.
Cc: <stable@vger.kernel.org> # 4.13
Fixes: 96edd61dcf44362d3ef0bed1a5361e0ac7886a63 ("xen/balloon: don't
online new memory initially")
Reported-by: Simon Gaiser <hw42@ipsumj.de>
Suggested-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
-rw-r--r-- | drivers/xen/xen-balloon.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/xen/xen-balloon.c b/drivers/xen/xen-balloon.c index e89136ab851e..b437fccd4e62 100644 --- a/drivers/xen/xen-balloon.c +++ b/drivers/xen/xen-balloon.c | |||
@@ -57,7 +57,7 @@ static int register_balloon(struct device *dev); | |||
57 | static void watch_target(struct xenbus_watch *watch, | 57 | static void watch_target(struct xenbus_watch *watch, |
58 | const char *path, const char *token) | 58 | const char *path, const char *token) |
59 | { | 59 | { |
60 | unsigned long long new_target; | 60 | unsigned long long new_target, static_max; |
61 | int err; | 61 | int err; |
62 | static bool watch_fired; | 62 | static bool watch_fired; |
63 | static long target_diff; | 63 | static long target_diff; |
@@ -72,13 +72,20 @@ static void watch_target(struct xenbus_watch *watch, | |||
72 | * pages. PAGE_SHIFT converts bytes to pages, hence PAGE_SHIFT - 10. | 72 | * pages. PAGE_SHIFT converts bytes to pages, hence PAGE_SHIFT - 10. |
73 | */ | 73 | */ |
74 | new_target >>= PAGE_SHIFT - 10; | 74 | new_target >>= PAGE_SHIFT - 10; |
75 | if (watch_fired) { | 75 | |
76 | balloon_set_new_target(new_target - target_diff); | 76 | if (!watch_fired) { |
77 | return; | 77 | watch_fired = true; |
78 | err = xenbus_scanf(XBT_NIL, "memory", "static-max", "%llu", | ||
79 | &static_max); | ||
80 | if (err != 1) | ||
81 | static_max = new_target; | ||
82 | else | ||
83 | static_max >>= PAGE_SHIFT - 10; | ||
84 | target_diff = xen_pv_domain() ? 0 | ||
85 | : static_max - balloon_stats.target_pages; | ||
78 | } | 86 | } |
79 | 87 | ||
80 | watch_fired = true; | 88 | balloon_set_new_target(new_target - target_diff); |
81 | target_diff = new_target - balloon_stats.target_pages; | ||
82 | } | 89 | } |
83 | static struct xenbus_watch target_watch = { | 90 | static struct xenbus_watch target_watch = { |
84 | .node = "memory/target", | 91 | .node = "memory/target", |