New stats for vhost ports are rx_bytes, tx_bytes, multicast, rx_errors and
rx_length_errors. New stats for PMD ports are rx_dropped, rx_length_errors,
rx_crc_errors and rx_missed_errors. DPDK imissed packets are now classified
as dropped instead of errors.

Signed-off-by: Timo Puha <timox.p...@intel.com>
---
 lib/netdev-dpdk.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 76 insertions(+), 10 deletions(-)

diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index 8b843db..9fe625d 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -884,6 +884,35 @@ is_vhost_running(struct virtio_net *dev)
     return (dev != NULL && (dev->flags & VIRTIO_DEV_RUNNING));
 }
 
+static inline void
+netdev_dpdk_vhost_update_rx_counters(struct netdev_stats *stats,
+                                     struct dp_packet **packets, int count)
+{
+    int i;
+    struct dp_packet *packet;
+
+    stats->rx_packets += count;
+    for (i = 0; i < count; i++) {
+        packet = packets[i];
+
+        if (OVS_UNLIKELY(dp_packet_size(packet) < ETH_HEADER_LEN)) {
+            /* This only protects the following multicast counting from
+             * too short packets, but it does not stop the packet from
+             * further processing. */
+            stats->rx_errors++;
+            stats->rx_length_errors++;
+            continue;
+        }
+
+        struct eth_header *eh = (struct eth_header *) dp_packet_data(packet);
+        if (OVS_UNLIKELY(eth_addr_is_multicast(eh->eth_dst))) {
+            stats->multicast++;
+        }
+
+        stats->rx_bytes += dp_packet_size(packet);
+    }
+}
+
 /*
  * The receive path for the vhost port is the TX path out from guest.
  */
@@ -911,7 +940,7 @@ netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq_,
     }
 
     rte_spinlock_lock(&vhost_dev->stats_lock);
-    vhost_dev->stats.rx_packets += (uint64_t)nb_rx;
+    netdev_dpdk_vhost_update_rx_counters(&vhost_dev->stats, packets, nb_rx);
     rte_spinlock_unlock(&vhost_dev->stats_lock);
 
     *c = (int) nb_rx;
@@ -948,6 +977,23 @@ netdev_dpdk_rxq_recv(struct netdev_rxq *rxq_, struct 
dp_packet **packets,
     return 0;
 }
 
+static inline void
+netdev_dpdk_vhost_update_tx_counters(struct netdev_stats *stats,
+                                     struct dp_packet **packets,
+                                     int attempted,
+                                     int dropped)
+{
+    int i;
+    int sent = attempted - dropped;
+
+    stats->tx_packets += sent;
+    stats->tx_dropped += dropped;
+
+    for (i = 0; i < sent; i++) {
+        stats->tx_bytes += dp_packet_size(packets[i]);
+    }
+}
+
 static void
 __netdev_dpdk_vhost_send(struct netdev *netdev, struct dp_packet **pkts,
                          int cnt, bool may_steal)
@@ -1005,8 +1051,8 @@ __netdev_dpdk_vhost_send(struct netdev *netdev, struct 
dp_packet **pkts,
     rte_spinlock_unlock(&vhost_dev->vhost_tx_lock);
 
     rte_spinlock_lock(&vhost_dev->stats_lock);
-    vhost_dev->stats.tx_packets += (total_pkts - cnt);
-    vhost_dev->stats.tx_dropped += cnt;
+    netdev_dpdk_vhost_update_tx_counters(&vhost_dev->stats, pkts, total_pkts,
+                                         cnt);
     rte_spinlock_unlock(&vhost_dev->stats_lock);
 
 out:
@@ -1309,14 +1355,10 @@ netdev_dpdk_vhost_get_stats(const struct netdev *netdev,
     ovs_mutex_lock(&dev->mutex);
     memset(stats, 0, sizeof(*stats));
     /* Unsupported Stats */
-    stats->rx_errors = UINT64_MAX;
-    stats->tx_errors = UINT64_MAX;
-    stats->multicast = UINT64_MAX;
     stats->collisions = UINT64_MAX;
     stats->rx_crc_errors = UINT64_MAX;
     stats->rx_fifo_errors = UINT64_MAX;
     stats->rx_frame_errors = UINT64_MAX;
-    stats->rx_length_errors = UINT64_MAX;
     stats->rx_missed_errors = UINT64_MAX;
     stats->rx_over_errors = UINT64_MAX;
     stats->tx_aborted_errors = UINT64_MAX;
@@ -1325,16 +1367,20 @@ netdev_dpdk_vhost_get_stats(const struct netdev *netdev,
     stats->tx_fifo_errors = UINT64_MAX;
     stats->tx_heartbeat_errors = UINT64_MAX;
     stats->tx_window_errors = UINT64_MAX;
-    stats->rx_bytes += UINT64_MAX;
     stats->rx_dropped += UINT64_MAX;
-    stats->tx_bytes += UINT64_MAX;
 
     rte_spinlock_lock(&dev->stats_lock);
     /* Supported Stats */
     stats->rx_packets += dev->stats.rx_packets;
     stats->tx_packets += dev->stats.tx_packets;
     stats->tx_dropped += dev->stats.tx_dropped;
+    stats->multicast = dev->stats.multicast;
+    stats->rx_bytes = dev->stats.rx_bytes;
+    stats->tx_bytes = dev->stats.tx_bytes;
+    stats->rx_errors = dev->stats.rx_errors;
+    stats->rx_length_errors = dev->stats.rx_length_errors;
     rte_spinlock_unlock(&dev->stats_lock);
+
     ovs_mutex_unlock(&dev->mutex);
 
     return 0;
@@ -1357,13 +1403,33 @@ netdev_dpdk_get_stats(const struct netdev *netdev, 
struct netdev_stats *stats)
     stats->tx_packets = rte_stats.opackets;
     stats->rx_bytes = rte_stats.ibytes;
     stats->tx_bytes = rte_stats.obytes;
-    stats->rx_errors = rte_stats.ierrors;
+    /* DPDK counts imissed as errors, but count them here as dropped instead */
+    stats->rx_errors = rte_stats.ierrors - rte_stats.imissed;
     stats->tx_errors = rte_stats.oerrors;
     stats->multicast = rte_stats.imcasts;
 
     rte_spinlock_lock(&dev->stats_lock);
     stats->tx_dropped = dev->stats.tx_dropped;
     rte_spinlock_unlock(&dev->stats_lock);
+
+    /* These are the available DPDK counters for packets not received due to
+     * local resource constraints in DPDK and NIC respectively. */
+    stats->rx_dropped = rte_stats.rx_nombuf + rte_stats.imissed;
+    stats->collisions = UINT64_MAX;
+
+    stats->rx_length_errors = rte_stats.ibadlen;
+    stats->rx_over_errors = UINT64_MAX;
+    stats->rx_crc_errors = rte_stats.ibadcrc;
+    stats->rx_frame_errors = UINT64_MAX;
+    stats->rx_fifo_errors = UINT64_MAX;
+    stats->rx_missed_errors = rte_stats.imissed;
+
+    stats->tx_aborted_errors = UINT64_MAX;
+    stats->tx_carrier_errors = UINT64_MAX;
+    stats->tx_fifo_errors = UINT64_MAX;
+    stats->tx_heartbeat_errors = UINT64_MAX;
+    stats->tx_window_errors = UINT64_MAX;
+
     ovs_mutex_unlock(&dev->mutex);
 
     return 0;
-- 
1.8.3.1

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to