Skip to contentSkip to conversation

Segment dirty log for performance

PATCH In review Ben Guthro 3 participants 4 messages Oct 24, 2007 – Oct 25, 2007

lore
Share & tools
lore

Ben Guthro

author
#0 lore raw

PATCH 1/1 Segment dirty log for performance

Represent dirty log as an array of bitmaps.
Also, when bookkeeping the valid HVM pfn ranges, breaks the PFNs into two ranges -- RAM and VGA. This allows the dirty page bitmaps to conform to these ranges and to skip the (sometimes large) empty PFN range between them.

xen/arch/x86/mm/p2m.c +6 -3
diff -r 9bdb3e7a99c9 xen/arch/x86/mm/p2m.c
@@ -241,9 +241,12 @@ set_p2m_entry(struct domain *d, unsigned
                                0, L1_PAGETABLE_ENTRIES);
     ASSERT(p2m_entry);
 
-    /* Track the highest gfn for which we have ever had a valid mapping */
-    if ( mfn_valid(mfn) && (gfn > d->arch.p2m.max_mapped_pfn) )
-        d->arch.p2m.max_mapped_pfn = gfn;
+    if ( mfn_valid(mfn) ) {
+        paging_pfn_range_append(d, gfn);
+        /* Track the highest gfn for which we have ever had a valid mapping */
+        if (gfn > d->arch.p2m.max_mapped_pfn ) 
+            d->arch.p2m.max_mapped_pfn = gfn;
+    }
 
     if ( mfn_valid(mfn) || (p2mt == p2m_mmio_direct) )
         entry_content = l1e_from_pfn(mfn_x(mfn), p2m_type_to_flags(p2mt));
xen/arch/x86/mm/paging.c +177 -69

299 lines not on this page · raw message

xen/arch/x86/mm/shadow/private.h +12 -7
diff -r 9bdb3e7a99c9 xen/arch/x86/mm/shadow/private.h
@@ -491,17 +491,22 @@ sh_mfn_is_dirty(struct domain *d, mfn_t 
 /* Is this guest page dirty?  Call only in log-dirty mode. */
 {
     unsigned long pfn;
+    struct pfn_range *pr, *pr0 = d->arch.paging.log_dirty.pfn_range;
+    
     ASSERT(shadow_mode_log_dirty(d));
-    ASSERT(d->arch.paging.log_dirty.bitmap != NULL);
 
     /* We /really/ mean PFN here, even for non-translated guests. */
     pfn = get_gpfn_from_mfn(mfn_x(gmfn));
-    if ( likely(VALID_M2P(pfn))
-         && likely(pfn < d->arch.paging.log_dirty.bitmap_size) 
-         && test_bit(pfn, d->arch.paging.log_dirty.bitmap) )
-        return 1;
-
-    return 0;
+    if ( unlikely(!VALID_M2P(pfn)) )
+         return 0;
+         
+    for (pr = pr0; likely(pr - pr0 != PFN_RANGE_NR && pr->len > 0); pr++)
+    {
+        ASSERT(pr->dirty_bitmap != NULL);
+        if ( likely(pr->start <= pfn && pfn < pr->start + pr->len) )
+            return test_bit(pfn - pr->start, pr->dirty_bitmap);
+    }
+    return 0; /* shouldn't get here */
 }
 
 
xen/include/asm-x86/domain.h +9 -4
diff -r 9bdb3e7a99c9 xen/include/asm-x86/domain.h
@@ -158,13 +158,18 @@ struct log_dirty_domain {
     int            locker; /* processor that holds the lock */
     const char    *locker_function; /* func that took it */
 
-    /* log-dirty bitmap to record dirty pages */
-    unsigned long *bitmap;
-    unsigned int   bitmap_size;  /* in pages, bit per page */
-
     /* log-dirty mode stats */
     unsigned int   fault_count;
     unsigned int   dirty_count;
+
+    /* segmented log-dirty bitmap to record dirty pages */
+#define PFN_RANGE_NR 4
+    struct pfn_range {
+        unsigned long start;
+        unsigned long len;
+        uint8_t *dirty_bitmap;
+        unsigned int dirty_bitmap_size;  /* in pages, bit per page */
+    } pfn_range[PFN_RANGE_NR];
 
     /* functions which are paging mode specific */
     int            (*enable_log_dirty   )(struct domain *d);
xen/include/asm-x86/paging.h +2 -0
diff -r 9bdb3e7a99c9 xen/include/asm-x86/paging.h
@@ -258,6 +258,8 @@ static inline int paging_cmpxchg_guest_e
         return (!cmpxchg_user(p, *old, new));
 }
 
+void paging_pfn_range_append(struct domain *d, unsigned long gfn);
+
 /* Helper function that writes a pte in such a way that a concurrent read 
  * never sees a half-written entry that has _PAGE_PRESENT set */
 static inline void safe_write_pte(l1_pgentry_t *p, l1_pgentry_t new)

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel

#1 lore raw
Quoted 8 lines · Ben Guthro

Represent dirty log as an array of bitmaps.
Also, when bookkeeping the valid HVM pfn ranges, breaks the PFNs into two ranges -- RAM and VGA. This allows the dirty page bitmaps to conform to these ranges and to skip the (sometimes large) empty PFN range between them.

In terms of tracking active ranges of pseudophysical space, we already have a data structure that can give that info (the p2m radix tree). And the better way of subdividing the dirty bitmap would be to make that a radix tree too, where the leaves are PAGE_SIZE'd bitmaps each handling 128MB of pseudophys address space. This would mean we only need order-0 allocations in the dirty bitmap logic, greatly reducing the chance of domain-migration failure with ENOMEM.

Apart from the obvious benefit of allocating a smaller dirty bitmap, which is hence more likely to succeed, how much does this improve migration performance for a small-ish memory guest? Is it significant?

-- Keir

#2 lore raw
Quoted 21 lines · Keir Fraser
Quoted 9 lines · Ben Guthro

Represent dirty log as an array of bitmaps.
Also, when bookkeeping the valid HVM pfn ranges, breaks the PFNs into two ranges -- RAM and VGA. This allows the dirty page bitmaps to conform to these ranges and to skip the (sometimes large) empty PFN range between them.

In terms of tracking active ranges of pseudophysical space, we already have a data structure that can give that info (the p2m radix tree). And the better way of subdividing the dirty bitmap would be to make that a radix tree too, where the leaves are PAGE_SIZE'd bitmaps each handling 128MB of pseudophys address space. This would mean we only need order-0 allocations in the dirty bitmap logic, greatly reducing the chance of domain-migration failure with ENOMEM.

Quoted 6 lines

Apart from the obvious benefit of allocating a smaller dirty bitmap, which is hence more likely to succeed, how much does this improve migration performance for a small-ish memory guest? Is it significant?

-- Keir

No, the performance benefit is not noticeable. We (Robert Phillips, actually) did it to make migrate more reliable. But relying only on order-0 allocations is obviously even better. I'll take a look at using the radix tree as you suggest.

Thanks,
Dave

#3 lore raw
Quoted 4 lines · David Lively

No, the performance benefit is not noticeable. We (Robert Phillips, actually) did it to make migrate more reliable. But relying only on order-0 allocations is obviously even better. I'll take a look at using the radix tree as you suggest.

Okay, I see. A patch to use only order-0 allocations would be excellent!

-- Keir