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

[Xen-devel] [PATCH 01 of 11] x86/mm: make p2m lock into an rwlock



# HG changeset patch
# User Tim Deegan <tim@xxxxxxx>
# Date 1336661656 -3600
# Node ID 4a99c5456e9d8aa707bbd57bb4f4af88e1d456ca
# Parent  8a86d841e6d42fbffc9e20d3028875dd4990882d
x86/mm: make p2m lock into an rwlock

Because the p2m lock was already recursive, we need to add a new
mm-lock class of recursive rwlocks.

Signed-off-by: Tim Deegan <tim@xxxxxxx>

diff -r 8a86d841e6d4 -r 4a99c5456e9d xen/arch/x86/mm/mm-locks.h
--- a/xen/arch/x86/mm/mm-locks.h        Tue May 08 13:36:24 2012 +0200
+++ b/xen/arch/x86/mm/mm-locks.h        Thu May 10 15:54:16 2012 +0100
@@ -97,13 +97,71 @@ static inline void _mm_enforce_order_loc
     __set_lock_level(level);
 }
 
+
+static inline void mm_rwlock_init(mm_rwlock_t *l)
+{
+    rwlock_init(&l->lock);
+    l->locker = -1;
+    l->locker_function = "nobody";
+    l->unlock_level = 0;
+}
+
+static inline int mm_write_locked_by_me(mm_rwlock_t *l)
+{
+    return (l->locker == get_processor_id());
+}
+
+static inline void _mm_write_lock(mm_rwlock_t *l, const char *func, int level)
+{
+    if ( !mm_write_locked_by_me(l) )
+    {
+        __check_lock_level(level);
+        write_lock(&l->lock);
+        l->locker = get_processor_id();
+        l->locker_function = func;
+        l->unlock_level = __get_lock_level();
+        __set_lock_level(level);
+    }
+    l->recurse_count++;
+}
+
+static inline void mm_write_unlock(mm_rwlock_t *l)
+{
+    if ( --(l->recurse_count) != 0 )
+        return;
+    l->locker = -1;
+    l->locker_function = "nobody";
+    __set_lock_level(l->unlock_level);
+    write_unlock(&l->lock);
+}
+
+static inline void _mm_read_lock(mm_rwlock_t *l, int level)
+{
+    __check_lock_level(level);
+    read_lock(&l->lock);
+    /* There's nowhere to store the per-CPU unlock level so we can't
+     * set the lock level. */
+}
+
+static inline void mm_read_unlock(mm_rwlock_t *l)
+{
+    read_unlock(&l->lock);
+}
+
 /* This wrapper uses the line number to express the locking order below */
 #define declare_mm_lock(name)                                                 \
     static inline void mm_lock_##name(mm_lock_t *l, const char *func, int rec)\
     { _mm_lock(l, func, __LINE__, rec); }
+#define declare_mm_rwlock(name)                                               \
+    static inline void mm_write_lock_##name(mm_rwlock_t *l, const char *func) \
+    { _mm_write_lock(l, func, __LINE__); }                                    \
+    static inline void mm_read_lock_##name(mm_rwlock_t *l)                    \
+    { _mm_read_lock(l, __LINE__); }
 /* These capture the name of the calling function */
 #define mm_lock(name, l) mm_lock_##name(l, __func__, 0)
 #define mm_lock_recursive(name, l) mm_lock_##name(l, __func__, 1)
+#define mm_write_lock(name, l) mm_write_lock_##name(l, __func__)
+#define mm_read_lock(name, l) mm_read_lock_##name(l)
 
 /* This wrapper is intended for "external" locks which do not use
  * the mm_lock_t types. Such locks inside the mm code are also subject
@@ -152,27 +210,24 @@ declare_mm_lock(nestedp2m)
 #define nestedp2m_unlock(d) mm_unlock(&(d)->arch.nested_p2m_lock)
 
 /* P2M lock (per-p2m-table)
- * 
- * This protects all queries and updates to the p2m table. 
  *
- * A note about ordering:
- *   The order established here is enforced on all mutations of a p2m.
- *   For lookups, the order established here is enforced only for hap
- *   domains (1. shadow domains present a few nasty inversions; 
- *            2. shadow domains do not support paging and sharing, 
- *               the main sources of dynamic p2m mutations)
- * 
- * The lock is recursive as it is common for a code path to look up a gfn
- * and later mutate it.
+ * This protects all queries and updates to the p2m table.
+ * Queries may be made under the read lock but all modifications
+ * need the main (write) lock.
+ *
+ * The write lock is recursive as it is common for a code path to look
+ * up a gfn and later mutate it.
  */
 
