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
