summaryrefslogtreecommitdiff
path: root/ofproto
diff options
context:
space:
mode:
authorJarno Rajahalme <jarno@ovn.org>2017-01-18 15:26:03 -0800
committerJarno Rajahalme <jarno@ovn.org>2017-01-18 15:26:03 -0800
commitf9cf9e574ec6c3aa99b4845bab3ef7b9173c661e (patch)
treef99b00c7fd561fbcce68372462487a6e6355c120 /ofproto
parent9cdef506692c433dae4cc3bc332436554851c752 (diff)
downloadopenvswitch-f9cf9e574ec6c3aa99b4845bab3ef7b9173c661e.tar.gz
ofproto-dpif: Use acquire/release barriers with 'tables_version'.
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@vmware.com> Fixes: 621b8064b7 ("ofproto: Infra for table versioning.") Signed-off-by: Jarno Rajahalme <jarno@ovn.org> Acked-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'ofproto')
-rw-r--r--ofproto/ofproto-dpif.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 72e91b941..d7bde69b1 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;
}