Commit 7cf3b79e authored by Vitaly Kuznetsov's avatar Vitaly Kuznetsov Committed by Greg Kroah-Hartman

Drivers: hv: balloon: keep track of where ha_region starts

Windows 2012 (non-R2) does not specify hot add region in hot add requests
and the logic in hot_add_req() is trying to find a 128Mb-aligned region
covering the request. It may also happen that host's requests are not 128Mb
aligned and the created ha_region will start before the first specified
PFN. We can't online these non-present pages but we don't remember the real
start of the region.

This is a regression introduced by the commit 5abbbb75 ("Drivers: hv:
hv_balloon: don't lose memory when onlining order is not natural"). While
the idea of keeping the 'moving window' was wrong (as there is no guarantee
that hot add requests come ordered) we should still keep track of
covered_start_pfn. This is not a revert, the logic is different.
Signed-off-by: default avatarVitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: default avatarK. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 26840437
...@@ -430,13 +430,14 @@ struct dm_info_msg { ...@@ -430,13 +430,14 @@ struct dm_info_msg {
* currently hot added. We hot add in multiples of 128M * currently hot added. We hot add in multiples of 128M
* chunks; it is possible that we may not be able to bring * chunks; it is possible that we may not be able to bring
* online all the pages in the region. The range * online all the pages in the region. The range
* covered_end_pfn defines the pages that can * covered_start_pfn:covered_end_pfn defines the pages that can
* be brough online. * be brough online.
*/ */
struct hv_hotadd_state { struct hv_hotadd_state {
struct list_head list; struct list_head list;
unsigned long start_pfn; unsigned long start_pfn;
unsigned long covered_start_pfn;
unsigned long covered_end_pfn; unsigned long covered_end_pfn;
unsigned long ha_end_pfn; unsigned long ha_end_pfn;
unsigned long end_pfn; unsigned long end_pfn;
...@@ -682,7 +683,8 @@ static void hv_online_page(struct page *pg) ...@@ -682,7 +683,8 @@ static void hv_online_page(struct page *pg)
list_for_each(cur, &dm_device.ha_region_list) { list_for_each(cur, &dm_device.ha_region_list) {
has = list_entry(cur, struct hv_hotadd_state, list); has = list_entry(cur, struct hv_hotadd_state, list);
cur_start_pgp = (unsigned long)pfn_to_page(has->start_pfn); cur_start_pgp = (unsigned long)
pfn_to_page(has->covered_start_pfn);
cur_end_pgp = (unsigned long)pfn_to_page(has->covered_end_pfn); cur_end_pgp = (unsigned long)pfn_to_page(has->covered_end_pfn);
if (((unsigned long)pg >= cur_start_pgp) && if (((unsigned long)pg >= cur_start_pgp) &&
...@@ -854,6 +856,7 @@ static unsigned long process_hot_add(unsigned long pg_start, ...@@ -854,6 +856,7 @@ static unsigned long process_hot_add(unsigned long pg_start,
list_add_tail(&ha_region->list, &dm_device.ha_region_list); list_add_tail(&ha_region->list, &dm_device.ha_region_list);
ha_region->start_pfn = rg_start; ha_region->start_pfn = rg_start;
ha_region->ha_end_pfn = rg_start; ha_region->ha_end_pfn = rg_start;
ha_region->covered_start_pfn = pg_start;
ha_region->covered_end_pfn = pg_start; ha_region->covered_end_pfn = pg_start;
ha_region->end_pfn = rg_start + rg_size; ha_region->end_pfn = rg_start + rg_size;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment