netdev_vport_inc_tx() and netdev_vport_inc_rx() are called from every
revalidator thread simultaneously. Switching to use atomic counters
avoid expensive mutex operations.

Signed-off-by: Clemens Famulla-Conrad <[email protected]>
---
 lib/netdev-vport-private.h |  7 ++++++-
 lib/netdev-vport.c         | 29 ++++++++++++++---------------
 2 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/lib/netdev-vport-private.h b/lib/netdev-vport-private.h
index 586231057..671c23c28 100644
--- a/lib/netdev-vport-private.h
+++ b/lib/netdev-vport-private.h
@@ -33,11 +33,16 @@ struct netdev_vport {
     /* Sequence number for outgoing GRE packets. */
     atomic_count gre_seqno;
 
+    /* packet/byte counters updated lock-free */
+    atomic_uint64_t rx_packets;
+    atomic_uint64_t rx_bytes;
+    atomic_uint64_t tx_packets;
+    atomic_uint64_t tx_bytes;
+
     /* Protects all members below. */
     struct ovs_mutex mutex;
 
     struct eth_addr etheraddr;
-    struct netdev_stats stats;
 
     /* Tunnels. */
     char egress_iface[IFNAMSIZ];
diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
index d11269d00..e6fd03744 100644
--- a/lib/netdev-vport.c
+++ b/lib/netdev-vport.c
@@ -203,6 +203,10 @@ netdev_vport_construct(struct netdev *netdev_)
 
     ovs_mutex_init(&dev->mutex);
     atomic_count_init(&dev->gre_seqno, 0);
+    atomic_init(&dev->rx_packets, 0);
+    atomic_init(&dev->rx_bytes, 0);
+    atomic_init(&dev->tx_packets, 0);
+    atomic_init(&dev->tx_bytes, 0);
     eth_addr_random(&dev->etheraddr);
 
     if (name && dpif_port && (strlen(name) > strlen(dpif_port) + 1) &&
@@ -1119,11 +1123,10 @@ netdev_vport_inc_rx(const struct netdev *netdev,
 {
     if (is_vport_class(netdev_get_class(netdev))) {
         struct netdev_vport *dev = netdev_vport_cast(netdev);
+        uint64_t orig;
 
-        ovs_mutex_lock(&dev->mutex);
-        dev->stats.rx_packets += stats->n_packets;
-        dev->stats.rx_bytes += stats->n_bytes;
-        ovs_mutex_unlock(&dev->mutex);
+        atomic_add_relaxed(&dev->rx_packets, stats->n_packets, &orig);
+        atomic_add_relaxed(&dev->rx_bytes, stats->n_bytes, &orig);
     }
 }
 
@@ -1133,11 +1136,10 @@ netdev_vport_inc_tx(const struct netdev *netdev,
 {
     if (is_vport_class(netdev_get_class(netdev))) {
         struct netdev_vport *dev = netdev_vport_cast(netdev);
+        uint64_t orig;
 
-        ovs_mutex_lock(&dev->mutex);
-        dev->stats.tx_packets += stats->n_packets;
-        dev->stats.tx_bytes += stats->n_bytes;
-        ovs_mutex_unlock(&dev->mutex);
+        atomic_add_relaxed(&dev->tx_packets, stats->n_packets, &orig);
+        atomic_add_relaxed(&dev->tx_bytes, stats->n_bytes, &orig);
     }
 }
 
@@ -1196,13 +1198,10 @@ netdev_vport_get_stats(const struct netdev *netdev, 
struct netdev_stats *stats)
 {
     struct netdev_vport *dev = netdev_vport_cast(netdev);
 
-    ovs_mutex_lock(&dev->mutex);
-    /* Passing only collected counters */
-    stats->tx_packets = dev->stats.tx_packets;
-    stats->tx_bytes = dev->stats.tx_bytes;
-    stats->rx_packets = dev->stats.rx_packets;
-    stats->rx_bytes = dev->stats.rx_bytes;
-    ovs_mutex_unlock(&dev->mutex);
+    atomic_read_relaxed(&dev->rx_packets, &stats->rx_packets);
+    atomic_read_relaxed(&dev->rx_bytes, &stats->rx_bytes);
+    atomic_read_relaxed(&dev->tx_packets, &stats->tx_packets);
+    atomic_read_relaxed(&dev->tx_bytes, &stats->tx_bytes);
 
     return 0;
 }
-- 
2.51.0

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to