bitkeeper revision 1.836.1.1 (4070ff6fJhQoaxeSlTRL6ojba0QXfw)
authoriap10@tetris.cl.cam.ac.uk <iap10@tetris.cl.cam.ac.uk>
Mon, 5 Apr 2004 06:40:47 +0000 (06:40 +0000)
committeriap10@tetris.cl.cam.ac.uk <iap10@tetris.cl.cam.ac.uk>
Mon, 5 Apr 2004 06:40:47 +0000 (06:40 +0000)
shadow logdirty mode added

xen/common/memory.c
xen/include/asm-i386/page.h
xen/include/xen/shadow.h

index b7896e3cfbccffc941d3148f242c0a195b6450a8..6b3b9d4e707e9c313f5d59f9214ee10b9b0ba3e8 100644 (file)
@@ -1149,7 +1149,12 @@ int do_update_va_mapping(unsigned long page_nr,
        }
 
        check_pagetable( p, p->mm.pagetable, "va" ); // debug
-    
+
+       /* if we're in logdirty mode, we need to note that we've updated the
+          PTE in the PT-holding page. This is a bit of a pain as we don't
+          know the physcial (machine) frame number of the page */
+       if ( p->mm.shadow_mode == SHM_logdirty )
+         mark_dirty( &current->mm, va_to_l1mfn(page_nr<<PAGE_SHIFT) );    
     }
 
 
index 1f8260e03ce1880017c3cabc4bcaac99ac87b526..54cbd85f1147b1831a1e462220c72f522fed67f4 100644 (file)
@@ -93,6 +93,8 @@ typedef struct { unsigned long pt_lo; } pagetable_t;
 #define linear_pg_table ((l1_pgentry_t *)LINEAR_PT_VIRT_START)
 #define linear_l2_table ((l2_pgentry_t *)(LINEAR_PT_VIRT_START+(LINEAR_PT_VIRT_START>>(L2_PAGETABLE_SHIFT-L1_PAGETABLE_SHIFT))))
 
+#define va_to_l1mfn(_va) (l2_pgentry_val(linear_l2_table[_va>>L2_PAGETABLE_SHIFT]) >> PAGE_SHIFT)
+
 extern l2_pgentry_t idle_pg_table[ENTRIES_PER_L2_PAGETABLE];
 extern void paging_init(void);
 
index f5c0d5327aff8fdf44693d172d4dd9e486358249..e5399d4ad08a79fe34612ae80fabd3765642afb5 100644 (file)
@@ -82,8 +82,12 @@ static inline void mark_dirty( struct mm_struct *m, unsigned int mfn )
        ASSERT(m->shadow_dirty_bitmap);
        if( likely(pfn<m->shadow_dirty_bitmap_size) )
        {
-               // use setbit to be smp guest safe
-               set_bit( pfn, m->shadow_dirty_bitmap );
+               /* use setbit to be smp guest safe. Since the same page is likely to 
+                  get marked dirty many times, examine the bit first before doing the
+                  expensive lock-prefixed opertion */
+
+               if (! test_bit( pfn, m->shadow_dirty_bitmap ) )
+                       set_bit( pfn, m->shadow_dirty_bitmap );
        }
        else
        {
@@ -328,6 +332,18 @@ static inline unsigned long get_shadow_status( struct mm_struct *m,
 {
        unsigned long res;
 
+       /* If we get here, we know that this domain is running in shadow mode. 
+          We also know that some sort of update has happened to the underlying
+          page table page: either a PTE has been updated, or the page has
+          changed type. If we're in log dirty mode, we should set the approrpiate
+          bit in the dirty bitmap.
+          NB: the VA update path doesn't use this so needs to be handled 
+          independnetly. 
+        */
+
+       if( m->shadow_mode == SHM_logdirty )
+               mark_dirty( m, gpfn );
+
        spin_lock(&m->shadow_lock);
        res = __shadow_status( m, gpfn );
        if (!res) spin_unlock(&m->shadow_lock);