WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] This patch defines a new PGT type called

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] This patch defines a new PGT type called PGT_shared_page and a new synthetic
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 16 Dec 2009 22:40:50 -0800
Delivery-date: Wed, 16 Dec 2009 22:41:06 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1261031276 0
# Node ID 3a3be3938b2c71d179330b10fcb187db00c837b2
# Parent  9b344d919ee4c54e33d6f14c44a9fa1856aa6b7d
This patch defines a new PGT type called PGT_shared_page and a new synthetic
domain called 'dom_cow'. In order to share a page, the type needs to be changed
to PGT_shared_page and the owner to dom_dow. Only pages with PGT_none, and no
type count are allowed to become sharable. Conversly, sharable pages can only be
made 'private' if type count equals one. page_make_sharable() and
page_make_private() handle these transitions.

Signed-off-by: Grzegorz Milos <Grzegorz.Milos@xxxxxxxxxx>
---
 xen/arch/x86/mm.c        |   98 ++++++++++++++++++++++++++++++++++++++++++++++-
 xen/common/page_alloc.c  |    9 +++-
 xen/include/asm-x86/mm.h |   45 +++++++++++----------
 xen/include/public/xen.h |    4 +
 4 files changed, 134 insertions(+), 22 deletions(-)

diff -r 9b344d919ee4 -r 3a3be3938b2c xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Thu Dec 17 06:27:55 2009 +0000
+++ b/xen/arch/x86/mm.c Thu Dec 17 06:27:56 2009 +0000
@@ -138,7 +138,7 @@ int mem_hotplug = 0;
 int mem_hotplug = 0;
 
 /* Private domain structs for DOMID_XEN and DOMID_IO. */
-struct domain *dom_xen, *dom_io;
+struct domain *dom_xen, *dom_io, *dom_cow;
 
 /* Frame table size in pages. */
 unsigned long max_page;
@@ -250,6 +250,13 @@ void __init arch_init_memory(void)
      */
     dom_io = domain_create(DOMID_IO, DOMCRF_dummy, 0);
     BUG_ON(dom_io == NULL);
+    
+    /*
+     * Initialise our DOMID_IO domain.
+     * This domain owns sharable pages.
+     */
+    dom_cow = domain_create(DOMID_COW, DOMCRF_dummy, 0);
+    BUG_ON(dom_cow == NULL);
 
     /* First 1MB of RAM is historically marked as I/O. */
     for ( i = 0; i < 0x100; i++ )
@@ -3789,6 +3796,95 @@ int steal_page(
     return -1;
 }
 
