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

[Xen-changelog] [xen stable-4.9] gnttab: improve GNTTABOP_cache_flush locking



commit 986fcb8513262b4fec1303f15dd9c9c962e6fc84
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Wed Dec 20 15:56:49 2017 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Wed Dec 20 15:56:49 2017 +0100

    gnttab: improve GNTTABOP_cache_flush locking
    
    Dropping the lock before returning from grant_map_exists() means handing
    possibly stale information back to the caller. Return back the pointer
    to the active entry instead, for the caller to release the lock once
    done.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Andre Przywara <andre.przywara@xxxxxxxxxx>
    Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
    master commit: 553ac37137c2d1c03bf1b69cfb192ffbfe29daa4
    master date: 2017-12-04 11:04:18 +0100
---
 xen/common/grant_table.c | 37 +++++++++++++++++--------------------
 1 file changed, 17 insertions(+), 20 deletions(-)

diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c
index 7ac0234..d3b0f60 100644
--- a/xen/common/grant_table.c
+++ b/xen/common/grant_table.c
@@ -680,10 +680,10 @@ static int _set_status(unsigned gt_version,
         return _set_status_v2(domid, readonly, mapflag, shah, act, status);
 }
 
-static int grant_map_exists(const struct domain *ld,
-                            struct grant_table *rgt,
-                            unsigned long mfn,
-                            unsigned int *ref_count)
+static struct active_grant_entry *grant_map_exists(const struct domain *ld,
+                                                   struct grant_table *rgt,
+                                                   unsigned long mfn,
+                                                   unsigned int *ref_count)
 {
     unsigned int ref, max_iter;
     
@@ -699,28 +699,20 @@ static int grant_map_exists(const struct domain *ld,
                    nr_grant_entries(rgt));
     for ( ref = *ref_count; ref < max_iter; ref++ )
     {
-        struct active_grant_entry *act;
-        bool_t exists;
-
-        act = active_entry_acquire(rgt, ref);
-
-        exists = act->pin
-            && act->domid == ld->domain_id
-            && act->frame == mfn;
+        struct active_grant_entry *act = active_entry_acquire(rgt, ref);
 
+        if ( act->pin && act->domid == ld->domain_id && act->frame == mfn )
+            return act;
         active_entry_release(act);
-
-        if ( exists )
-            return 0;
     }
 
     if ( ref < nr_grant_entries(rgt) )
     {
         *ref_count = ref;
-        return 1;
+        return NULL;
     }
 
-    return -EINVAL;
+    return ERR_PTR(-EINVAL);
 }
 
 #define MAPKIND_READ 1
@@ -3013,6 +3005,7 @@ static int __gnttab_cache_flush(const 
gnttab_cache_flush_t *cflush,
     struct domain *d, *owner;
     struct page_info *page;
     unsigned long mfn;
+    struct active_grant_entry *act = NULL;
     void *v;
     int ret;
 
@@ -3050,13 +3043,13 @@ static int __gnttab_cache_flush(const 
gnttab_cache_flush_t *cflush,
     {
         grant_read_lock(owner->grant_table);
 
-        ret = grant_map_exists(d, owner->grant_table, mfn, ref_count);
-        if ( ret != 0 )
+        act = grant_map_exists(d, owner->grant_table, mfn, ref_count);
+        if ( IS_ERR_OR_NULL(act) )
         {
             grant_read_unlock(owner->grant_table);
             rcu_unlock_domain(d);
             put_page(page);
-            return ret;
+            return act ? PTR_ERR(act) : 1;
         }
     }
 
@@ -3073,7 +3066,11 @@ static int __gnttab_cache_flush(const 
gnttab_cache_flush_t *cflush,
         ret = 0;
 
     if ( d != owner )
+    {
+        active_entry_release(act);
         grant_read_unlock(owner->grant_table);
+    }
+
     unmap_domain_page(v);
     put_page(page);
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.9

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

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