armada: port and queue counters 39/41739/2
authorDamjan Marion <[email protected]>
Wed, 23 Oct 2024 13:35:49 +0000 (15:35 +0200)
committerDamjan Marion <[email protected]>
Wed, 23 Oct 2024 15:15:25 +0000 (17:15 +0200)
Type: improvement
Change-Id: I221253be147e99cd082911f28d088b64ca96eff5
Signed-off-by: Damjan Marion <[email protected]>
src/plugins/dev_armada/CMakeLists.txt
src/plugins/dev_armada/pp2/counters.c [new file with mode: 0644]
src/plugins/dev_armada/pp2/init.c
src/plugins/dev_armada/pp2/port.c
src/plugins/dev_armada/pp2/pp2.h

index f955a9b..e755e7b 100644 (file)
@@ -16,6 +16,7 @@ set(MUSDK_LINK_FLAGS "-Wl,--whole-archive,${MUSDK_LIB_DIR}/libmusdk.a,--no-whole
 add_vpp_plugin(dev_armada
   SOURCES
   plugin.c
+  pp2/counters.c
   pp2/init.c
   pp2/format.c
   pp2/port.c
diff --git a/src/plugins/dev_armada/pp2/counters.c b/src/plugins/dev_armada/pp2/counters.c
new file mode 100644 (file)
index 0000000..a041138
--- /dev/null
@@ -0,0 +1,241 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright (c) 2023 Cisco Systems, Inc.
+ */
+
+#include <vnet/vnet.h>
+#include <vnet/ethernet/ethernet.h>
+#include <vnet/dev/dev.h>
+#include <vnet/dev/counters.h>
+#include <vnet/dev/bus/platform.h>
+#include <vppinfra/ring.h>
+#include <dev_armada/musdk.h>
+#include <dev_armada/pp2/pp2.h>
+
+VLIB_REGISTER_LOG_CLASS (mvpp2_log, static) = {
+  .class_name = "armada",
+  .subclass_name = "pp2-counters",
+};
+
+typedef enum
+{
+  MVPP2_PORT_CTR_RX_BYTES,
+  MVPP2_PORT_CTR_RX_PACKETS,
+  MVPP2_PORT_CTR_RX_UCAST,
+  MVPP2_PORT_CTR_RX_ERRORS,
+  MVPP2_PORT_CTR_RX_FULLQ_DROPPED,
+  MVPP2_PORT_CTR_RX_BM_DROPPED,
+  MVPP2_PORT_CTR_RX_EARLY_DROPPED,
+  MVPP2_PORT_CTR_RX_FIFO_DROPPED,
+  MVPP2_PORT_CTR_RX_CLS_DROPPED,
+
+  MVPP2_PORT_CTR_TX_BYTES,
+  MVPP2_PORT_CTR_TX_PACKETS,
+  MVPP2_PORT_CTR_TX_UCAST,
+  MVPP2_PORT_CTR_TX_ERRORS,
+} mvpp2_port_counter_id_t;
+
+typedef enum
+{
+  MVPP2_RXQ_CTR_ENQ_DESC,
+  MVPP2_RXQ_CTR_DROP_FULLQ,
+  MVPP2_RXQ_CTR_DROP_EARLY,
+  MVPP2_RXQ_CTR_DROP_BM,
+} mvpp2_rxq_counter_id_t;
+
+typedef enum
+{
+  MVPP2_TXQ_CTR_ENQ_DESC,
+  MVPP2_TXQ_CTR_ENQ_DEC_TO_DDR,
+  MVPP2_TXQ_CTR_ENQ_BUF_TO_DDR,
+  MVPP2_TXQ_CTR_DEQ_DESC,
+} mvpp2_txq_counter_id_t;
+
+static vnet_dev_counter_t mvpp2_port_counters[] = {
+  VNET_DEV_CTR_RX_BYTES (MVPP2_PORT_CTR_RX_BYTES),
+  VNET_DEV_CTR_RX_PACKETS (MVPP2_PORT_CTR_RX_PACKETS),
+  VNET_DEV_CTR_RX_DROPS (MVPP2_PORT_CTR_RX_ERRORS),
+  VNET_DEV_CTR_VENDOR (MVPP2_PORT_CTR_RX_UCAST, RX, PACKETS, "unicast"),
+  VNET_DEV_CTR_VENDOR (MVPP2_PORT_CTR_RX_FULLQ_DROPPED, RX, PACKETS,
+                      "fullq dropped"),
+  VNET_DEV_CTR_VENDOR (MVPP2_PORT_CTR_RX_BM_DROPPED, RX, PACKETS,
+                      "bm dropped"),
+  VNET_DEV_CTR_VENDOR (MVPP2_PORT_CTR_RX_EARLY_DROPPED, RX, PACKETS,
+                      "early dropped"),
+  VNET_DEV_CTR_VENDOR (MVPP2_PORT_CTR_RX_FIFO_DROPPED, RX, PACKETS,
+                      "fifo dropped"),
+  VNET_DEV_CTR_VENDOR (MVPP2_PORT_CTR_RX_CLS_DROPPED, RX, PACKETS,
+                      "cls dropped"),
+
+  VNET_DEV_CTR_TX_BYTES (MVPP2_PORT_CTR_TX_BYTES),
+  VNET_DEV_CTR_TX_PACKETS (MVPP2_PORT_CTR_TX_PACKETS),
+  VNET_DEV_CTR_TX_DROPS (MVPP2_PORT_CTR_TX_ERRORS),
+  VNET_DEV_CTR_VENDOR (MVPP2_PORT_CTR_TX_UCAST, TX, PACKETS, "unicast"),
+};
+
+static vnet_dev_counter_t mvpp2_rxq_counters[] = {
+  VNET_DEV_CTR_VENDOR (MVPP2_RXQ_CTR_ENQ_DESC, RX, DESCRIPTORS, "enqueued"),
+  VNET_DEV_CTR_VENDOR (MVPP2_RXQ_CTR_DROP_FULLQ, RX, PACKETS, "drop fullQ"),
+  VNET_DEV_CTR_VENDOR (MVPP2_RXQ_CTR_DROP_EARLY, RX, PACKETS, "drop early"),
+  VNET_DEV_CTR_VENDOR (MVPP2_RXQ_CTR_DROP_BM, RX, PACKETS, "drop BM"),
+};
+
+static vnet_dev_counter_t mvpp2_txq_counters[] = {
+  VNET_DEV_CTR_VENDOR (MVPP2_TXQ_CTR_ENQ_DESC, TX, DESCRIPTORS, "enqueued"),
+  VNET_DEV_CTR_VENDOR (MVPP2_TXQ_CTR_DEQ_DESC, TX, PACKETS, "dequeued"),
+  VNET_DEV_CTR_VENDOR (MVPP2_TXQ_CTR_ENQ_BUF_TO_DDR, TX, BUFFERS,
+                      "enq to DDR"),
+  VNET_DEV_CTR_VENDOR (MVPP2_TXQ_CTR_ENQ_DEC_TO_DDR, TX, DESCRIPTORS,
+                      "enq to DDR"),
+};
+
+void
+mvpp2_port_add_counters (vlib_main_t *vm, vnet_dev_port_t *port)
+{
+  vnet_dev_port_add_counters (vm, port, mvpp2_port_counters,
+                             ARRAY_LEN (mvpp2_port_counters));
+
+  foreach_vnet_dev_port_rx_queue (q, port)
+    vnet_dev_rx_queue_add_counters (vm, q, mvpp2_rxq_counters,
+                                   ARRAY_LEN (mvpp2_rxq_counters));
+
+  foreach_vnet_dev_port_tx_queue (q, port)
+    vnet_dev_tx_queue_add_counters (vm, q, mvpp2_txq_counters,
+                                   ARRAY_LEN (mvpp2_txq_counters));
+}
+
+void
+mvpp2_port_clear_counters (vlib_main_t *vm, vnet_dev_port_t *port)
+{
+  mvpp2_port_t *mp = vnet_dev_get_port_data (port);
+  struct pp2_ppio_statistics stats;
+  pp2_ppio_get_statistics (mp->ppio, &stats, 1);
+}
+
+void
+mvpp2_rxq_clear_counters (vlib_main_t *vm, vnet_dev_rx_queue_t *q)
+{
+  mvpp2_port_t *mp = vnet_dev_get_port_data (q->port);
+  struct pp2_ppio_inq_statistics stats;
+  pp2_ppio_inq_get_statistics (mp->ppio, 0, q->queue_id, &stats, 1);
+}
+
+void
+mvpp2_txq_clear_counters (vlib_main_t *vm, vnet_dev_tx_queue_t *q)
+{
+  mvpp2_port_t *mp = vnet_dev_get_port_data (q->port);
+  struct pp2_ppio_inq_statistics stats;
+  pp2_ppio_inq_get_statistics (mp->ppio, 0, q->queue_id, &stats, 1);
+}
+
+vnet_dev_rv_t
+mvpp2_port_get_stats (vlib_main_t *vm, vnet_dev_port_t *port)
+{
+  mvpp2_port_t *mp = vnet_dev_get_port_data (port);
+  struct pp2_ppio_statistics stats;
+  pp2_ppio_get_statistics (mp->ppio, &stats, 0);
+
+  foreach_vnet_dev_counter (c, port->counter_main)
+    {
+      switch (c->user_data)
+       {
+       case MVPP2_PORT_CTR_RX_BYTES:
+         vnet_dev_counter_value_update (vm, c, stats.rx_bytes);
+         break;
+       case MVPP2_PORT_CTR_RX_PACKETS:
+         vnet_dev_counter_value_update (vm, c, stats.rx_packets);
+         break;
+       case MVPP2_PORT_CTR_RX_UCAST:
+         vnet_dev_counter_value_update (vm, c, stats.rx_unicast_packets);
+         break;
+       case MVPP2_PORT_CTR_RX_ERRORS:
+         vnet_dev_counter_value_update (vm, c, stats.rx_errors);
+         break;
+       case MVPP2_PORT_CTR_TX_BYTES:
+         vnet_dev_counter_value_update (vm, c, stats.tx_bytes);
+         break;
+       case MVPP2_PORT_CTR_TX_PACKETS:
+         vnet_dev_counter_value_update (vm, c, stats.tx_packets);
+         break;
+       case MVPP2_PORT_CTR_TX_UCAST:
+         vnet_dev_counter_value_update (vm, c, stats.tx_unicast_packets);
+         break;
+       case MVPP2_PORT_CTR_TX_ERRORS:
+         vnet_dev_counter_value_update (vm, c, stats.tx_errors);
+         break;
+       case MVPP2_PORT_CTR_RX_FULLQ_DROPPED:
+         vnet_dev_counter_value_update (vm, c, stats.rx_fullq_dropped);
+         break;
+       case MVPP2_PORT_CTR_RX_BM_DROPPED:
+         vnet_dev_counter_value_update (vm, c, stats.rx_bm_dropped);
+         break;
+       case MVPP2_PORT_CTR_RX_EARLY_DROPPED:
+         vnet_dev_counter_value_update (vm, c, stats.rx_early_dropped);
+         break;
+       case MVPP2_PORT_CTR_RX_FIFO_DROPPED:
+         vnet_dev_counter_value_update (vm, c, stats.rx_fifo_dropped);
+         break;
+       case MVPP2_PORT_CTR_RX_CLS_DROPPED:
+         vnet_dev_counter_value_update (vm, c, stats.rx_cls_dropped);
+         break;
+
+       default:
+         ASSERT (0);
+       }
+    }
+
+  foreach_vnet_dev_port_rx_queue (q, port)
+    {
+      struct pp2_ppio_inq_statistics stats;
+      pp2_ppio_inq_get_statistics (mp->ppio, 0, q->queue_id, &stats, 0);
+
+      foreach_vnet_dev_counter (c, q->counter_main)
+       {
+         switch (c->user_data)
+           {
+           case MVPP2_RXQ_CTR_ENQ_DESC:
+             vnet_dev_counter_value_update (vm, c, stats.enq_desc);
+             break;
+           case MVPP2_RXQ_CTR_DROP_BM:
+             vnet_dev_counter_value_update (vm, c, stats.drop_bm);
+             break;
+           case MVPP2_RXQ_CTR_DROP_EARLY:
+             vnet_dev_counter_value_update (vm, c, stats.drop_early);
+             break;
+           case MVPP2_RXQ_CTR_DROP_FULLQ:
+             vnet_dev_counter_value_update (vm, c, stats.drop_fullq);
+             break;
+           default:
+             ASSERT (0);
+           }
+       }
+    }
+
+  foreach_vnet_dev_port_tx_queue (q, port)
+    {
+      struct pp2_ppio_outq_statistics stats;
+      pp2_ppio_outq_get_statistics (mp->ppio, q->queue_id, &stats, 0);
+
+      foreach_vnet_dev_counter (c, q->counter_main)
+       {
+         switch (c->user_data)
+           {
+           case MVPP2_TXQ_CTR_ENQ_DESC:
+             vnet_dev_counter_value_update (vm, c, stats.enq_desc);
+             break;
+           case MVPP2_TXQ_CTR_DEQ_DESC:
+             vnet_dev_counter_value_update (vm, c, stats.deq_desc);
+             break;
+           case MVPP2_TXQ_CTR_ENQ_BUF_TO_DDR:
+             vnet_dev_counter_value_update (vm, c, stats.enq_buf_to_ddr);
+             break;
+           case MVPP2_TXQ_CTR_ENQ_DEC_TO_DDR:
+             vnet_dev_counter_value_update (vm, c, stats.enq_dec_to_ddr);
+             break;
+           default:
+             ASSERT (0);
+           }
+       }
+    }
+
+  return VNET_DEV_OK;
+}
index c0ae726..30fef34 100644 (file)
@@ -287,6 +287,7 @@ mvpp2_init (vlib_main_t *vm, vnet_dev_t *dev)
             .config_change = mvpp2_port_cfg_change,
             .config_change_validate = mvpp2_port_cfg_change_validate,
             .format_status = format_mvpp2_port_status,
+           .clear_counters = mvpp2_port_clear_counters,
           },
           .data_size = sizeof (mvpp2_port_t),
           .initial_data = &mvpp2_port,
@@ -302,6 +303,9 @@ mvpp2_init (vlib_main_t *vm, vnet_dev_t *dev)
         .max_size = 4096,
        .size_is_power_of_two = 1,
       },
