net/sfc: collect per queue stats in EF100 Tx

If Tx datapath collects per queue statistics, use these stats
to provide opackets and obytes in basic ethdev stats.

Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Signed-off-by: Ivan Ilchenko <ivan.ilchenko@oktetlabs.ru>
This commit is contained in:
Ivan Ilchenko 2021-09-28 14:29:12 +03:00 committed by Ferruh Yigit
parent 395ffcb431
commit acc474488b
5 changed files with 104 additions and 17 deletions

View File

@ -239,6 +239,8 @@ struct sfc_sw_stats {
/* Location of per-queue reset values for packets/bytes in reset_vals */
uint64_t *reset_rx_pkts;
uint64_t *reset_rx_bytes;
uint64_t *reset_tx_pkts;
uint64_t *reset_tx_bytes;
rte_spinlock_t queues_bitmap_lock;
void *queues_bitmap_mem;

View File

@ -168,6 +168,7 @@ struct sfc_dp_tx {
unsigned int features;
#define SFC_DP_TX_FEAT_MULTI_PROCESS 0x1
#define SFC_DP_TX_FEAT_STATS 0x2
/**
* Tx offload capabilities supported by the datapath on device
* level only if HW/FW supports it.

View File

@ -710,6 +710,9 @@ sfc_ef100_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
}
dma_desc_space -= (added - pkt_start);
sfc_pkts_bytes_add(&txq->dp.dpq.stats, 1,
rte_pktmbuf_pkt_len(*pktp));
}
if (likely(added != txq->added)) {
@ -940,7 +943,8 @@ struct sfc_dp_tx sfc_ef100_tx = {
.type = SFC_DP_TX,
.hw_fw_caps = SFC_DP_HW_FW_CAP_EF100,
},
.features = SFC_DP_TX_FEAT_MULTI_PROCESS,
.features = SFC_DP_TX_FEAT_MULTI_PROCESS |
SFC_DP_TX_FEAT_STATS,
.dev_offload_capa = 0,
.queue_offload_capa = DEV_TX_OFFLOAD_VLAN_INSERT |
DEV_TX_OFFLOAD_IPV4_CKSUM |

View File

@ -613,6 +613,33 @@ sfc_stats_get_dp_rx(struct sfc_adapter *sa, uint64_t *pkts, uint64_t *bytes)
*bytes = bytes_sum;
}
static void
sfc_stats_get_dp_tx(struct sfc_adapter *sa, uint64_t *pkts, uint64_t *bytes)
{
struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
uint64_t pkts_sum = 0;
uint64_t bytes_sum = 0;
unsigned int i;
for (i = 0; i < sas->ethdev_txq_count; ++i) {
struct sfc_txq_info *txq_info;
txq_info = sfc_txq_info_by_ethdev_qid(sas, i);
if (txq_info->state & SFC_TXQ_INITIALIZED) {
union sfc_pkts_bytes qstats;
sfc_pkts_bytes_get(&txq_info->dp->dpq.stats, &qstats);
pkts_sum += qstats.pkts -
sa->sw_stats.reset_tx_pkts[i];
bytes_sum += qstats.bytes -
sa->sw_stats.reset_tx_bytes[i];
}
}
*pkts = pkts_sum;
*bytes = bytes_sum;
}
/*
* Some statistics are computed as A - B where A and B each increase
* monotonically with some hardware counter(s) and the counters are read
@ -641,6 +668,7 @@ sfc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
{
const struct sfc_adapter_priv *sap = sfc_adapter_priv_by_eth_dev(dev);
bool have_dp_rx_stats = sap->dp_rx->features & SFC_DP_RX_FEAT_STATS;
bool have_dp_tx_stats = sap->dp_tx->features & SFC_DP_TX_FEAT_STATS;
struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
struct sfc_port *port = &sa->port;
uint64_t *mac_stats;
@ -650,6 +678,8 @@ sfc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
if (have_dp_rx_stats)
sfc_stats_get_dp_rx(sa, &stats->ipackets, &stats->ibytes);
if (have_dp_tx_stats)
sfc_stats_get_dp_tx(sa, &stats->opackets, &stats->obytes);
ret = sfc_port_update_mac_stats(sa, B_FALSE);
if (ret != 0)
@ -672,25 +702,27 @@ sfc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
/* CRC is included in these stats, but shouldn't be */
stats->ibytes -= stats->ipackets * RTE_ETHER_CRC_LEN;
}
stats->opackets =
mac_stats[EFX_MAC_VADAPTER_TX_UNICAST_PACKETS] +
mac_stats[EFX_MAC_VADAPTER_TX_MULTICAST_PACKETS] +
mac_stats[EFX_MAC_VADAPTER_TX_BROADCAST_PACKETS];
stats->obytes =
mac_stats[EFX_MAC_VADAPTER_TX_UNICAST_BYTES] +
mac_stats[EFX_MAC_VADAPTER_TX_MULTICAST_BYTES] +
mac_stats[EFX_MAC_VADAPTER_TX_BROADCAST_BYTES];
if (!have_dp_tx_stats) {
stats->opackets =
mac_stats[EFX_MAC_VADAPTER_TX_UNICAST_PACKETS] +
mac_stats[EFX_MAC_VADAPTER_TX_MULTICAST_PACKETS] +
mac_stats[EFX_MAC_VADAPTER_TX_BROADCAST_PACKETS];
stats->obytes =
mac_stats[EFX_MAC_VADAPTER_TX_UNICAST_BYTES] +
mac_stats[EFX_MAC_VADAPTER_TX_MULTICAST_BYTES] +
mac_stats[EFX_MAC_VADAPTER_TX_BROADCAST_BYTES];
/* CRC is included in these stats, but shouldn't be */
stats->obytes -= stats->opackets * RTE_ETHER_CRC_LEN;
}
stats->imissed = mac_stats[EFX_MAC_VADAPTER_RX_BAD_PACKETS];
stats->oerrors = mac_stats[EFX_MAC_VADAPTER_TX_BAD_PACKETS];
/* CRC is included in these stats, but shouldn't be */
stats->obytes -= stats->opackets * RTE_ETHER_CRC_LEN;
} else {
stats->opackets = mac_stats[EFX_MAC_TX_PKTS];
stats->obytes = mac_stats[EFX_MAC_TX_OCTETS];
/* CRC is included in these stats, but shouldn't be */
stats->obytes -= mac_stats[EFX_MAC_TX_PKTS] * RTE_ETHER_CRC_LEN;
if (!have_dp_tx_stats) {
stats->opackets = mac_stats[EFX_MAC_TX_PKTS];
stats->obytes = mac_stats[EFX_MAC_TX_OCTETS] -
mac_stats[EFX_MAC_TX_PKTS] * RTE_ETHER_CRC_LEN;
}
/*
* Take into account stats which are whenever supported

View File

@ -60,6 +60,29 @@ sfc_sw_stat_get_rx_good_pkts_bytes(struct sfc_adapter *sa, uint16_t qid,
}
}
static sfc_get_sw_stat_val_t sfc_sw_stat_get_tx_good_pkts_bytes;
static void
sfc_sw_stat_get_tx_good_pkts_bytes(struct sfc_adapter *sa, uint16_t qid,
uint64_t *values,
unsigned int values_count)
{
struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
struct sfc_txq_info *txq_info;
union sfc_pkts_bytes qstats;
RTE_SET_USED(values_count);
SFC_ASSERT(values_count == SFX_SW_STATS_GROUP_BASIC_MAX);
txq_info = sfc_txq_info_by_ethdev_qid(sas, qid);
if (txq_info->state & SFC_TXQ_INITIALIZED) {
sfc_pkts_bytes_get(&txq_info->dp->dpq.stats, &qstats);
values[SFC_SW_STATS_GROUP_BASIC_PKTS] = qstats.pkts;
values[SFC_SW_STATS_GROUP_BASIC_BYTES] = qstats.bytes;
} else {
values[SFC_SW_STATS_GROUP_BASIC_PKTS] = 0;
values[SFC_SW_STATS_GROUP_BASIC_BYTES] = 0;
}
}
static sfc_get_sw_stat_val_t sfc_get_sw_stat_val_rx_dbells;
static void
sfc_get_sw_stat_val_rx_dbells(struct sfc_adapter *sa, uint16_t qid,
@ -110,6 +133,19 @@ const struct sfc_sw_stat_descr sfc_sw_stats_descr[] = {
.get_val = NULL,
.provide_total = false,
},
/* Group of Tx packets/bytes stats */
{
.name = SFC_SW_STAT_GOOD_PACKETS,
.type = SFC_SW_STATS_TX,
.get_val = sfc_sw_stat_get_tx_good_pkts_bytes,
.provide_total = false,
},
{
.name = SFC_SW_STAT_GOOD_BYTES,
.type = SFC_SW_STATS_TX,
.get_val = NULL,
.provide_total = false,
},
/* End of basic stats */
{
.name = "dbells",
@ -641,6 +677,7 @@ sfc_sw_stats_fill_available_descr(struct sfc_adapter *sa)
{
const struct sfc_adapter_priv *sap = &sa->priv;
bool have_dp_rx_stats = sap->dp_rx->features & SFC_DP_RX_FEAT_STATS;
bool have_dp_tx_stats = sap->dp_tx->features & SFC_DP_TX_FEAT_STATS;
struct sfc_sw_stats *sw_stats = &sa->sw_stats;
const struct sfc_sw_stat_descr *sw_stat_descr;
unsigned int i;
@ -652,6 +689,10 @@ sfc_sw_stats_fill_available_descr(struct sfc_adapter *sa)
sw_stat_descr->type == SFC_SW_STATS_RX &&
sfc_sw_stats_is_packets_or_bytes(sw_stat_descr->name))
continue;
if (!have_dp_tx_stats &&
sw_stat_descr->type == SFC_SW_STATS_TX &&
sfc_sw_stats_is_packets_or_bytes(sw_stat_descr->name))
continue;
sw_stats->supp[sw_stats->supp_count].descr = sw_stat_descr;
sw_stats->supp_count++;
}
@ -678,6 +719,13 @@ sfc_sw_stats_set_reset_basic_stats(struct sfc_adapter *sa)
sa->sw_stats.reset_rx_bytes = reset_vals;
break;
case SFC_SW_STATS_TX:
if (strcmp(sw_stat->name,
SFC_SW_STAT_GOOD_PACKETS) == 0)
sa->sw_stats.reset_tx_pkts = reset_vals;
else if (strcmp(sw_stat->name,
SFC_SW_STAT_GOOD_BYTES) == 0)
sa->sw_stats.reset_tx_bytes = reset_vals;
break;
default:
SFC_GENERIC_LOG(ERR, "Unknown SW stat type");
return -EINVAL;