[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] RFC: [0/2] Remove netloop by lazy copying in netback



On Wed, Mar 28, 2007 at 06:46:40AM +1000, Herbert Xu wrote:
> 
> I've checked again and the accessed bit is certainly present on ppc
> as well as ia64.  The only I don't know is if it's present on the
> nested page tables on ia64 but I see no reasons why it wouldn't be.

Here is a completely untested patch that demonstrates how this could
be done on x86.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@xxxxxxxxxxxxxxxxxxx>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff -r 3ac19fda0bc2 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Fri Mar 02 12:11:52 2007 +0000
+++ b/xen/arch/x86/mm.c Wed Mar 28 22:58:45 2007 +1000
@@ -1262,6 +1262,36 @@ static void free_l4_table(struct page_in
 #endif
 
 
+static inline int cmpxchg_intpte(intpte_t *p,
+                                intpte_t *old,
+                                intpte_t new,
+                                unsigned long mfn,
+                                struct vcpu *v)
+{
+        int rv;
+
+        for ( ; ; )
+        {
+            intpte_t t = *old;
+
+            rv = paging_cmpxchg_guest_entry(v, p, old, new, _mfn(mfn));
+            if ( unlikely(rv == 0) )
+            {
+                MEM_LOG("Failed to update %" PRIpte " -> %" PRIpte
+                        ": saw %" PRIpte, t, new, t);
+                break;
+            }
+
+            if ( t == *old )
+                break;
+
+            /* Allowed to change in Accessed/Dirty flags only. */
+            BUG_ON((t ^ *old) & ~(intpte_t)(_PAGE_ACCESSED|_PAGE_DIRTY));
+        }
+
+        return rv;
+}
+
 /* How to write an entry to the guest pagetables.
  * Returns 0 for failure (pointer not valid), 1 for success. */
 static inline int update_intpte(intpte_t *p, 
@@ -1274,27 +1304,7 @@ static inline int update_intpte(intpte_t
 #ifndef PTE_UPDATE_WITH_CMPXCHG
     rv = paging_write_guest_entry(v, p, new, _mfn(mfn));
 #else
-    {
-        intpte_t t = old;
-        for ( ; ; )
-        {
-            rv = paging_cmpxchg_guest_entry(v, p, &t, new, _mfn(mfn));
-            if ( unlikely(rv == 0) )
-            {
-                MEM_LOG("Failed to update %" PRIpte " -> %" PRIpte
-                        ": saw %" PRIpte, old, new, t);
-                break;
-            }
-
-            if ( t == old )
-                break;
-
-            /* Allowed to change in Accessed/Dirty flags only. */
-            BUG_ON((t ^ old) & ~(intpte_t)(_PAGE_ACCESSED|_PAGE_DIRTY));
-
-            old = t;
-        }
-    }
+    rv = cmpxchg_intpte(p, &old, new, mfn, v);
 #endif
     return rv;
 }
@@ -2598,6 +2608,7 @@ static int destroy_grant_va_mapping(
     unsigned long addr, unsigned long frame, struct vcpu *v)
 {
     l1_pgentry_t *pl1e, ol1e;
+    intpte_t *ptep, opte, npte;
     unsigned long gl1mfn;
     int rc = 0;
     
@@ -2619,12 +2630,19 @@ static int destroy_grant_va_mapping(
     }
 
     /* Delete pagetable entry. */
-    if ( unlikely(!UPDATE_ENTRY(l1, pl1e, ol1e, l1e_empty(), gl1mfn, v)) )
+    ptep = (intpte_t *)pl1e;
+    opte = l1e_get_intpte(ol1e);
+    npte = l1e_get_intpte(l1e_empty());
+
+    if ( unlikely(!cmpxchg_intpte(ptep, opte, npte, mfn, v)) )
     {
         MEM_LOG("Cannot delete PTE entry at %p", (unsigned long *)pl1e);
         rc = GNTST_general_error;
         goto out;
     }
+
+    if (!(opte & (intpte_t)_PAGE_ACCESSED))
+        rc = GNTST_unused;
 
  out:
     guest_unmap_l1e(v, pl1e);
diff -r 3ac19fda0bc2 xen/common/grant_table.c
--- a/xen/common/grant_table.c  Fri Mar 02 12:11:52 2007 +0000
+++ b/xen/common/grant_table.c  Wed Mar 28 22:58:45 2007 +1000
@@ -394,7 +394,7 @@ gnttab_map_grant_ref(
     return 0;
 }
 
-static void
+static int
 __gnttab_unmap_grant_ref(
     struct gnttab_unmap_grant_ref *op)
 {
@@ -416,7 +416,7 @@ __gnttab_unmap_grant_ref(
     {
         gdprintk(XENLOG_INFO, "Bad handle (%d).\n", op->handle);
         op->status = GNTST_bad_handle;
-        return;
+        return 0;
     }
 
     map = &maptrack_entry(ld->grant_table, op->handle);
@@ -425,7 +425,7 @@ __gnttab_unmap_grant_ref(
     {
         gdprintk(XENLOG_INFO, "Zero flags for handle (%d).\n", op->handle);
         op->status = GNTST_bad_handle;
-        return;
+        return 0;
     }
 
     dom   = map->domid;
@@ -437,7 +437,7 @@ __gnttab_unmap_grant_ref(
         /* This can happen when a grant is implicitly unmapped. */
         gdprintk(XENLOG_INFO, "Could not find domain %d\n", dom);
         domain_crash(ld); /* naughty... */
-        return;
+        return 0;
     }
 
     TRACE_1D(TRC_MEM_PAGE_GRANT_UNMAP, dom);
@@ -511,9 +511,17 @@ __gnttab_unmap_grant_ref(
         gnttab_clear_flag(_GTF_reading, &sha->flags);
 
  unmap_out:
-    op->status = rc;
     spin_unlock(&rd->grant_table->lock);
     rcu_unlock_domain(rd);
+
+    op->status = rc;
+
+    if (rc == GNTST_unused) {
+        op->status = GNTST_okay;
+        return 0;
+    }
+
+    return 1;
 }
 
 static long
@@ -521,23 +529,25 @@ gnttab_unmap_grant_ref(
     XEN_GUEST_HANDLE(gnttab_unmap_grant_ref_t) uop, unsigned int count)
 {
     int i;
+    int used = 0;
+    int err = -EFAULT;
     struct gnttab_unmap_grant_ref op;
 
     for ( i = 0; i < count; i++ )
     {
         if ( unlikely(__copy_from_guest_offset(&op, uop, i, 1)) )
             goto fault;
-        __gnttab_unmap_grant_ref(&op);
+        used |= __gnttab_unmap_grant_ref(&op);
         if ( unlikely(__copy_to_guest_offset(uop, i, &op, 1)) )
             goto fault;
     }
 
-    flush_tlb_mask(current->domain->domain_dirty_cpumask);
-    return 0;
+    err = 0;
 
 fault:
-    flush_tlb_mask(current->domain->domain_dirty_cpumask);
-    return -EFAULT;    
+    if (used)
+        flush_tlb_mask(current->domain->domain_dirty_cpumask);
+    return err;
 }
 
 int
diff -r 3ac19fda0bc2 xen/include/public/grant_table.h
--- a/xen/include/public/grant_table.h  Fri Mar 02 12:11:52 2007 +0000
+++ b/xen/include/public/grant_table.h  Wed Mar 28 22:58:45 2007 +1000
@@ -360,6 +360,7 @@ DEFINE_XEN_GUEST_HANDLE(gnttab_query_siz
 /*
  * Values for error status returns. All errors are -ve.
  */
+#define GNTST_unused           (1)  /* Entry is unused (internal status).    */
 #define GNTST_okay             (0)  /* Normal return.                        */
 #define GNTST_general_error    (-1) /* General undefined error.              */
 #define GNTST_bad_domain       (-2) /* Unrecognsed domain id.                */

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.