-declare_mm_lock(p2m)
-#define p2m_lock(p)           mm_lock_recursive(p2m, &(p)->lock)
-#define gfn_lock(p,g,o)       mm_lock_recursive(p2m, &(p)->lock)
-#define p2m_unlock(p)         mm_unlock(&(p)->lock)
-#define gfn_unlock(p,g,o)     mm_unlock(&(p)->lock)
-#define p2m_locked_by_me(p)   mm_locked_by_me(&(p)->lock)
-#define gfn_locked_by_me(p,g) mm_locked_by_me(&(p)->lock)
+declare_mm_rwlock(p2m);
+#define p2m_lock(p)           mm_write_lock(p2m, &(p)->lock);
+#define p2m_unlock(p)         mm_write_unlock(&(p)->lock);
+#define gfn_lock(p,g,o)       p2m_lock(p)
+#define gfn_unlock(p,g,o)     p2m_unlock(p)
+#define p2m_read_lock(p)      mm_read_lock(p2m, &(p)->lock)
+#define p2m_read_unlock(p)    mm_read_unlock(&(p)->lock)
+#define p2m_locked_by_me(p)   mm_write_locked_by_me(&(p)->lock)
+#define gfn_locked_by_me(p,g) p2m_locked_by_me(p)
 
 /* Sharing per page lock
  *
diff -r 8a86d841e6d4 -r 4a99c5456e9d xen/arch/x86/mm/p2m.c
--- a/xen/arch/x86/mm/p2m.c     Tue May 08 13:36:24 2012 +0200
+++ b/xen/arch/x86/mm/p2m.c     Thu May 10 15:54:16 2012 +0100
@@ -71,7 +71,7 @@ boolean_param("hap_2mb", opt_hap_2mb);
 /* Init the datastructures for later use by the p2m code */
 static void p2m_initialise(struct domain *d, struct p2m_domain *p2m)
 {
-    mm_lock_init(&p2m->lock);
+    mm_rwlock_init(&p2m->lock);
     mm_lock_init(&p2m->pod.lock);
     INIT_LIST_HEAD(&p2m->np2m_list);
     INIT_PAGE_LIST_HEAD(&p2m->pages);
diff -r 8a86d841e6d4 -r 4a99c5456e9d xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h  Tue May 08 13:36:24 2012 +0200
+++ b/xen/include/asm-x86/mm.h  Thu May 10 15:54:16 2012 +0100
@@ -649,4 +649,12 @@ typedef struct mm_lock {
     const char        *locker_function; /* func that took it */
 } mm_lock_t;
 
+typedef struct mm_rwlock {
+    rwlock_t           lock;
+    int                unlock_level;
+    int                recurse_count;
+    int                locker; /* CPU that holds the write lock */
+    const char        *locker_function; /* func that took it */
+} mm_rwlock_t;
+
 #endif /* __ASM_X86_MM_H__ */
diff -r 8a86d841e6d4 -r 4a99c5456e9d xen/include/asm-x86/p2m.h
--- a/xen/include/asm-x86/p2m.h Tue May 08 13:36:24 2012 +0200
+++ b/xen/include/asm-x86/p2m.h Thu May 10 15:54:16 2012 +0100
@@ -192,7 +192,7 @@ typedef unsigned int p2m_query_t;
 /* Per-p2m-table state */
 struct p2m_domain {
     /* Lock that protects updates to the p2m */
-    mm_lock_t          lock;
+    mm_rwlock_t           lock;
 
     /* Shadow translated domain: p2m mapping */
     pagetable_t        phys_table;

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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