+      .ops = {
+         .clear_counters = mvpp2_rxq_clear_counters,
+      },
     },
     .tx_queue = {
       .config = {
@@ -315,6 +319,7 @@ mvpp2_init (vlib_main_t *vm, vnet_dev_t *dev)
       .ops = {
          .alloc = mvpp2_txq_alloc,
          .free = mvpp2_txq_free,
+         .clear_counters = mvpp2_txq_clear_counters,
       },
         },
       };
index a42432c..4dbea1f 100644 (file)
@@ -75,6 +75,8 @@ mvpp2_port_init (vlib_main_t *vm, vnet_dev_port_t *port)
 
   log_debug (dev, "port %u %U", port->port_id, format_pp2_ppio_link_info, &li);
 
+  mvpp2_port_add_counters (vm, port);
+
 done:
   if (rv != VNET_DEV_OK)
     mvpp2_port_stop (vm, port);
@@ -145,12 +147,13 @@ mvpp2_port_poll (vlib_main_t *vm, vnet_dev_port_t *port)
        }
     }
 
-  if (changes.change.any == 0)
-    return;
-
-  mp->last_link_info = li;
+  if (changes.change.any)
+    {
+      mp->last_link_info = li;
+      vnet_dev_port_state_change (vm, port, changes);
+    }
 
-  vnet_dev_port_state_change (vm, port, changes);
+  mvpp2_port_get_stats (vm, port);
 }
 
 vnet_dev_rv_t
index 6b12dc7..7be3c72 100644 (file)
@@ -68,6 +68,13 @@ typedef struct
   vnet_dev_rx_queue_t *rxq;
 } mvpp2_rx_trace_t;
 
+/* counters.c */
+void mvpp2_port_add_counters (vlib_main_t *, vnet_dev_port_t *);
+void mvpp2_port_clear_counters (vlib_main_t *, vnet_dev_port_t *);
+void mvpp2_rxq_clear_counters (vlib_main_t *, vnet_dev_rx_queue_t *);
+void mvpp2_txq_clear_counters (vlib_main_t *, vnet_dev_tx_queue_t *);
+vnet_dev_rv_t mvpp2_port_get_stats (vlib_main_t *, vnet_dev_port_t *);
+
 /* format.c */
 format_function_t format_pp2_ppio_link_info;
 format_function_t format_mvpp2_port_status;