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

xen-devel

[Top] [All Lists]

[Xen-devel] [PATCH] shadow: drop guest VRAM write access after some idle

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] shadow: drop guest VRAM write access after some idleness
From: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>
Date: Thu, 8 May 2008 12:58:20 +0100
Cc: tim.deegan@xxxxxxxxxxxxx, gianluca.guida@xxxxxxxxxxxxx
Delivery-date: 2008年5月08日 04:58:44 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <20080502140509.GF4819@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Mail-followup-to: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxx, tim.deegan@xxxxxxxxxxxxx, gianluca.guida@xxxxxxxxxxxxx
References: <20080502140509.GF4819@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.12-2006年07月14日
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.
diff -r 3bc6ad3beafc -r 98b06d404e6b xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c Fri May 02 14:59:35 2008 +0100
+++ b/xen/arch/x86/mm/shadow/common.c Thu May 08 12:50:34 2008 +0100
@@ -2871,6 +2871,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
@@ -2881,7 +2883,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);
@@ -2890,17 +2893,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));
@@ -2921,10 +2923,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;
@@ -2932,26 +2944,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;
@@ -2970,7 +2985,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. */
@@ -2987,7 +3003,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__
@@ -2998,6 +3017,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 3bc6ad3beafc -r 98b06d404e6b xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c Fri May 02 14:59:35 2008 +0100
+++ b/xen/arch/x86/mm/shadow/multi.c Thu May 08 12:50:34 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 3bc6ad3beafc -r 98b06d404e6b xen/arch/x86/mm/shadow/private.h
--- a/xen/arch/x86/mm/shadow/private.h Fri May 02 14:59:35 2008 +0100
+++ b/xen/arch/x86/mm/shadow/private.h Thu May 08 12:50:34 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-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>
Previous by Date: Re: [Xen-devel] long latency of domain shutdown , Jan Beulich
Next by Date: Re: [Xen-devel] long latency of domain shutdown , Keir Fraser
Previous by Thread: [Xen-devel] Re: [PATCH] shadow: track video RAM dirty bits , Samuel Thibault
Next by Thread: [Xen-devel] [PATCH] Add missing ChangeLog entries , john . levon
Indexes: [Date] [Thread] [Top] [All Lists]

Copyright ©, Citrix Systems Inc. All rights reserved. Legal and Privacy
Citrix This site is hosted by Citrix

AltStyle によって変換されたページ (->オリジナル) /