[ovs-dev] [PATCH] ofproto-dpif: Use acquire/release barriers with 'tables_version'.

Jarno Rajahalme jarno at ovn.org
Thu Jan 12 18:17:32 UTC 2017


Use memory_order_release when updating the tables version number to
make sure no memory accesses before the atomic_store (possibly
relating to setting up the new version) are reordered to take place
after the atomic_store, which makes the new version available to other
threads.

Correspondingly, use memory_order_acquire when reading the
current tables_version to make sure no later memory accesses (possibly
relating to the current version) are reordered to take place before
the atomic_read to ensure that those memory accesses can not relate to
an older version than returned by the atomic_read.

Suggested-by: Daniele Di Proietto <ddiproietto at vmware.com>
Signed-off-by: Jarno Rajahalme <jarno at ovn.org>
---
 ofproto/ofproto-dpif.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 3b274ee..0e6842d 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -1548,7 +1548,15 @@ set_tables_version(struct ofproto *ofproto_, ovs_version_t version)
 {
     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
 
-    atomic_store_relaxed(&ofproto->tables_version, version);
+    /* Use memory_order_release to signify that any prior memory accesses can
+     * not be reordered to happen after this atomic store.  This makes sure the
+     * new version is properly set up when the readers can read this 'version'
+     * value. */
+    atomic_store_explicit(&ofproto->tables_version, version,
+                          memory_order_release);
+    /* 'need_revalidate' can be reordered to happen before the atomic_store
+     * above, but it does not matter as this variable is not accessed by other
+     * threads. */
     ofproto->backer->need_revalidate = REV_FLOW_TABLE;
 }
 
@@ -3723,8 +3731,12 @@ ofproto_dpif_get_tables_version(struct ofproto_dpif *ofproto)
 {
     ovs_version_t version;
 
-    atomic_read_relaxed(&ofproto->tables_version, &version);
-
+    /* Use memory_order_acquire to signify that any following memory accesses
+     * can not be reordered to happen before this atomic read.  This makes sure
+     * all following reads relate to this or a newer version, but never to an
+     * older version. */
+    atomic_read_explicit(&ofproto->tables_version, &version,
+                         memory_order_acquire);
     return version;
 }
 
-- 
2.1.4



More information about the dev mailing list