[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [IA64] fix memory leak when domVTI is created



# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 47a5dfd1bcd6203c5c57fc01fc32c94e332ccbb3
# Parent  4151d83d0db9e6de89a943d0c083c6bf339315bf
[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@xxxxxxxxxxxxx>
---
 xen/arch/ia64/asm-offsets.c   |    1 +
 xen/arch/ia64/xen/dom0_ops.c  |    9 +++++++++
 xen/arch/ia64/xen/domain.c    |   40 +++++++++++++++++++++++++++++-----------
 xen/include/asm-ia64/domain.h |    2 ++
 4 files changed, 41 insertions(+), 11 deletions(-)

diff -r 4151d83d0db9 -r 47a5dfd1bcd6 xen/arch/ia64/asm-offsets.c
--- a/xen/arch/ia64/asm-offsets.c       Thu Aug 03 10:44:23 2006 -0600
+++ b/xen/arch/ia64/asm-offsets.c       Thu Aug 03 11:05:59 2006 -0600
@@ -32,6 +32,7 @@ void foo(void)
        DEFINE(IA64_CPU_SIZE, sizeof (struct cpuinfo_ia64));
        DEFINE(UNW_FRAME_INFO_SIZE, sizeof (struct unw_frame_info));
        DEFINE(SHARED_INFO_SIZE, sizeof (struct shared_info));
+       DEFINE(MAPPED_REGS_T_SIZE, sizeof (mapped_regs_t));
 
        BLANK();
        DEFINE(IA64_MCA_CPU_INIT_STACK_OFFSET, offsetof (struct ia64_mca_cpu, 
init_stack));
diff -r 4151d83d0db9 -r 47a5dfd1bcd6 xen/arch/ia64/xen/dom0_ops.c
--- a/xen/arch/ia64/xen/dom0_ops.c      Thu Aug 03 10:44:23 2006 -0600
+++ b/xen/arch/ia64/xen/dom0_ops.c      Thu Aug 03 11:05:59 2006 -0600
@@ -122,6 +122,15 @@ long arch_do_dom0_op(dom0_op_t *op, XEN_
                     ret = -EINVAL;
                     break;
                 }
+                if (!d->arch.is_vti) {
+                    struct vcpu *v;
+                    for_each_vcpu(d, v) {
+                        BUG_ON(v->arch.privregs == NULL);
+                        free_domheap_pages(virt_to_page(v->arch.privregs),
+                                      get_order_from_shift(XMAPPEDREGS_SHIFT));
+                        relinquish_vcpu_resources(v);
+                    }
+                }
                 d->arch.is_vti = 1;
                 vmx_setup_platform(d);
             }
diff -r 4151d83d0db9 -r 47a5dfd1bcd6 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Thu Aug 03 10:44:23 2006 -0600
+++ b/xen/arch/ia64/xen/domain.c        Thu Aug 03 11:05:59 2006 -0600
@@ -236,6 +236,14 @@ void startup_cpu_idle_loop(void)
        continue_cpu_idle_loop();
 }
 
+/* compile time test for get_order(sizeof(mapped_regs_t)) !=
+ * get_order_from_shift(XMAPPEDREGS_SHIFT))
+ */
+#if !(((1 << (XMAPPEDREGS_SHIFT - 1)) < MAPPED_REGS_T_SIZE) && \
+      (MAPPED_REGS_T_SIZE < (1 << (XMAPPEDREGS_SHIFT + 1))))
+# error "XMAPPEDREGS_SHIFT doesn't match sizeof(mapped_regs_t)."
+#endif
+
 struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id)
 {
        struct vcpu *v;
@@ -261,13 +269,17 @@ struct vcpu *alloc_vcpu_struct(struct do
 
        if (!is_idle_domain(d)) {
            if (!d->arch.is_vti) {
-               /* Create privregs page only if not VTi.  */
-               v->arch.privregs = 
-                   alloc_xenheap_pages(get_order(sizeof(mapped_regs_t)));
+               int order;
+               int i;
+
+               /* Create privregs page only if not VTi. */
+               order = get_order_from_shift(XMAPPEDREGS_SHIFT);
+               v->arch.privregs = alloc_xenheap_pages(order);
                BUG_ON(v->arch.privregs == NULL);
-               memset(v->arch.privregs, 0, PAGE_SIZE);
-               share_xen_page_with_guest(virt_to_page(v->arch.privregs),
-                                         d, XENSHARE_writable);
+               memset(v->arch.privregs, 0, 1 << XMAPPEDREGS_SHIFT);
+               for (i = 0; i < (1 << order); i++)
+                   share_xen_page_with_guest(virt_to_page(v->arch.privregs) +
+                                             i, d, XENSHARE_writable);
            }
 
            v->arch.metaphysical_rr0 = d->arch.metaphysical_rr0;
@@ -295,15 +307,21 @@ struct vcpu *alloc_vcpu_struct(struct do
        return v;
 }
 
+void relinquish_vcpu_resources(struct vcpu *v)
+{
+    if (v->arch.privregs != NULL) {
+        free_xenheap_pages(v->arch.privregs,
+                           get_order_from_shift(XMAPPEDREGS_SHIFT));
+        v->arch.privregs = NULL;
+    }
+}
+
 void free_vcpu_struct(struct vcpu *v)
 {
        if (VMX_DOMAIN(v))
                vmx_relinquish_vcpu_resources(v);
-       else {
-               if (v->arch.privregs != NULL)
-                       free_xenheap_pages(v->arch.privregs,
-                                     get_order_from_shift(XMAPPEDREGS_SHIFT));
-       }
+       else
+               relinquish_vcpu_resources(v);
 
        free_xenheap_pages(v, KERNEL_STACK_SIZE_ORDER);
 }
diff -r 4151d83d0db9 -r 47a5dfd1bcd6 xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h     Thu Aug 03 10:44:23 2006 -0600
+++ b/xen/include/asm-ia64/domain.h     Thu Aug 03 11:05:59 2006 -0600
@@ -37,6 +37,8 @@ p2m_entry_retry(struct p2m_entry* entry)
 }
 
 extern void domain_relinquish_resources(struct domain *);
+struct vcpu;
+extern void relinquish_vcpu_resources(struct vcpu *v);
 
 /* given a current domain metaphysical address, return the physical address */
 extern unsigned long translate_domain_mpaddr(unsigned long mpaddr,

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.