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] shadow: drop guest VRAM write access afte

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] shadow: drop guest VRAM write access after some idleness
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 08 May 2008 11:50:15 -0700
Delivery-date: Thu, 08 May 2008 11:50:35 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
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/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/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 1210248945 -3600
# Node ID 0ac957f9d42e778565e745d7b6dc55bd527c8e90
# Parent  fe625fd796f8de4cf09cba6b7bd0c7e8438e2552
shadow: drop guest VRAM write access after some idleness

If the video RAM has been kept clean for at least 2 seconds, we can
afford taking the time to drop guest write access, which allows us to
save the dirty bit scanning entirely until we get a guest page handle.

From: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/mm/shadow/common.c  |   53 +++++++++++++++++++++++++++++----------
 xen/arch/x86/mm/shadow/multi.c   |   15 ++++++++++-
 xen/arch/x86/mm/shadow/private.h |    1 
 3 files changed, 55 insertions(+), 14 deletions(-)

diff -r fe625fd796f8 -r 0ac957f9d42e xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c   Thu May 08 13:14:27 2008 +0100
+++ b/xen/arch/x86/mm/shadow/common.c   Thu May 08 13:15:45 2008 +0100
@@ -2869,6 +2869,8 @@ int shadow_track_dirty_vram(struct domai
     unsigned long end_pfn = begin_pfn + nr;
     unsigned long dirty_size = (nr + 7) / 8;
     int flush_tlb = 0;
+    unsigned long i;
+    p2m_type_t t;
 
     if (end_pfn < begin_pfn
             || begin_pfn > d->arch.p2m->max_mapped_pfn
@@ -2879,7 +2881,8 @@ int shadow_track_dirty_vram(struct domai
 
     if ( d->dirty_vram && (!nr ||
              ( begin_pfn != d->dirty_vram->begin_pfn
-            || end_pfn   != d->dirty_vram->end_pfn )) ) {
+            || end_pfn   != d->dirty_vram->end_pfn )) )
+    {
         /* Different tracking, tear the previous down. */
         gdprintk(XENLOG_INFO, "stopping tracking VRAM %lx - %lx\n", 
d->dirty_vram->begin_pfn, d->dirty_vram->end_pfn);
         xfree(d->dirty_vram->sl1ma);
@@ -2888,17 +2891,16 @@ int shadow_track_dirty_vram(struct domai
         d->dirty_vram = NULL;
     }
 
-    if ( !nr ) {
+    if ( !nr )
+    {
         rc = 0;
         goto out;
     }
 
     /* This should happen seldomly (Video mode change),
      * no need to be careful. */
-    if ( !d->dirty_vram ) {
-        unsigned long i;
-        p2m_type_t t;
-
+    if ( !d->dirty_vram )
+    {
         /* Just recount from start. */
         for ( i = begin_pfn; i < end_pfn; i++ )
             flush_tlb |= sh_remove_all_mappings(d->vcpu[0], gfn_to_mfn(d, i, 
&t));
@@ -2919,10 +2921,20 @@ int shadow_track_dirty_vram(struct domai
             goto out_sl1ma;
         memset(d->dirty_vram->dirty_bitmap, 0, dirty_size);
 
+        d->dirty_vram->last_dirty = NOW();
+
         /* Tell the caller that this time we could not track dirty bits. */
         rc = -ENODATA;
-    } else {
-        int i;
+    }
+    else if (d->dirty_vram->last_dirty == -1)
+    {
+        /* still completely clean, just copy our empty bitmap */
+        rc = -EFAULT;
+        if ( copy_to_guest(dirty_bitmap, d->dirty_vram->dirty_bitmap, 
dirty_size) == 0 )
+            rc = 0;
+    }
+    else
+    {
 #ifdef __i386__
         unsigned long map_mfn = INVALID_MFN;
         void *map_sl1p = NULL;
@@ -2930,26 +2942,29 @@ int shadow_track_dirty_vram(struct domai
 
         /* Iterate over VRAM to track dirty bits. */
         for ( i = 0; i < nr; i++ ) {
-            p2m_type_t t;
             mfn_t mfn = gfn_to_mfn(d, begin_pfn + i, &t);
             struct page_info *page = mfn_to_page(mfn);
             u32 count_info = page->u.inuse.type_info & PGT_count_mask;
             int dirty = 0;
             paddr_t sl1ma = d->dirty_vram->sl1ma[i];
 
-            switch (count_info) {
+            switch (count_info)
+            {
             case 0:
                 /* No guest reference, nothing to track. */
                 break;
             case 1:
                 /* One guest reference. */
-                if ( sl1ma == INVALID_PADDR ) {
+                if ( sl1ma == INVALID_PADDR )
+                {
                     /* We don't know which sl1e points to this, too bad. */
                     dirty = 1;
                     /* TODO: Heuristics for finding the single mapping of
                      * this gmfn */
                     flush_tlb |= sh_remove_all_mappings(d->vcpu[0], 
gfn_to_mfn(d, begin_pfn + i, &t));
-                } else {
+                }
+                else
+                {
                     /* Hopefully the most common case: only one mapping,
                      * whose dirty bit we can use. */
                     l1_pgentry_t *sl1e;
@@ -2968,7 +2983,8 @@ int shadow_track_dirty_vram(struct domai
                     sl1e = maddr_to_virt(sl1ma);
 #endif
 
-                    if ( l1e_get_flags(*sl1e) & _PAGE_DIRTY ) {
+                    if ( l1e_get_flags(*sl1e) & _PAGE_DIRTY )
+                    {
                         dirty = 1;
                         /* Note: this is atomic, so we may clear a
                          * _PAGE_ACCESSED set by another processor. */
@@ -2985,7 +3001,10 @@ int shadow_track_dirty_vram(struct domai
             }
 
             if ( dirty )
+            {
                 d->dirty_vram->dirty_bitmap[i / 8] |= 1 << (i % 8);
+                d->dirty_vram->last_dirty = NOW();
+            }
         }
 
 #ifdef __i386__
@@ -2996,6 +3015,14 @@ int shadow_track_dirty_vram(struct domai
         rc = -EFAULT;
         if ( copy_to_guest(dirty_bitmap, d->dirty_vram->dirty_bitmap, 
dirty_size) == 0 ) {
             memset(d->dirty_vram->dirty_bitmap, 0, dirty_size);
+            if (d->dirty_vram->last_dirty + SECONDS(2) < NOW())
+            {
+                /* was clean for more than two seconds, try to disable guest
+                 * write access */
+                for ( i = begin_pfn; i < end_pfn; i++ )
+                    flush_tlb |= sh_remove_write_access(d->vcpu[0], 
gfn_to_mfn(d, i, &t), 1, 0);
+                d->dirty_vram->last_dirty = -1;
+            }
             rc = 0;
         }
     }
diff -r fe625fd796f8 -r 0ac957f9d42e xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c    Thu May 08 13:14:27 2008 +0100
+++ b/xen/arch/x86/mm/shadow/multi.c    Thu May 08 13:15:45 2008 +0100
@@ -870,6 +870,17 @@ _sh_propagate(struct vcpu *v,
         }
     }
 
+    if ( unlikely((level == 1) && d->dirty_vram
+            && d->dirty_vram->last_dirty == -1
+            && gfn_x(target_gfn) >= d->dirty_vram->begin_pfn
+            && gfn_x(target_gfn) < d->dirty_vram->end_pfn) )
+    {
+        if ( ft & FETCH_TYPE_WRITE )
+            d->dirty_vram->last_dirty = NOW();
+        else
+            sflags &= ~_PAGE_RW;
+    }
+
     /* Read-only memory */
     if ( p2mt == p2m_ram_ro ) 
         sflags &= ~_PAGE_RW;
@@ -1320,8 +1331,10 @@ static inline void shadow_vram_put_l1e(s
                  * just hope it will remain. */
             }
         }
-        if ( dirty )
+        if ( dirty ) {
             d->dirty_vram->dirty_bitmap[i / 8] |= 1 << (i % 8);
+            d->dirty_vram->last_dirty = NOW();
+        }
     }
 }
 
diff -r fe625fd796f8 -r 0ac957f9d42e xen/arch/x86/mm/shadow/private.h
--- a/xen/arch/x86/mm/shadow/private.h  Thu May 08 13:14:27 2008 +0100
+++ b/xen/arch/x86/mm/shadow/private.h  Thu May 08 13:15:45 2008 +0100
@@ -536,6 +536,7 @@ struct sh_dirty_vram {
     unsigned long end_pfn;
     paddr_t *sl1ma;
     uint8_t *dirty_bitmap;
+    s_time_t last_dirty;
 };
 
 /**************************************************************************/

_______________________________________________
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] shadow: drop guest VRAM write access after some idleness, Xen patchbot-unstable <=