diff options
author | Jarno Rajahalme <jarno@ovn.org> | 2017-01-18 15:26:03 -0800 |
---|---|---|
committer | Jarno Rajahalme <jarno@ovn.org> | 2017-01-18 15:26:03 -0800 |
commit | f9cf9e574ec6c3aa99b4845bab3ef7b9173c661e (patch) | |
tree | f99b00c7fd561fbcce68372462487a6e6355c120 /ofproto | |
parent | 9cdef506692c433dae4cc3bc332436554851c752 (diff) | |
download | openvswitch-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.c | 18 |
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; } |