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] [XEN] Clean up grant-table pinning logic.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [XEN] Clean up grant-table pinning logic.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 05 Sep 2006 21:00:27 +0000
Delivery-date: Tue, 05 Sep 2006 14:00:51 -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 kfraser@xxxxxxxxxxxxxxxxxxxxxxxxxxx
# Node ID 66dd34f2f439e49e5a19c77ac7e7085a8b18a226
# Parent  4fc1688d9a163644b4c3b15072432d1c2b203c50
[XEN] Clean up grant-table pinning logic.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/common/grant_table.c |  154 +++++++++++++++++++++--------------------------
 1 files changed, 70 insertions(+), 84 deletions(-)

diff -r 4fc1688d9a16 -r 66dd34f2f439 xen/common/grant_table.c
--- a/xen/common/grant_table.c  Tue Sep 05 17:26:20 2006 +0100
+++ b/xen/common/grant_table.c  Tue Sep 05 12:20:31 2006 -0700
@@ -90,11 +90,8 @@ __gnttab_map_grant_ref(
     unsigned long  frame = 0;
     int            rc = GNTST_okay;
     struct active_grant_entry *act;
-
-    /* Entry details from @rd's shared grant table. */
     grant_entry_t *sha;
-    domid_t        sdom;
-    u16            sflags;
+    union grant_combo scombo, prev_scombo, new_scombo;
 
     /*
      * We bound the number of times we retry CMPXCHG on memory locations that
@@ -175,13 +172,20 @@ __gnttab_map_grant_ref(
 
     spin_lock(&rd->grant_table->lock);
 
-    sdom = sha->domid;
+    /* If already pinned, check the active domid and avoid refcnt overflow. */
+    if ( act->pin &&
+         ((act->domid != ld->domain_id) ||
+          (act->pin & 0x80808080U) != 0) )
+        PIN_FAIL(unlock_out, GNTST_general_error,
+                 "Bad domain (%d != %d), or risk of counter overflow %08x\n",
+                 act->domid, ld->domain_id, act->pin);
 
     if ( !act->pin ||
          (!(op->flags & GNTMAP_readonly) &&
           !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask))) )
     {
-        sflags = sha->flags;
+        scombo.shorts.flags = sha->flags;
+        scombo.shorts.domid = sha->domid;
 
         /*
          * This loop attempts to set the access (reading/writing) flags
@@ -191,33 +195,29 @@ __gnttab_map_grant_ref(
          */
         for ( ; ; )
         {
-            union grant_combo scombo, prev_scombo, new_scombo;
-
-            if ( unlikely((sflags & GTF_type_mask) != GTF_permit_access) ||
-                 unlikely(sdom != led->domain->domain_id) )
-                PIN_FAIL(unlock_out, GNTST_general_error,
-                         "Bad flags (%x) or dom (%d). (NB. expected dom %d)\n",
-                         sflags, sdom, led->domain->domain_id);
-
-            /* Merge two 16-bit values into a 32-bit combined update. */
-            scombo.shorts.flags = sflags;
-            scombo.shorts.domid = sdom;
-            
+            /* If not already pinned, check the grant domid and type. */
+            if ( !act->pin &&
+                 (((scombo.shorts.flags & GTF_type_mask) !=
+                   GTF_permit_access) ||
+                  (scombo.shorts.domid != ld->domain_id)) )
+                 PIN_FAIL(unlock_out, GNTST_general_error,
+                          "Bad flags (%x) or dom (%d). (expected dom %d)\n",
+                          scombo.shorts.flags, scombo.shorts.domid,
+                          ld->domain_id);
+
             new_scombo = scombo;
             new_scombo.shorts.flags |= GTF_reading;
 
             if ( !(op->flags & GNTMAP_readonly) )
             {
                 new_scombo.shorts.flags |= GTF_writing;
-                if ( unlikely(sflags & GTF_readonly) )
+                if ( unlikely(scombo.shorts.flags & GTF_readonly) )
                     PIN_FAIL(unlock_out, GNTST_general_error,
                              "Attempt to write-pin a r/o grant entry.\n");
             }
 
             prev_scombo.word = cmpxchg((u32 *)&sha->flags,
                                        scombo.word, new_scombo.word);
-
-            /* Did the combined update work (did we see what we expected?). */
             if ( likely(prev_scombo.word == scombo.word) )
                 break;
 
@@ -225,24 +225,15 @@ __gnttab_map_grant_ref(
                 PIN_FAIL(unlock_out, GNTST_general_error,
                          "Shared grant entry is unstable.\n");
 
-            /* Didn't see what we expected. Split out the seen flags & dom. */
-            sflags = prev_scombo.shorts.flags;
-            sdom   = prev_scombo.shorts.domid;
+            scombo = prev_scombo;
         }
 
         if ( !act->pin )
         {
-            act->domid = sdom;
+            act->domid = scombo.shorts.domid;
             act->frame = gmfn_to_mfn(rd, sha->frame);
         }
     }
-    else if ( unlikely(sdom != ld->domain_id) )
-        PIN_FAIL(unlock_out, GNTST_general_error,
-                 "Bad domain (%d). (NB. expected dom %d)\n",
-                 sdom, ld->domain_id);
-    else if ( (act->pin & 0x80808080U) != 0 )
-        PIN_FAIL(unlock_out, ENOSPC,
-                 "Risk of counter overflow %08x\n", act->pin);
 
     if ( op->flags & GNTMAP_device_map )
         act->pin += (op->flags & GNTMAP_readonly) ?
@@ -550,9 +541,7 @@ gnttab_prepare_for_transfer(
 {
     struct grant_table *rgt;
     struct grant_entry *sha;
-    domid_t             sdom;
-    u16                 sflags;
-    union grant_combo   scombo, prev_scombo, tmp_scombo;
+    union grant_combo   scombo, prev_scombo, new_scombo;
     int                 retries = 0;
 
     if ( unlikely((rgt = rd->grant_table) == NULL) ||
@@ -567,29 +556,25 @@ gnttab_prepare_for_transfer(
 
     sha = &rgt->shared[ref];
     
-    sflags = sha->flags;
-    sdom   = sha->domid;
+    scombo.shorts.flags = sha->flags;
+    scombo.shorts.domid = sha->domid;
 
     for ( ; ; )
     {
-        if ( unlikely(sflags != GTF_accept_transfer) ||
-             unlikely(sdom != ld->domain_id) )
+        if ( unlikely(scombo.shorts.flags != GTF_accept_transfer) ||
+             unlikely(scombo.shorts.domid != ld->domain_id) )
         {
             DPRINTK("Bad flags (%x) or dom (%d). (NB. expected dom %d)\n",
-                    sflags, sdom, ld->domain_id);
+                    scombo.shorts.flags, scombo.shorts.domid,
+                    ld->domain_id);
             goto fail;
         }
 
-        /* Merge two 16-bit values into a 32-bit combined update. */
-        scombo.shorts.flags = sflags;
-        scombo.shorts.domid = sdom;
-
-        tmp_scombo = scombo;
-        tmp_scombo.shorts.flags |= GTF_transfer_committed;
+        new_scombo = scombo;
+        new_scombo.shorts.flags |= GTF_transfer_committed;
+
         prev_scombo.word = cmpxchg((u32 *)&sha->flags,
-                                   scombo.word, tmp_scombo.word);
-
-        /* Did the combined update work (did we see what we expected?). */
+                                   scombo.word, new_scombo.word);
         if ( likely(prev_scombo.word == scombo.word) )
             break;
 
@@ -599,9 +584,7 @@ gnttab_prepare_for_transfer(
             goto fail;
         }
 
-        /* Didn't see what we expected. Split out the seen flags & dom. */
-        sflags = prev_scombo.shorts.flags;
-        sdom   = prev_scombo.shorts.domid;
+        scombo = prev_scombo;
     }
 
     spin_unlock(&rgt->lock);
@@ -739,16 +722,21 @@ __release_grant_for_copy(
         gnttab_mark_dirty(rd, r_frame);
 
     spin_lock(&rd->grant_table->lock);
+
     if ( readonly )
+    {
         act->pin -= GNTPIN_hstr_inc;
+    }
     else
+    {
         act->pin -= GNTPIN_hstw_inc;
-
-    if ( !(act->pin & GNTPIN_hstw_mask) && !readonly )
-        gnttab_clear_flag(_GTF_writing, &sha->flags);
+        if ( !(act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) )
+            gnttab_clear_flag(_GTF_writing, &sha->flags);
+    }
 
     if ( !act->pin )
         gnttab_clear_flag(_GTF_reading, &sha->flags);
+
     spin_unlock(&rd->grant_table->lock);
 }
 
@@ -764,8 +752,7 @@ __acquire_grant_for_copy(
     struct active_grant_entry *act;
     s16 rc = GNTST_okay;
     int retries = 0;
-    u16 sflags;
-    domid_t sdom;
+    union grant_combo scombo, prev_scombo, new_scombo;
 
     if ( unlikely(gref >= NR_GRANT_ENTRIES) )
         PIN_FAIL(error_out, GNTST_bad_gntref,
@@ -776,37 +763,43 @@ __acquire_grant_for_copy(
 
     spin_lock(&rd->grant_table->lock);
     
-    sdom = sha->domid;
+    /* If already pinned, check the active domid and avoid refcnt overflow. */
+    if ( act->pin &&
+         ((act->domid != current->domain->domain_id) ||
+          (act->pin & 0x80808080U) != 0) )
+        PIN_FAIL(unlock_out, GNTST_general_error,
+                 "Bad domain (%d != %d), or risk of counter overflow %08x\n",
+                 act->domid, current->domain->domain_id, act->pin);
 
     if ( !act->pin ||
-         (!readonly && !(act->pin & GNTPIN_hstw_mask)) )
-    {
-        sflags = sha->flags;
+         (!readonly && !(act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask))) )
+    {
+        scombo.shorts.flags = sha->flags;
+        scombo.shorts.domid = sha->domid;
 
         for ( ; ; )
         {
-            union grant_combo scombo, prev_scombo, new_scombo;
-
-            if ( unlikely((sflags & GTF_type_mask) != GTF_permit_access ||
-                          sdom != current->domain->domain_id ) )
-                PIN_FAIL(unlock_out, GNTST_general_error,
-                         "Bad flags (%x) or dom (%d). (NB. expected dom %d)\n",
-                         sflags, sdom, current->domain->domain_id);
-
-            /* Merge two 16-bit values into a 32-bit combined update. */
-            scombo.shorts.flags = sflags;
-            scombo.shorts.domid = sdom;
-            
+            /* If not already pinned, check the grant domid and type. */
+            if ( !act->pin &&
+                 (((scombo.shorts.flags & GTF_type_mask) !=
+                   GTF_permit_access) ||
+                  (scombo.shorts.domid != current->domain->domain_id)) )
+                 PIN_FAIL(unlock_out, GNTST_general_error,
+                          "Bad flags (%x) or dom (%d). (expected dom %d)\n",
+                          scombo.shorts.flags, scombo.shorts.domid,
+                          current->domain->domain_id);
+
             new_scombo = scombo;
             new_scombo.shorts.flags |= GTF_reading;
 
             if ( !readonly )
             {
                 new_scombo.shorts.flags |= GTF_writing;
-                if ( unlikely(sflags & GTF_readonly) )
+                if ( unlikely(scombo.shorts.flags & GTF_readonly) )
                     PIN_FAIL(unlock_out, GNTST_general_error,
                              "Attempt to write-pin a r/o grant entry.\n");
             }
+
             prev_scombo.word = cmpxchg((u32 *)&sha->flags,
                                        scombo.word, new_scombo.word);
             if ( likely(prev_scombo.word == scombo.word) )
@@ -815,23 +808,16 @@ __acquire_grant_for_copy(
             if ( retries++ == 4 )
                 PIN_FAIL(unlock_out, GNTST_general_error,
                          "Shared grant entry is unstable.\n");
-            sflags = prev_scombo.shorts.flags;
-            sdom = prev_scombo.shorts.flags;
+
+            scombo = prev_scombo;
         }
 
         if ( !act->pin )
         {
-            act->domid = sdom;
+            act->domid = scombo.shorts.domid;
             act->frame = gmfn_to_mfn(rd, sha->frame);
         }
     }
-    else if ( unlikely(sdom != current->domain->domain_id) )
-        PIN_FAIL(unlock_out, GNTST_general_error,
-                 "Bad domain (%d). (NB. expected dom %d)\n",
-                 sdom, current->domain->domain_id);
-    else if ( (act->pin & 0x80808080U) != 0 )
-        PIN_FAIL(unlock_out, ENOSPC,
-                 "Risk of counter overflow %08x\n", act->pin);
 
     act->pin += readonly ? GNTPIN_hstr_inc : GNTPIN_hstw_inc;
 

_______________________________________________
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] [XEN] Clean up grant-table pinning logic., Xen patchbot-unstable <=