]> git.proxmox.com Git - mirror_ovs.git/commitdiff
netdev: use acquire-release semantics for change_seq in netdev
authorYanqin Wei <Yanqin.Wei@arm.com>
Tue, 26 Nov 2019 07:35:23 +0000 (15:35 +0800)
committerBen Pfaff <blp@ovn.org>
Mon, 2 Dec 2019 22:48:14 +0000 (14:48 -0800)
"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@arm.com>
Signed-off-by: Yanqin Wei <Yanqin.Wei@arm.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
lib/netdev-provider.h
lib/netdev.c

index 1e5a40c898fc4a11f0241e98697ec9b22ded7374..f109c4e66f0d177fc41015da2d8a16a63df9c4c9 100644 (file)
@@ -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
index af8f8560d3bd03154f635ee70b54760a79e31013..405c98c687fad82f66218173eb34633fe0d32000 100644 (file)
@@ -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