mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
xc: use XENMEM_claim_pages hypercall during guest creation.
We add an extra parameter to the structures passed to the PV routine (arch_setup_meminit) and HVM routine (setup_guest) that determines whether the claim hypercall is to be done. The contents of the 'claim_enabled' is defined as an 'int' in case the hypercall expands in the future with extra flags (for example for per-NUMA allocation). For right now the proper values are: 0 to disable it or 1 to enable it. If the hypervisor does not support this function, the xc_domain_claim_pages and xc_domain_get_outstanding_pages will silently return 0 (and set errno to zero). Signed-off-by: Dan Magenheimer <dan.magenheimer@oracle.com> [v2: Updated per Ian's recommendations] [v3: Added support for out-of-sync hypervisor] Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
This commit is contained in:
1 parent
749bc93f7a
commit
fc67e9dc0c
6 files changed
+70
-4
No files matched your search
@@ -135,6 +135,7 @@ struct xc_dom_image {
|
||||
domid_t guest_domid;
|
||||
int8_t vhpt_size_log2; /* for IA64 */
|
||||
int8_t superpages;
|
||||
int claim_enabled; /* 0 by default, 1 enables it */
|
||||
int shadow_enabled;
|
||||
|
||||
int xen_version;
|
||||
|
||||
@@ -706,6 +706,13 @@ int arch_setup_meminit(struct xc_dom_image *dom)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* try to claim pages for early warning of insufficient memory avail */
|
||||
if ( dom->claim_enabled ) {
|
||||
rc = xc_domain_claim_pages(dom->xch, dom->guest_domid,
|
||||
dom->total_pages);
|
||||
if ( rc )
|
||||
return rc;
|
||||
}
|
||||
/* setup initial p2m */
|
||||
for ( pfn = 0; pfn < dom->total_pages; pfn++ )
|
||||
dom->p2m_host[pfn] = pfn;
|
||||
@@ -722,6 +729,11 @@ int arch_setup_meminit(struct xc_dom_image *dom)
|
||||
dom->xch, dom->guest_domid, allocsz,
|
||||
0, 0, &dom->p2m_host[i]);
|
||||
}
|
||||
|
||||
/* Ensure no unclaimed pages are left unused.
|
||||
* OK to call if hadn't done the earlier claim call. */
|
||||
(void)xc_domain_claim_pages(dom->xch, dom->guest_domid,
|
||||
0 /* cancels the claim */);
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
@@ -775,6 +775,36 @@ int xc_domain_add_to_physmap(xc_interface *xch,
|
||||
return do_memory_op(xch, XENMEM_add_to_physmap, &xatp, sizeof(xatp));
|
||||
}
|
||||
|
||||
int xc_domain_claim_pages(xc_interface *xch,
|
||||
uint32_t domid,
|
||||
unsigned long nr_pages)
|
||||
{
|
||||
int err;
|
||||
struct xen_memory_reservation reservation = {
|
||||
.nr_extents = nr_pages,
|
||||
.extent_order = 0,
|
||||
.mem_flags = 0, /* no flags */
|
||||
.domid = domid
|
||||
};
|
||||
|
||||
set_xen_guest_handle(reservation.extent_start, HYPERCALL_BUFFER_NULL);
|
||||
|
||||
err = do_memory_op(xch, XENMEM_claim_pages, &reservation, sizeof(reservation));
|
||||
/* Ignore it if the hypervisor does not support the call. */
|
||||
if (err == -1 && errno == ENOSYS)
|
||||
err = errno = 0;
|
||||
return err;
|
||||
}
|
||||
unsigned long xc_domain_get_outstanding_pages(xc_interface *xch)
|
||||
{
|
||||
long ret = do_memory_op(xch, XENMEM_get_outstanding_pages, NULL, 0);
|
||||
|
||||
/* Ignore it if the hypervisor does not support the call. */
|
||||
if (ret == -1 && errno == ENOSYS)
|
||||
ret = errno = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xc_domain_populate_physmap(xc_interface *xch,
|
||||
uint32_t domid,
|
||||
unsigned long nr_extents,
|
||||
|
||||
@@ -252,6 +252,7 @@ static int setup_guest(xc_interface *xch,
|
||||
unsigned long stat_normal_pages = 0, stat_2mb_pages = 0,
|
||||
stat_1gb_pages = 0;
|
||||
int pod_mode = 0;
|
||||
int claim_enabled = args->claim_enabled;
|
||||
|
||||
if ( nr_pages > target_pages )
|
||||
pod_mode = XENMEMF_populate_on_demand;
|
||||
@@ -329,6 +330,16 @@ static int setup_guest(xc_interface *xch,
|
||||
xch, dom, 0xa0, 0, pod_mode, &page_array[0x00]);
|
||||
cur_pages = 0xc0;
|
||||
stat_normal_pages = 0xc0;
|
||||
|
||||
/* try to claim pages for early warning of insufficient memory available */
|
||||
if ( claim_enabled ) {
|
||||
rc = xc_domain_claim_pages(xch, dom, nr_pages - cur_pages);
|
||||
if ( rc != 0 )
|
||||
{
|
||||
PERROR("Could not allocate memory for HVM guest as we cannot claim memory!");
|
||||
goto error_out;
|
||||
}
|
||||
}
|
||||
while ( (rc == 0) && (nr_pages > cur_pages) )
|
||||
{
|
||||
/* Clip count to maximum 1GB extent. */
|
||||
@@ -506,12 +517,16 @@ static int setup_guest(xc_interface *xch,
|
||||
munmap(page0, PAGE_SIZE);
|
||||
}
|
||||
|
||||
free(page_array);
|
||||
return 0;
|
||||
|
||||
rc = 0;
|
||||
goto out;
|
||||
error_out:
|
||||
rc = -1;
|
||||
out:
|
||||
/* ensure no unclaimed pages are left unused */
|
||||
xc_domain_claim_pages(xch, dom, 0 /* cancels the claim */);
|
||||
|
||||
free(page_array);
|
||||
return -1;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* xc_hvm_build:
|
||||
|
||||
@@ -1133,6 +1133,12 @@ int xc_domain_populate_physmap_exact(xc_interface *xch,
|
||||
unsigned int mem_flags,
|
||||
xen_pfn_t *extent_start);
|
||||
|
||||
int xc_domain_claim_pages(xc_interface *xch,
|
||||
uint32_t domid,
|
||||
unsigned long nr_pages);
|
||||
|
||||
unsigned long xc_domain_get_outstanding_pages(xc_interface *xch);
|
||||
|
||||
int xc_domain_memory_exchange_pages(xc_interface *xch,
|
||||
int domid,
|
||||
unsigned long nr_in_extents,
|
||||
|
||||
@@ -231,6 +231,8 @@ struct xc_hvm_build_args {
|
||||
|
||||
/* Extra SMBIOS structures passed to HVMLOADER */
|
||||
struct xc_hvm_firmware_module smbios_module;
|
||||
/* Whether to use claim hypercall (1 - enable, 0 - disable). */
|
||||
int claim_enabled;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||