revalidator_purge() iterates and modifies umap->cmap. This should
not happen in quiescent state, because cmap implementation based
on rcu protected variables. Let's move the thread to active state
before purging to avoid possible wrong memory accesses.

CC: Joe Stringer <[email protected]>
Fixes: 9fce0584a643 ("revalidator: Use 'cmap' for storing ukeys.")
Signed-off-by: Ilya Maximets <[email protected]>
---
 ofproto/ofproto-dpif-upcall.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index 28172cb05..02ae2aabe 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -511,6 +511,7 @@ udpif_stop_threads(struct udpif *udpif)
 {
     if (udpif && (udpif->n_handlers != 0 || udpif->n_revalidators != 0)) {
         size_t i;
+        bool quiescent = ovsrcu_is_quiescent();
 
         latch_set(&udpif->exit_latch);
 
@@ -524,6 +525,10 @@ udpif_stop_threads(struct udpif *udpif)
             xpthread_join(udpif->revalidators[i].thread, NULL);
         }
 
+        if (quiescent) {
+            ovsrcu_quiesce_end();
+        }
+
         dpif_disable_upcall(udpif->dpif);
 
         for (i = 0; i < udpif->n_revalidators; i++) {
@@ -534,6 +539,10 @@ udpif_stop_threads(struct udpif *udpif)
             revalidator_purge(revalidator);
         }
 
+        if (quiescent) {
+            ovsrcu_quiesce_start();
+        }
+
         latch_poll(&udpif->exit_latch);
 
         ovs_barrier_destroy(&udpif->reval_barrier);
-- 
2.17.1

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

Reply via email to