]> xenbits.xensource.com Git - xen.git/commitdiff
x86/mm: Take care of domain reference for shared pages
authorAndres Lagar-Cavilla <andres@lagarcavilla.org>
Thu, 5 Apr 2012 10:06:03 +0000 (11:06 +0100)
committerAndres Lagar-Cavilla <andres@lagarcavilla.org>
Thu, 5 Apr 2012 10:06:03 +0000 (11:06 +0100)
Making a page sharable removes it from the previous owner's list. Making it
private adds it. These actions are similar to freeing or allocating a page.
Except that they were not minding the domain reference that is taken/dropped
when the first/last page is allocated/freed.

Without fixing this, a domain might remain zombie when destroyed if all its
pages are shared.

Signed-off-by: Andres Lagar-Cavilla <andres@lagarcavilla.org>
Acked-by: Tim Deegan <tim@xen.org>
Committed-by: Tim Deegan <tim@xen.org>
xen/arch/x86/mm/mem_sharing.c

index c838fd848f92c92b4d7840ec0fdf6bc64ba241bf..11c4ff62e563acf4c35ae28001011511bc3bb954 100644 (file)
@@ -401,6 +401,7 @@ static int page_make_sharable(struct domain *d,
                        struct page_info *page, 
                        int expected_refcnt)
 {
+    int drop_dom_ref;
     spin_lock(&d->page_alloc_lock);
 
     /* Change page type and count atomically */
@@ -430,8 +431,12 @@ static int page_make_sharable(struct domain *d,
 
     page_set_owner(page, dom_cow);
     d->tot_pages--;
+    drop_dom_ref = (d->tot_pages == 0);
     page_list_del(page, &d->page_list);
     spin_unlock(&d->page_alloc_lock);
+
+    if ( drop_dom_ref )
+        put_domain(d);
     return 0;
 }
 
@@ -466,7 +471,8 @@ static int page_make_private(struct domain *d, struct page_info *page)
     ASSERT(page_get_owner(page) == dom_cow);
     page_set_owner(page, d);
 
-    d->tot_pages++;
+    if ( d->tot_pages++ == 0 )
+        get_domain(d);
     page_list_add_tail(page, &d->page_list);
     spin_unlock(&d->page_alloc_lock);