[ovs-dev] [PATCH v2] netdev: use acquire-release semantics for change_seq in netdev

Yanqin Wei Yanqin.Wei at arm.com
Tue Nov 26 07:35:23 UTC 2019


"rxq_enabled" of netdev is writen in the vhost thread and read by pmd
thread once it observes 'change_seq' is updated. This patch is to keep
order on aarch64 or other weak memory model CPU to ensure 'rxq_enabled' is
observed before 'change_seq'.

Reviewed-by: Gavin Hu <Gavin.Hu at arm.com>
Signed-off-by: Yanqin Wei <Yanqin.Wei at arm.com>
---
 lib/netdev-provider.h | 13 +++++++++----
 lib/netdev.c          |  7 ++++++-
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/lib/netdev-provider.h b/lib/netdev-provider.h
index 1e5a40c89..f109c4e66 100644
--- a/lib/netdev-provider.h
+++ b/lib/netdev-provider.h
@@ -63,7 +63,7 @@ struct netdev {
      *
      * Minimally, the sequence number is required to change whenever
      * 'netdev''s flags, features, ethernet address, or carrier changes. */
-    uint64_t change_seq;
+    atomic_uint64_t change_seq;
 
     /* A netdev provider might be unable to change some of the device's
      * parameter (n_rxq, mtu) when the device is in use.  In this case
@@ -91,12 +91,17 @@ struct netdev {
 static inline void
 netdev_change_seq_changed(const struct netdev *netdev_)
 {
+    uint64_t change_seq;
     struct netdev *netdev = CONST_CAST(struct netdev *, netdev_);
     seq_change(connectivity_seq_get());
-    netdev->change_seq++;
-    if (!netdev->change_seq) {
-        netdev->change_seq++;
+
+    atomic_read_relaxed(&netdev->change_seq, &change_seq);
+    change_seq++;
+    if (OVS_UNLIKELY(!change_seq)) {
+        change_seq++;
     }
+    atomic_store_explicit(&netdev->change_seq, change_seq,
+                          memory_order_release);
 }
 
 static inline void
diff --git a/lib/netdev.c b/lib/netdev.c
index af8f8560d..405c98c68 100644
--- a/lib/netdev.c
+++ b/lib/netdev.c
@@ -2039,7 +2039,12 @@ restore_all_flags(void *aux OVS_UNUSED)
 uint64_t
 netdev_get_change_seq(const struct netdev *netdev)
 {
-    return netdev->change_seq;
+    uint64_t change_seq;
+
+    atomic_read_explicit(&CONST_CAST(struct netdev *, netdev)->change_seq,
+                        &change_seq, memory_order_acquire);
+
+    return change_seq;
 }
 
 #ifndef _WIN32
-- 
2.17.1



More information about the dev mailing list