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:
parent
395ffcb431
commit
acc474488b
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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 |
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user