ia64/xen-unstable

changeset 16980:28310fefde60

[IA64] Fix domain refernece counting

Fix the domain refernece counting caused by allocated pages from domheap for
shared page and hyperregister page. Calling share_xen_page_with_guest() with
domain heap page is wrong so that it increments domian->xenpages which is
never decremented. Thus the domian refcount doesn't decrease to 0 so that
destroy_domain() is never called. This patch make the allocation done from
xenheap again.

The other way to fix it is to work around domain->xenheap and the page
refrence count somehow, but it would be very ugly. The right way to do so
is to enhance the xen page allocator to be aware of this kind of page in
addition to xenheap and domheap. But we don't want to touch the common code.
And given that the limitation on xenheap of xen/ia64 is much relaxed,
probably it isn't necessary to be so nervouse not to allocate those pages
from xenheap. If it happend to be necessary to allocate those pages from
domheap, we could address it at that time. For now just allocate them from
xenheap.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Alex Williamson <alex.williamson@hp.com>
date Tue Feb 05 09:23:59 2008 -0700 (2008-02-05)
parents c98276a51ff8
children 700f33cc0297
files xen/arch/ia64/xen/domain.c
line diff
     1.1 --- a/xen/arch/ia64/xen/domain.c	Mon Feb 04 08:38:35 2008 -0700
     1.2 +++ b/xen/arch/ia64/xen/domain.c	Tue Feb 05 09:23:59 2008 -0700
     1.3 @@ -398,7 +398,7 @@ void relinquish_vcpu_resources(struct vc
     1.4  	if (HAS_PERVCPU_VHPT(v->domain))
     1.5  		pervcpu_vhpt_free(v);
     1.6  	if (v->arch.privregs != NULL) {
     1.7 -		free_domheap_pages(virt_to_page(v->arch.privregs),
     1.8 +		free_xenheap_pages(v->arch.privregs,
     1.9  		                   get_order_from_shift(XMAPPEDREGS_SHIFT));
    1.10  		v->arch.privregs = NULL;
    1.11  	}
    1.12 @@ -500,7 +500,6 @@ static void vcpu_share_privregs_with_gue
    1.13  int vcpu_late_initialise(struct vcpu *v)
    1.14  {
    1.15  	struct domain *d = v->domain;
    1.16 -	struct page_info *page;
    1.17  	int rc, order;
    1.18  
    1.19  	if (HAS_PERVCPU_VHPT(d)) {
    1.20 @@ -511,11 +510,9 @@ int vcpu_late_initialise(struct vcpu *v)
    1.21  
    1.22  	/* Create privregs page. */
    1.23  	order = get_order_from_shift(XMAPPEDREGS_SHIFT);
    1.24 -	page = alloc_domheap_pages(NULL, order, 0);
    1.25 -	if (page == NULL)
    1.26 +	v->arch.privregs = alloc_xenheap_pages(order);
    1.27 +	if (v->arch.privregs == NULL)
    1.28  		return -ENOMEM;
    1.29 -	
    1.30 -	v->arch.privregs = page_to_virt(page);
    1.31  	BUG_ON(v->arch.privregs == NULL);
    1.32  	memset(v->arch.privregs, 0, 1 << XMAPPEDREGS_SHIFT);
    1.33  	vcpu_share_privregs_with_guest(v);
    1.34 @@ -562,8 +559,7 @@ integer_param("pervcpu_vhpt", opt_pervcp
    1.35  int arch_domain_create(struct domain *d, unsigned int domcr_flags)
    1.36  {
    1.37  	int i;
    1.38 -	struct page_info *page = NULL;
    1.39 -	
    1.40 +
    1.41  	// the following will eventually need to be negotiated dynamically
    1.42  	d->arch.shared_info_va = DEFAULT_SHAREDINFO_ADDR;
    1.43  	d->arch.breakimm = 0x1000;
    1.44 @@ -582,10 +578,9 @@ int arch_domain_create(struct domain *d,
    1.45  #endif
    1.46  	if (tlb_track_create(d) < 0)
    1.47  		goto fail_nomem1;
    1.48 -	page = alloc_domheap_pages(NULL, get_order_from_shift(XSI_SHIFT), 0);
    1.49 -	if (page == NULL)
    1.50 +	d->shared_info = alloc_xenheap_pages(get_order_from_shift(XSI_SHIFT));
    1.51 +	if (d->shared_info == NULL)
    1.52  		goto fail_nomem;
    1.53 -	d->shared_info = page_to_virt(page);
    1.54  	BUG_ON(d->shared_info == NULL);
    1.55  	memset(d->shared_info, 0, XSI_SIZE);
    1.56  	for (i = 0; i < XSI_SIZE; i += PAGE_SIZE)
    1.57 @@ -628,8 +623,9 @@ fail_nomem:
    1.58  fail_nomem1:
    1.59  	if (d->arch.mm.pgd != NULL)
    1.60  	    pgd_free(d->arch.mm.pgd);
    1.61 -	if (page != NULL)
    1.62 -	    free_domheap_pages(page, get_order_from_shift(XSI_SHIFT));
    1.63 +	if (d->shared_info != NULL)
    1.64 +	    free_xenheap_pages(d->shared_info,
    1.65 +			       get_order_from_shift(XSI_SHIFT));
    1.66  	return -ENOMEM;
    1.67  }
    1.68  
    1.69 @@ -638,7 +634,7 @@ void arch_domain_destroy(struct domain *
    1.70  	mm_final_teardown(d);
    1.71  
    1.72  	if (d->shared_info != NULL)
    1.73 -		free_domheap_pages(virt_to_page(d->shared_info),
    1.74 +		free_xenheap_pages(d->shared_info,
    1.75  				   get_order_from_shift(XSI_SHIFT));
    1.76  
    1.77  	tlb_track_destroy(d);