rcu_barrier will block the current thread until all the postponed
rcu job has been finished. it's like the OVS's version of
the kernel rcu_barrier()

Signed-off-by: Peng He <[email protected]>
---
 lib/ovs-rcu.c | 31 +++++++++++++++++++++++++++++++
 lib/ovs-rcu.h |  4 ++++
 2 files changed, 35 insertions(+)

diff --git a/lib/ovs-rcu.c b/lib/ovs-rcu.c
index 1866bd308..2bf6b6eae 100644
--- a/lib/ovs-rcu.c
+++ b/lib/ovs-rcu.c
@@ -444,3 +444,34 @@ ovsrcu_init_module(void)
         ovsthread_once_done(&once);
     }
 }
+
+static void
+ovsrcu_barrier_func(void *seq_)
+{
+    struct seq *seq = (struct seq*)seq_;
+    seq_change(seq);
+}
+
+bool
+ovsrcu_barrier(struct seq *seq, long long int timeout)
+{
+    /* first let all threads flush their cbset */
+    ovsrcu_synchronize();
+
+    /* then register a new cbset, ensure this cbset
+     * is at the tail of global listi
+     */
+    uint64_t seqno = seq_read(seq);
+    ovsrcu_postpone__(ovsrcu_barrier_func, (void*)seq);
+    long long int now = time_msec();
+    long long int deadline = now + timeout;
+
+    do {
+        seq_wait(seq, seqno);
+        poll_timer_wait_until(deadline);
+        poll_block();
+        now = time_msec(); /* update now */
+    } while (seqno == seq_read(seq) && now < deadline);
+
+    return !(seqno == seq_read(seq));
+}
diff --git a/lib/ovs-rcu.h b/lib/ovs-rcu.h
index ecc4c9201..c9c044e06 100644
--- a/lib/ovs-rcu.h
+++ b/lib/ovs-rcu.h
@@ -159,6 +159,7 @@
 
 #include "compiler.h"
 #include "ovs-atomic.h"
+#include "seq.h"
 
 #if __GNUC__
 #define OVSRCU_TYPE(TYPE) struct { ATOMIC(TYPE) p; }
@@ -310,4 +311,7 @@ void ovsrcu_synchronize(void);
 
 void ovsrcu_exit(void);
 
+bool ovsrcu_barrier(struct seq *seq, long long int timeout);
+
+
 #endif /* ovs-rcu.h */
-- 
2.25.1

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to