[Top][All Lists]

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

[Qemu-devel] [PATCH 1/3] rcu: use call_rcu semantics from liburcu

From: Emilio G. Cota
Subject: [Qemu-devel] [PATCH 1/3] rcu: use call_rcu semantics from liburcu
Date: Tue, 3 Feb 2015 17:08:17 -0500

The recently added call_rcu does not match liburcu's call_rcu's semantics;
instead, call_rcu1 does. Fix it by doing the following:

- Rename QEMU's call_rcu  to call_rcu_first_elem
- Rename QEMU's call_rcu1 to call_rcu

The end goal is to be able to switch at compile-time between
liburcu and QEMU's RCU implementation.

Signed-off-by: Emilio G. Cota <address@hidden>
 docs/rcu.txt       | 21 ++++++++++-----------
 include/qemu/rcu.h |  6 +++---
 memory.c           |  4 ++--
 util/rcu.c         |  2 +-
 4 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/docs/rcu.txt b/docs/rcu.txt
index 61752b9..575f563 100644
--- a/docs/rcu.txt
+++ b/docs/rcu.txt
@@ -85,8 +85,8 @@ The core RCU API is small:
         synchronize_rcu.  If this is not possible (for example, because
         the updater is protected by the BQL), you can use call_rcu.
-     void call_rcu1(struct rcu_head * head,
-                    void (*func)(struct rcu_head *head));
+     void call_rcu(struct rcu_head * head,
+                   void (*func)(struct rcu_head *head));
         This function invokes func(head) after all pre-existing RCU
         read-side critical sections on all threads have completed.  This
@@ -106,7 +106,7 @@ The core RCU API is small:
         so that the reclaimer function can fetch the struct foo address
         and free it:
-            call_rcu1(&foo.rcu, foo_reclaim);
+            call_rcu(&foo.rcu, foo_reclaim);
             void foo_reclaim(struct rcu_head *rp)
@@ -117,15 +117,15 @@ The core RCU API is small:
         For the common case where the rcu_head member is the first of the
         struct, you can use the following macro.
-     void call_rcu(T *p,
-                   void (*func)(T *p),
-                   field-name);
+     void call_rcu_first_elem(T *p,
+                              void (*func)(T *p),
+                              field-name);
-        call_rcu1 is typically used through this macro, in the common case
+        call_rcu is typically used through this macro, in the common case
         where the "struct rcu_head" is the first field in the struct.  In
         the above case, one could have written simply:
-            call_rcu(foo_reclaim, g_free, rcu);
+            call_rcu_first_elem(foo_reclaim, g_free, rcu);
      typeof(*p) atomic_rcu_read(p);
@@ -196,10 +196,9 @@ DIFFERENCES WITH LINUX
 - atomic_rcu_read and atomic_rcu_set replace rcu_dereference and
   rcu_assign_pointer.  They take a _pointer_ to the variable being accessed.
-- call_rcu is a macro that has an extra argument (the name of the first
-  field in the struct, which must be a struct rcu_head), and expects the
+- call_rcu_first_elem is a macro that has an extra argument (the name of the
+  first field in the struct, which must be a struct rcu_head), and expects the
   type of the callback's argument to be the type of the first argument.
-  call_rcu1 is the same as Linux's call_rcu.
diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h
index 068a279..492d943 100644
--- a/include/qemu/rcu.h
+++ b/include/qemu/rcu.h
@@ -126,13 +126,13 @@ struct rcu_head {
     RCUCBFunc *func;
-extern void call_rcu1(struct rcu_head *head, RCUCBFunc *func);
+extern void call_rcu(struct rcu_head *head, RCUCBFunc *func);
 /* The operands of the minus operator must have the same type,
  * which must be the one that we specify in the cast.
-#define call_rcu(head, func, field)                                      \
-    call_rcu1(({                                                         \
+#define call_rcu_first_elem(head, func, field)                           \
+    call_rcu(({                                                          \
          char __attribute__((unused))                                    \
             offset_must_be_zero[-offsetof(typeof(*(head)), field)],      \
             func_type_invalid = (func) - (void (*)(typeof(head)))(func); \
diff --git a/memory.c b/memory.c
index 9b91243..dc5e4e9 100644
--- a/memory.c
+++ b/memory.c
@@ -755,7 +755,7 @@ static void address_space_update_topology(AddressSpace *as)
     /* Writes are protected by the BQL.  */
     atomic_rcu_set(&as->current_map, new_view);
-    call_rcu(old_view, flatview_unref, rcu);
+    call_rcu_first_elem(old_view, flatview_unref, rcu);
     /* Note that all the old MemoryRegions are still alive up to this
      * point.  This relieves most MemoryListeners from the need to
@@ -1983,7 +1983,7 @@ void address_space_destroy(AddressSpace *as)
      * entries that the guest should never use.  Wait for the old
      * values to expire before freeing the data.
-    call_rcu(as, do_address_space_destroy, rcu);
+    call_rcu_first_elem(as, do_address_space_destroy, rcu);
 bool io_mem_read(MemoryRegion *mr, hwaddr addr, uint64_t *pval, unsigned size)
diff --git a/util/rcu.c b/util/rcu.c
index c9c3e6e..309a6e4 100644
--- a/util/rcu.c
+++ b/util/rcu.c
@@ -253,7 +253,7 @@ static void *call_rcu_thread(void *opaque)
-void call_rcu1(struct rcu_head *node, void (*func)(struct rcu_head *node))
+void call_rcu(struct rcu_head *node, void (*func)(struct rcu_head *node))
     node->func = func;

reply via email to

[Prev in Thread] Current Thread [Next in Thread]