All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Vrabel <david.vrabel@citrix.com>
To: xen-devel@lists.xenproject.org
Cc: Keir Fraser <keir@xen.org>, Jan Beulich <jbeulich@suse.com>,
	Christoph Egger <chegger@amazon.de>, Tim Deegan <tim@xen.org>,
	David Vrabel <david.vrabel@citrix.com>,
	Matt Wilson <msw@amazon.com>,
	Ian Campbell <ian.campbell@citrix.com>
Subject: [PATCHv6 3/5] gnttab: split grant table lock into table and maptrack locks
Date: Wed, 22 Apr 2015 17:00:34 +0100	[thread overview]
Message-ID: <1429718436-9782-4-git-send-email-david.vrabel@citrix.com> (raw)
In-Reply-To: <1429718436-9782-1-git-send-email-david.vrabel@citrix.com>

From: Matt Wilson <msw@amazon.com>

The maptrack lock protects the maptrack state only.

Signed-off-by: Matt Wilson <msw@amazon.com>
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
---
Subsequent changes make both these locks uncontented.  Is this patch
really necessary? -- dvrabel
---
 xen/common/grant_table.c      |   33 ++++++++++++++++++++++++++++-----
 xen/include/xen/grant_table.h |    7 ++++++-
 2 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c
index 3a555f9..a5470c8 100644
--- a/xen/common/grant_table.c
+++ b/xen/common/grant_table.c
@@ -264,10 +264,10 @@ static inline void
 put_maptrack_handle(
     struct grant_table *t, int handle)
 {
-    spin_lock(&t->lock);
+    spin_lock(&t->maptrack_lock);
     maptrack_entry(t, handle).ref = t->maptrack_head;
     t->maptrack_head = handle;
-    spin_unlock(&t->lock);
+    spin_unlock(&t->maptrack_lock);
 }
 
 static inline int
@@ -279,7 +279,7 @@ get_maptrack_handle(
     struct grant_mapping *new_mt;
     unsigned int          new_mt_limit, nr_frames;
 
-    spin_lock(&lgt->lock);
+    spin_lock(&lgt->maptrack_lock);
 
     while ( unlikely((handle = __get_maptrack_handle(lgt)) == -1) )
     {
@@ -308,12 +308,15 @@ get_maptrack_handle(
                  nr_frames + 1);
     }
 
-    spin_unlock(&lgt->lock);
+    spin_unlock(&lgt->maptrack_lock);
 
     return handle;
 }
 
-/* Number of grant table entries. Caller must hold d's grant table lock. */
+/* 
+ * Number of grant table entries. Caller must hold d's grant table
+ * read lock.
+ */
 static unsigned int nr_grant_entries(struct grant_table *gt)
 {
     ASSERT(gt->gt_version != 0);
@@ -531,6 +534,13 @@ static int grant_map_exists(const struct domain *ld,
     return -EINVAL;
 }
 
+/* 
+ * Count the number of mapped ro or rw entries tracked in the left
+ * grant table given a provided mfn provided by a foreign domain. 
+ *
+ * This function takes the maptrack lock from the left grant table and
+ * must be called with the right grant table's rwlock held.
+ */
 static void mapcount(
     struct grant_table *lgt, struct domain *rd, unsigned long mfn,
     unsigned int *wrc, unsigned int *rdc)
@@ -540,6 +550,16 @@ static void mapcount(
 
     *wrc = *rdc = 0;
 
+    /* 
+     * While taking the local maptrack spinlock prevents any mapping
+     * changes, the remote active entries could be changing while we
+     * are counting. The caller has to hold the grant table lock, or
+     * some other mechanism should be used to prevent concurrent
+     * changes during this operation.
+     */
+    ASSERT(spin_is_locked(&rd->grant_table->lock));
+    spin_lock(&lgt->maptrack_lock);
+
     for ( handle = 0; handle < lgt->maptrack_limit; handle++ )
     {
         struct active_grant_entry *act;
@@ -552,6 +572,8 @@ static void mapcount(
         if ( act->frame == mfn )
             (map->flags & GNTMAP_readonly) ? (*rdc)++ : (*wrc)++;
     }
+
+    spin_unlock(&lgt->maptrack_lock);
 }
 
 /*
@@ -2980,6 +3002,7 @@ grant_table_create(
 
     /* Simple stuff. */
     spin_lock_init(&t->lock);
+    spin_lock_init(&t->maptrack_lock);
     t->nr_grant_frames = INITIAL_NR_GRANT_FRAMES;
 
     /* Active grant table. */
diff --git a/xen/include/xen/grant_table.h b/xen/include/xen/grant_table.h
index 32f5786..8ff1883 100644
--- a/xen/include/xen/grant_table.h
+++ b/xen/include/xen/grant_table.h
@@ -82,7 +82,12 @@ struct grant_table {
     struct grant_mapping **maptrack;
     unsigned int          maptrack_head;
     unsigned int          maptrack_limit;
-    /* Lock protecting updates to active and shared grant tables. */
+    /* Lock protecting the maptrack page list, head, and limit */
+    spinlock_t            maptrack_lock;
+    /* 
+     * Lock protecting updates to grant table state (version, active
+     * entry list, etc.)
+     */
     spinlock_t            lock;
     /* The defined versions are 1 and 2.  Set to 0 if we don't know
        what version to use yet. */
-- 
1.7.10.4

  parent reply	other threads:[~2015-04-22 16:01 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-22 16:00 [PATCHv6 0/6] gnttab: Improve scaleability David Vrabel
2015-04-22 16:00 ` [PATCHv6 1/5] gnttab: add locking documentation David Vrabel
2015-04-22 16:00 ` [PATCHv6 2/5] gnttab: introduce per-active entry locks David Vrabel
2015-04-23 12:42   ` Jan Beulich
2015-04-23 13:49     ` David Vrabel
2015-04-22 16:00 ` David Vrabel [this message]
2015-04-23 15:04   ` [PATCHv6 3/5] gnttab: split grant table lock into table and maptrack locks Jan Beulich
2015-04-29 10:53     ` David Vrabel
2015-04-29 11:12       ` Jan Beulich
2015-04-22 16:00 ` [PATCHv6 4/5] gnttab: remove unnecessary grant table locks David Vrabel
2015-04-23 11:23   ` Tim Deegan
2015-04-23 15:31   ` Jan Beulich
2015-04-22 16:00 ` [PATCHv6 5/5] gnttab: use per-VCPU maptrack free lists David Vrabel
2015-04-23 16:11   ` Jan Beulich
2015-04-23 16:29     ` David Vrabel
2015-04-24  6:44       ` Jan Beulich
2015-04-24  9:09     ` Malcolm Crossley
2015-04-24  9:50       ` Jan Beulich
2015-04-24 10:02         ` Andrew Cooper
2015-04-24 10:21         ` Malcolm Crossley
2015-04-24 12:52           ` Jan Beulich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1429718436-9782-4-git-send-email-david.vrabel@citrix.com \
    --to=david.vrabel@citrix.com \
    --cc=chegger@amazon.de \
    --cc=ian.campbell@citrix.com \
    --cc=jbeulich@suse.com \
    --cc=keir@xen.org \
    --cc=msw@amazon.com \
    --cc=tim@xen.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.