octeon: add counters support for port and queue

Type: feature

Change-Id: I5d52d78a93c7d0a12b9cee16fe7ebabdc2b19f0a
Signed-off-by: Monendra Singh Kushwaha <kmonendra@marvell.com>
This commit is contained in:
Monendra Singh Kushwaha
2024-05-16 14:15:40 +05:30
committed by Damjan Marion
parent afd03ffff5
commit b26b2bcd43
4 changed files with 322 additions and 0 deletions

View File

@@ -35,6 +35,7 @@ add_vpp_plugin(dev_octeon
rx_node.c
tx_node.c
flow.c
counter.c
MULTIARCH_SOURCES
rx_node.c

View File

@@ -0,0 +1,296 @@
/*
* Copyright (c) 2024 Marvell.
* SPDX-License-Identifier: Apache-2.0
* https://spdx.org/licenses/Apache-2.0.html
*/
#include <vnet/vnet.h>
#include <vnet/dev/dev.h>
#include <vnet/dev/pci.h>
#include <vnet/dev/counters.h>
#include <dev_octeon/octeon.h>
#include <dev_octeon/common.h>
VLIB_REGISTER_LOG_CLASS (oct_log, static) = {
.class_name = "oct",
.subclass_name = "counters",
};
typedef enum
{
OCT_PORT_CTR_RX_BYTES,
OCT_PORT_CTR_TX_BYTES,
OCT_PORT_CTR_RX_PACKETS,
OCT_PORT_CTR_TX_PACKETS,
OCT_PORT_CTR_RX_DROPS,
OCT_PORT_CTR_TX_DROPS,
OCT_PORT_CTR_RX_DROP_BYTES,
OCT_PORT_CTR_RX_UCAST,
OCT_PORT_CTR_TX_UCAST,
OCT_PORT_CTR_RX_MCAST,
OCT_PORT_CTR_TX_MCAST,
OCT_PORT_CTR_RX_BCAST,
OCT_PORT_CTR_TX_BCAST,
OCT_PORT_CTR_RX_FCS,
OCT_PORT_CTR_RX_ERR,
OCT_PORT_CTR_RX_DROP_MCAST,
OCT_PORT_CTR_RX_DROP_BCAST,
OCT_PORT_CTR_RX_DROP_L3_MCAST,
OCT_PORT_CTR_RX_DROP_L3_BCAST,
} oct_port_counter_id_t;
vnet_dev_counter_t oct_port_counters[] = {
VNET_DEV_CTR_RX_BYTES (OCT_PORT_CTR_RX_BYTES),
VNET_DEV_CTR_RX_PACKETS (OCT_PORT_CTR_RX_PACKETS),
VNET_DEV_CTR_RX_DROPS (OCT_PORT_CTR_RX_DROPS),
VNET_DEV_CTR_VENDOR (OCT_PORT_CTR_RX_DROP_BYTES, RX, BYTES, "drop bytes"),
VNET_DEV_CTR_VENDOR (OCT_PORT_CTR_RX_UCAST, RX, PACKETS, "unicast"),
VNET_DEV_CTR_VENDOR (OCT_PORT_CTR_RX_MCAST, RX, PACKETS, "multicast"),
VNET_DEV_CTR_VENDOR (OCT_PORT_CTR_RX_BCAST, RX, PACKETS, "broadcast"),
VNET_DEV_CTR_VENDOR (OCT_PORT_CTR_RX_FCS, RX, PACKETS, "fcs"),
VNET_DEV_CTR_VENDOR (OCT_PORT_CTR_RX_ERR, RX, PACKETS, "error"),
VNET_DEV_CTR_VENDOR (OCT_PORT_CTR_RX_DROP_MCAST, RX, PACKETS,
"drop multicast"),
VNET_DEV_CTR_VENDOR (OCT_PORT_CTR_RX_DROP_BCAST, RX, PACKETS,
"drop broadcast"),
VNET_DEV_CTR_VENDOR (OCT_PORT_CTR_RX_DROP_L3_MCAST, RX, PACKETS,
"drop L3 multicast"),
VNET_DEV_CTR_VENDOR (OCT_PORT_CTR_RX_DROP_L3_BCAST, RX, PACKETS,
"drop L3 broadcast"),
VNET_DEV_CTR_TX_BYTES (OCT_PORT_CTR_TX_BYTES),
VNET_DEV_CTR_TX_PACKETS (OCT_PORT_CTR_TX_PACKETS),
VNET_DEV_CTR_TX_DROPS (OCT_PORT_CTR_TX_DROPS),
VNET_DEV_CTR_VENDOR (OCT_PORT_CTR_TX_UCAST, TX, PACKETS, "unicast"),
VNET_DEV_CTR_VENDOR (OCT_PORT_CTR_TX_MCAST, TX, PACKETS, "multicast"),
VNET_DEV_CTR_VENDOR (OCT_PORT_CTR_TX_BCAST, TX, PACKETS, "broadcast"),
};
typedef enum
{
OCT_RXQ_CTR_BYTES,
OCT_RXQ_CTR_PKTS,
OCT_RXQ_CTR_DROPS,
OCT_RXQ_CTR_DROP_BYTES,
OCT_RXQ_CTR_ERR,
} oct_rxq_counter_id_t;
vnet_dev_counter_t oct_rxq_counters[] = {
VNET_DEV_CTR_RX_BYTES (OCT_RXQ_CTR_BYTES),
VNET_DEV_CTR_RX_PACKETS (OCT_RXQ_CTR_PKTS),
VNET_DEV_CTR_RX_DROPS (OCT_RXQ_CTR_DROPS),
VNET_DEV_CTR_VENDOR (OCT_RXQ_CTR_DROP_BYTES, RX, BYTES, "drop bytes"),
VNET_DEV_CTR_VENDOR (OCT_RXQ_CTR_ERR, RX, PACKETS, "error"),
};
typedef enum
{
OCT_TXQ_CTR_BYTES,
OCT_TXQ_CTR_PKTS,
OCT_TXQ_CTR_DROPS,
OCT_TXQ_CTR_DROP_BYTES,
} oct_txq_counter_id_t;
vnet_dev_counter_t oct_txq_counters[] = {
VNET_DEV_CTR_TX_BYTES (OCT_TXQ_CTR_BYTES),
VNET_DEV_CTR_TX_PACKETS (OCT_TXQ_CTR_PKTS),
VNET_DEV_CTR_TX_DROPS (OCT_TXQ_CTR_DROPS),
VNET_DEV_CTR_VENDOR (OCT_TXQ_CTR_DROP_BYTES, TX, BYTES, "drop bytes"),
};
static vnet_dev_rv_t
oct_roc_err (vnet_dev_t *dev, int rv, char *fmt, ...)
{
u8 *s = 0;
va_list va;
va_start (va, fmt);
s = va_format (s, fmt, &va);
va_end (va);
log_err (dev, "%v - ROC error %s (%d)", s, roc_error_msg_get (rv), rv);
vec_free (s);
return VNET_DEV_ERR_INTERNAL;
}
void
oct_port_add_counters (vlib_main_t *vm, vnet_dev_port_t *port)
{
vnet_dev_port_add_counters (vm, port, oct_port_counters,
ARRAY_LEN (oct_port_counters));
foreach_vnet_dev_port_rx_queue (rxq, port)
{
vnet_dev_rx_queue_add_counters (vm, rxq, oct_rxq_counters,
ARRAY_LEN (oct_rxq_counters));
}
foreach_vnet_dev_port_tx_queue (txq, port)
{
vnet_dev_tx_queue_add_counters (vm, txq, oct_txq_counters,
ARRAY_LEN (oct_txq_counters));
}
}
vnet_dev_rv_t
oct_port_get_stats (vlib_main_t *vm, vnet_dev_port_t *port)
{
vnet_dev_t *dev = port->dev;
oct_device_t *cd = vnet_dev_get_data (dev);
struct roc_nix *nix = cd->nix;
int rrv;
struct roc_nix_stats stats;
if ((rrv = roc_nix_stats_get (nix, &stats)))
return oct_roc_err (dev, rrv, "roc_nix_stats_get() failed");
foreach_vnet_dev_counter (c, port->counter_main)
{
switch (c->user_data)
{
case OCT_PORT_CTR_RX_BYTES:
vnet_dev_counter_value_update (vm, c, stats.rx_octs);
break;
case OCT_PORT_CTR_TX_BYTES:
vnet_dev_counter_value_update (vm, c, stats.tx_octs);
break;
case OCT_PORT_CTR_RX_PACKETS:
vnet_dev_counter_value_update (
vm, c, stats.rx_ucast + stats.rx_bcast + stats.rx_mcast);
break;
case OCT_PORT_CTR_TX_PACKETS:
vnet_dev_counter_value_update (
vm, c, stats.tx_ucast + stats.tx_bcast + stats.tx_mcast);
break;
case OCT_PORT_CTR_RX_DROPS:
vnet_dev_counter_value_update (vm, c, stats.rx_drop);
break;
case OCT_PORT_CTR_TX_DROPS:
vnet_dev_counter_value_update (vm, c, stats.tx_drop);
break;
case OCT_PORT_CTR_RX_DROP_BYTES:
vnet_dev_counter_value_update (vm, c, stats.rx_drop_octs);
break;
case OCT_PORT_CTR_RX_UCAST:
vnet_dev_counter_value_update (vm, c, stats.rx_ucast);
break;
case OCT_PORT_CTR_TX_UCAST:
vnet_dev_counter_value_update (vm, c, stats.tx_ucast);
break;
case OCT_PORT_CTR_RX_MCAST:
vnet_dev_counter_value_update (vm, c, stats.rx_mcast);
break;
case OCT_PORT_CTR_TX_MCAST:
vnet_dev_counter_value_update (vm, c, stats.tx_mcast);
break;
case OCT_PORT_CTR_RX_BCAST:
vnet_dev_counter_value_update (vm, c, stats.rx_bcast);
break;
case OCT_PORT_CTR_TX_BCAST:
vnet_dev_counter_value_update (vm, c, stats.tx_bcast);
break;
case OCT_PORT_CTR_RX_FCS:
vnet_dev_counter_value_update (vm, c, stats.rx_fcs);
break;
case OCT_PORT_CTR_RX_ERR:
vnet_dev_counter_value_update (vm, c, stats.rx_err);
break;
case OCT_PORT_CTR_RX_DROP_MCAST:
vnet_dev_counter_value_update (vm, c, stats.rx_drop_mcast);
break;
case OCT_PORT_CTR_RX_DROP_BCAST:
vnet_dev_counter_value_update (vm, c, stats.rx_drop_bcast);
break;
case OCT_PORT_CTR_RX_DROP_L3_MCAST:
vnet_dev_counter_value_update (vm, c, stats.rx_drop_l3_mcast);
break;
case OCT_PORT_CTR_RX_DROP_L3_BCAST:
vnet_dev_counter_value_update (vm, c, stats.rx_drop_l3_bcast);
break;
default:
ASSERT (0);
}
}
return VNET_DEV_OK;
}
vnet_dev_rv_t
oct_rxq_get_stats (vlib_main_t *vm, vnet_dev_port_t *port,
vnet_dev_rx_queue_t *rxq)
{
oct_rxq_t *crq = vnet_dev_get_rx_queue_data (rxq);
struct roc_nix_stats_queue qstats;
vnet_dev_t *dev = port->dev;
oct_device_t *cd = vnet_dev_get_data (dev);
struct roc_nix *nix = cd->nix;
int rrv;
if ((rrv = roc_nix_stats_queue_get (nix, crq->rq.qid, 1, &qstats)))
return oct_roc_err (dev, rrv, "roc_nix_stats_queue_get() failed");
foreach_vnet_dev_counter (c, rxq->counter_main)
{
switch (c->user_data)
{
case OCT_RXQ_CTR_BYTES:
vnet_dev_counter_value_update (vm, c, qstats.rx_octs);
break;
case OCT_RXQ_CTR_PKTS:
vnet_dev_counter_value_update (vm, c, qstats.rx_pkts);
break;
case OCT_RXQ_CTR_DROPS:
vnet_dev_counter_value_update (vm, c, qstats.rx_drop_pkts);
break;
case OCT_RXQ_CTR_DROP_BYTES:
vnet_dev_counter_value_update (vm, c, qstats.rx_drop_octs);
break;
case OCT_RXQ_CTR_ERR:
vnet_dev_counter_value_update (vm, c, qstats.rx_error_pkts);
break;
default:
ASSERT (0);
}
}
return VNET_DEV_OK;
}
vnet_dev_rv_t
oct_txq_get_stats (vlib_main_t *vm, vnet_dev_port_t *port,
vnet_dev_tx_queue_t *txq)
{
oct_txq_t *ctq = vnet_dev_get_tx_queue_data (txq);
struct roc_nix_stats_queue qstats;
vnet_dev_t *dev = port->dev;
oct_device_t *cd = vnet_dev_get_data (dev);
struct roc_nix *nix = cd->nix;
int rrv;
if ((rrv = roc_nix_stats_queue_get (nix, ctq->sq.qid, 0, &qstats)))
return oct_roc_err (dev, rrv, "roc_nix_stats_queue_get() failed");
foreach_vnet_dev_counter (c, txq->counter_main)
{
switch (c->user_data)
{
case OCT_TXQ_CTR_BYTES:
vnet_dev_counter_value_update (vm, c, qstats.tx_octs);
break;
case OCT_TXQ_CTR_PKTS:
vnet_dev_counter_value_update (vm, c, qstats.tx_pkts);
break;
case OCT_TXQ_CTR_DROPS:
vnet_dev_counter_value_update (vm, c, qstats.tx_drop_pkts);
break;
case OCT_TXQ_CTR_DROP_BYTES:
vnet_dev_counter_value_update (vm, c, qstats.tx_drop_octs);
break;
default:
ASSERT (0);
}
}
return VNET_DEV_OK;
}

View File

@@ -141,6 +141,14 @@ vnet_dev_rv_t oct_flow_validate_params (vlib_main_t *, vnet_dev_port_t *,
vnet_dev_rv_t oct_flow_query (vlib_main_t *, vnet_dev_port_t *, u32, uword,
u64 *);
/* counter.c */
void oct_port_add_counters (vlib_main_t *, vnet_dev_port_t *);
vnet_dev_rv_t oct_port_get_stats (vlib_main_t *, vnet_dev_port_t *);
vnet_dev_rv_t oct_rxq_get_stats (vlib_main_t *, vnet_dev_port_t *,
vnet_dev_rx_queue_t *);
vnet_dev_rv_t oct_txq_get_stats (vlib_main_t *, vnet_dev_port_t *,
vnet_dev_tx_queue_t *);
#define log_debug(dev, f, ...) \
vlib_log (VLIB_LOG_LEVEL_DEBUG, oct_log.class, "%U: " f, \
format_vnet_dev_addr, (dev), ##__VA_ARGS__)

View File

@@ -124,6 +124,8 @@ oct_port_init (vlib_main_t *vm, vnet_dev_port_t *port)
return rv;
}
oct_port_add_counters (vm, port);
return VNET_DEV_OK;
}
@@ -172,6 +174,21 @@ oct_port_poll (vlib_main_t *vm, vnet_dev_port_t *port)
vnet_dev_port_state_changes_t changes = {};
int rrv;
if (oct_port_get_stats (vm, port))
return;
foreach_vnet_dev_port_rx_queue (q, port)
{
if (oct_rxq_get_stats (vm, port, q))
return;
}
foreach_vnet_dev_port_tx_queue (q, port)
{
if (oct_txq_get_stats (vm, port, q))
return;
}
if (roc_nix_is_lbk (nix))
{
link_info.status = 1;