debuggers.hg
changeset 11064:47a5dfd1bcd6
[IA64] fix memory leak when domVTI is created
privregs clean up.
memory leak occures when VT-i domain is created.
When domain is created, xend sets max vcpu before domain setup.
So alloc_vcpu_struct() think the domain is normal domU, not domVTI.
And next xend set the domain as domVTI. so the memory is allocated for
domU won't be freed.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
privregs clean up.
memory leak occures when VT-i domain is created.
When domain is created, xend sets max vcpu before domain setup.
So alloc_vcpu_struct() think the domain is normal domU, not domVTI.
And next xend set the domain as domVTI. so the memory is allocated for
domU won't be freed.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author | awilliam@xenbuild.aw |
---|---|
date | Thu Aug 03 11:05:59 2006 -0600 (2006-08-03) |
parents | 4151d83d0db9 |
children | 147144f9ec51 |
files | xen/arch/ia64/asm-offsets.c xen/arch/ia64/xen/dom0_ops.c xen/arch/ia64/xen/domain.c xen/include/asm-ia64/domain.h |
line diff
1.1 --- a/xen/arch/ia64/asm-offsets.c Thu Aug 03 10:44:23 2006 -0600 1.2 +++ b/xen/arch/ia64/asm-offsets.c Thu Aug 03 11:05:59 2006 -0600 1.3 @@ -32,6 +32,7 @@ void foo(void) 1.4 DEFINE(IA64_CPU_SIZE, sizeof (struct cpuinfo_ia64)); 1.5 DEFINE(UNW_FRAME_INFO_SIZE, sizeof (struct unw_frame_info)); 1.6 DEFINE(SHARED_INFO_SIZE, sizeof (struct shared_info)); 1.7 + DEFINE(MAPPED_REGS_T_SIZE, sizeof (mapped_regs_t)); 1.8 1.9 BLANK(); 1.10 DEFINE(IA64_MCA_CPU_INIT_STACK_OFFSET, offsetof (struct ia64_mca_cpu, init_stack));
2.1 --- a/xen/arch/ia64/xen/dom0_ops.c Thu Aug 03 10:44:23 2006 -0600 2.2 +++ b/xen/arch/ia64/xen/dom0_ops.c Thu Aug 03 11:05:59 2006 -0600 2.3 @@ -122,6 +122,15 @@ long arch_do_dom0_op(dom0_op_t *op, XEN_ 2.4 ret = -EINVAL; 2.5 break; 2.6 } 2.7 + if (!d->arch.is_vti) { 2.8 + struct vcpu *v; 2.9 + for_each_vcpu(d, v) { 2.10 + BUG_ON(v->arch.privregs == NULL); 2.11 + free_domheap_pages(virt_to_page(v->arch.privregs), 2.12 + get_order_from_shift(XMAPPEDREGS_SHIFT)); 2.13 + relinquish_vcpu_resources(v); 2.14 + } 2.15 + } 2.16 d->arch.is_vti = 1; 2.17 vmx_setup_platform(d); 2.18 }
3.1 --- a/xen/arch/ia64/xen/domain.c Thu Aug 03 10:44:23 2006 -0600 3.2 +++ b/xen/arch/ia64/xen/domain.c Thu Aug 03 11:05:59 2006 -0600 3.3 @@ -236,6 +236,14 @@ void startup_cpu_idle_loop(void) 3.4 continue_cpu_idle_loop(); 3.5 } 3.6 3.7 +/* compile time test for get_order(sizeof(mapped_regs_t)) != 3.8 + * get_order_from_shift(XMAPPEDREGS_SHIFT)) 3.9 + */ 3.10 +#if !(((1 << (XMAPPEDREGS_SHIFT - 1)) < MAPPED_REGS_T_SIZE) && \ 3.11 + (MAPPED_REGS_T_SIZE < (1 << (XMAPPEDREGS_SHIFT + 1)))) 3.12 +# error "XMAPPEDREGS_SHIFT doesn't match sizeof(mapped_regs_t)." 3.13 +#endif 3.14 + 3.15 struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id) 3.16 { 3.17 struct vcpu *v; 3.18 @@ -261,13 +269,17 @@ struct vcpu *alloc_vcpu_struct(struct do 3.19 3.20 if (!is_idle_domain(d)) { 3.21 if (!d->arch.is_vti) { 3.22 - /* Create privregs page only if not VTi. */ 3.23 - v->arch.privregs = 3.24 - alloc_xenheap_pages(get_order(sizeof(mapped_regs_t))); 3.25 + int order; 3.26 + int i; 3.27 + 3.28 + /* Create privregs page only if not VTi. */ 3.29 + order = get_order_from_shift(XMAPPEDREGS_SHIFT); 3.30 + v->arch.privregs = alloc_xenheap_pages(order); 3.31 BUG_ON(v->arch.privregs == NULL); 3.32 - memset(v->arch.privregs, 0, PAGE_SIZE); 3.33 - share_xen_page_with_guest(virt_to_page(v->arch.privregs), 3.34 - d, XENSHARE_writable); 3.35 + memset(v->arch.privregs, 0, 1 << XMAPPEDREGS_SHIFT); 3.36 + for (i = 0; i < (1 << order); i++) 3.37 + share_xen_page_with_guest(virt_to_page(v->arch.privregs) + 3.38 + i, d, XENSHARE_writable); 3.39 } 3.40 3.41 v->arch.metaphysical_rr0 = d->arch.metaphysical_rr0; 3.42 @@ -295,15 +307,21 @@ struct vcpu *alloc_vcpu_struct(struct do 3.43 return v; 3.44 } 3.45 3.46 +void relinquish_vcpu_resources(struct vcpu *v) 3.47 +{ 3.48 + if (v->arch.privregs != NULL) { 3.49 + free_xenheap_pages(v->arch.privregs, 3.50 + get_order_from_shift(XMAPPEDREGS_SHIFT)); 3.51 + v->arch.privregs = NULL; 3.52 + } 3.53 +} 3.54 + 3.55 void free_vcpu_struct(struct vcpu *v) 3.56 { 3.57 if (VMX_DOMAIN(v)) 3.58 vmx_relinquish_vcpu_resources(v); 3.59 - else { 3.60 - if (v->arch.privregs != NULL) 3.61 - free_xenheap_pages(v->arch.privregs, 3.62 - get_order_from_shift(XMAPPEDREGS_SHIFT)); 3.63 - } 3.64 + else 3.65 + relinquish_vcpu_resources(v); 3.66 3.67 free_xenheap_pages(v, KERNEL_STACK_SIZE_ORDER); 3.68 }
4.1 --- a/xen/include/asm-ia64/domain.h Thu Aug 03 10:44:23 2006 -0600 4.2 +++ b/xen/include/asm-ia64/domain.h Thu Aug 03 11:05:59 2006 -0600 4.3 @@ -37,6 +37,8 @@ p2m_entry_retry(struct p2m_entry* entry) 4.4 } 4.5 4.6 extern void domain_relinquish_resources(struct domain *); 4.7 +struct vcpu; 4.8 +extern void relinquish_vcpu_resources(struct vcpu *v); 4.9 4.10 /* given a current domain metaphysical address, return the physical address */ 4.11 extern unsigned long translate_domain_mpaddr(unsigned long mpaddr,