+int page_make_sharable(struct domain *d, 
+                       struct page_info *page, 
+                       int expected_refcnt)
+{
+    unsigned long x, nx, y;
+
+    /* Acquire ref first, so that the page doesn't dissapear from us */
+    if(!get_page(page, d))
+        return -EINVAL;
+
+    spin_lock(&d->page_alloc_lock);
+
+    /* Change page type and count atomically */
+    y = page->u.inuse.type_info;
+    nx = PGT_shared_page | PGT_validated | 1; 
+    do {
+        x = y;
+        /* We can only change the type if count is zero, and 
+           type is PGT_none */
+        if((x & (PGT_type_mask | PGT_count_mask)) != PGT_none)
+        {
+            put_page(page);
+            spin_unlock(&d->page_alloc_lock);
+            return -EEXIST;
+        }
+        y = cmpxchg(&page->u.inuse.type_info, x, nx);
+    } while(x != y);
+
+    /* Check if the ref count is 2. The first from PGT_allocated, and the 
second
+     * from get_page at the top of this function */
+    if(page->count_info != (PGC_allocated | (2 + expected_refcnt)))
+    {
+        /* Return type count back to zero */
+        put_page_and_type(page);
+        spin_unlock(&d->page_alloc_lock);
+        return -E2BIG;
+    }
+
+    page_set_owner(page, dom_cow);
+    d->tot_pages--;
+    page_list_del(page, &d->page_list);
+    spin_unlock(&d->page_alloc_lock);
+
+    /* NOTE: We are not putting the page back. In effect this function acquires
+     * one ref and type ref for the caller */
+
+    return 0;
+}
+
+int page_make_private(struct domain *d, struct page_info *page)
+{
+    unsigned long x, y;
+
+    if(!get_page(page, dom_cow))
+        return -EINVAL;
+    
+    spin_lock(&d->page_alloc_lock);
+
+    /* Change page type and count atomically */
+    y = page->u.inuse.type_info;
+    do {
+        x = y;
+        /* We can only change the type if count is one */
+        if((x & (PGT_type_mask | PGT_count_mask)) != 
+                (PGT_shared_page | 1))
+        {
+            put_page(page);
+            spin_unlock(&d->page_alloc_lock);
+            return -EEXIST;
+        }
+        y = cmpxchg(&page->u.inuse.type_info, x, PGT_none);
+    } while(x != y);
+
+    /* We dropped type ref above, drop one ref count too */
+    put_page(page);
+
+    /* Change the owner */
+    ASSERT(page_get_owner(page) == dom_cow);
+    page_set_owner(page, d);
+
+    d->tot_pages++;
+    page_list_add_tail(page, &d->page_list);
+    spin_unlock(&d->page_alloc_lock);
+
+    put_page(page);
+
+    return 0;
+}
+
 static int __do_update_va_mapping(
     unsigned long va, u64 val64, unsigned long flags, struct domain *pg_owner)
 {
diff -r 9b344d919ee4 -r 3a3be3938b2c xen/common/page_alloc.c
--- a/xen/common/page_alloc.c   Thu Dec 17 06:27:55 2009 +0000
+++ b/xen/common/page_alloc.c   Thu Dec 17 06:27:56 2009 +0000
@@ -1145,7 +1145,7 @@ void free_domheap_pages(struct page_info
 
         spin_unlock_recursive(&d->page_alloc_lock);
     }
-    else if ( likely(d != NULL) )
+    else if ( likely(d != NULL) && likely(d != dom_cow) )
     {
         /* NB. May recursively lock from relinquish_memory(). */
         spin_lock_recursive(&d->page_alloc_lock);
@@ -1171,6 +1171,13 @@ void free_domheap_pages(struct page_info
                 scrub_one_page(&pg[i]);
 
         free_heap_pages(pg, order);
+    }
+    else if ( unlikely(d == dom_cow) )
+    {
+        ASSERT(order == 0); 
+        scrub_one_page(pg);
+        free_heap_pages(pg, 0);
+        drop_dom_ref = 0;
     }
     else
     {
diff -r 9b344d919ee4 -r 3a3be3938b2c xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h  Thu Dec 17 06:27:55 2009 +0000
+++ b/xen/include/asm-x86/mm.h  Thu Dec 17 06:27:56 2009 +0000
@@ -155,33 +155,34 @@ struct page_info
 #define PG_mask(x, idx) (x ## UL << PG_shift(idx))
 
  /* The following page types are MUTUALLY EXCLUSIVE. */
-#define PGT_none          PG_mask(0, 3) /* no special uses of this page */
-#define PGT_l1_page_table PG_mask(1, 3) /* using as an L1 page table? */
-#define PGT_l2_page_table PG_mask(2, 3) /* using as an L2 page table? */
-#define PGT_l3_page_table PG_mask(3, 3) /* using as an L3 page table? */
-#define PGT_l4_page_table PG_mask(4, 3) /* using as an L4 page table? */
-#define PGT_seg_desc_page PG_mask(5, 3) /* using this page in a GDT/LDT? */
-#define PGT_writable_page PG_mask(7, 3) /* has writable mappings? */
-#define PGT_type_mask     PG_mask(7, 3) /* Bits 29-31. */
+#define PGT_none          PG_mask(0, 4)  /* no special uses of this page   */
+#define PGT_l1_page_table PG_mask(1, 4)  /* using as an L1 page table?     */
+#define PGT_l2_page_table PG_mask(2, 4)  /* using as an L2 page table?     */
+#define PGT_l3_page_table PG_mask(3, 4)  /* using as an L3 page table?     */
+#define PGT_l4_page_table PG_mask(4, 4)  /* using as an L4 page table?     */
+#define PGT_seg_desc_page PG_mask(5, 4)  /* using this page in a GDT/LDT?  */
+#define PGT_writable_page PG_mask(7, 4)  /* has writable mappings?         */
+#define PGT_shared_page   PG_mask(8, 4)  /* CoW sharable page              */
+#define PGT_type_mask     PG_mask(15, 4) /* Bits 28-31 or 60-63.           */
 
  /* Owning guest has pinned this page to its current type? */
-#define _PGT_pinned       PG_shift(4)
-#define PGT_pinned        PG_mask(1, 4)
+#define _PGT_pinned       PG_shift(5)
+#define PGT_pinned        PG_mask(1, 5)
  /* Has this page been validated for use as its current type? */
-#define _PGT_validated    PG_shift(5)
-#define PGT_validated     PG_mask(1, 5)
+#define _PGT_validated    PG_shift(6)
+#define PGT_validated     PG_mask(1, 6)
  /* PAE only: is this an L2 page directory containing Xen-private mappings? */
-#define _PGT_pae_xen_l2   PG_shift(6)
-#define PGT_pae_xen_l2    PG_mask(1, 6)
+#define _PGT_pae_xen_l2   PG_shift(7)
+#define PGT_pae_xen_l2    PG_mask(1, 7)
 /* Has this page been *partially* validated for use as its current type? */
-#define _PGT_partial      PG_shift(7)
-#define PGT_partial       PG_mask(1, 7)
+#define _PGT_partial      PG_shift(8)
+#define PGT_partial       PG_mask(1, 8)
  /* Page is locked? */
-#define _PGT_locked       PG_shift(8)
-#define PGT_locked        PG_mask(1, 8)
+#define _PGT_locked       PG_shift(9)
+#define PGT_locked        PG_mask(1, 9)
 
  /* Count of uses of this frame as its current type. */
-#define PGT_count_width   PG_shift(8)
+#define PGT_count_width   PG_shift(9)
 #define PGT_count_mask    ((1UL<<PGT_count_width)-1)
 
  /* Cleared when the owning guest 'frees' this page. */
@@ -529,6 +530,10 @@ int steal_page(
     struct domain *d, struct page_info *page, unsigned int memflags);
 int donate_page(
     struct domain *d, struct page_info *page, unsigned int memflags);
+int page_make_sharable(struct domain *d, 
+                       struct page_info *page, 
+                       int expected_refcnt);
+int page_make_private(struct domain *d, struct page_info *page);
 
 int map_ldt_shadow_page(unsigned int);
 
@@ -551,6 +556,6 @@ unsigned int domain_clamp_alloc_bitsize(
 
 unsigned long domain_get_maximum_gpfn(struct domain *d);
 
-extern struct domain *dom_xen, *dom_io;        /* for vmcoreinfo */
+extern struct domain *dom_xen, *dom_io, *dom_cow;      /* for vmcoreinfo */
 
 #endif /* __ASM_X86_MM_H__ */
diff -r 9b344d919ee4 -r 3a3be3938b2c xen/include/public/xen.h
--- a/xen/include/public/xen.h  Thu Dec 17 06:27:55 2009 +0000
+++ b/xen/include/public/xen.h  Thu Dec 17 06:27:56 2009 +0000
@@ -366,6 +366,10 @@ typedef uint16_t domid_t;
  */
 #define DOMID_XEN  (0x7FF2U)
 
+/*
+ * DOMID_COW is used as the owner of sharable pages */
+#define DOMID_COW  (0x7FF3U)
+
 /* DOMID_INVALID is used to identity invalid domid */
 #define DOMID_INVALID (0x7FFFU)
 

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] This patch defines a new PGT type called PGT_shared_page and a new synthetic, Xen patchbot-unstable <=