From: Ivan Ilchenko Date: Tue, 28 Sep 2021 11:29:12 +0000 (+0300) Subject: net/sfc: collect per queue stats in EF100 Tx X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=acc474488b0e30825c4dd119321b8e8787a95f96;p=dpdk.git 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 Signed-off-by: Ivan Ilchenko --- diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index 30bd109e8b..ace66d435c 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -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; diff --git a/drivers/net/sfc/sfc_dp_tx.h b/drivers/net/sfc/sfc_dp_tx.h index 777807985b..184711b887 100644 --- a/drivers/net/sfc/sfc_dp_tx.h +++ b/drivers/net/sfc/sfc_dp_tx.h @@ -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. diff --git a/drivers/net/sfc/sfc_ef100_tx.c b/drivers/net/sfc/sfc_ef100_tx.c index 522e9a0d34..fce82795cc 100644 --- a/drivers/net/sfc/sfc_ef100_tx.c +++ b/drivers/net/sfc/sfc_ef100_tx.c @@ -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 | diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 14e8ed550b..6c8fd3a249 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -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 diff --git a/drivers/net/sfc/sfc_sw_stats.c b/drivers/net/sfc/sfc_sw_stats.c index 8ffa923215..6b3a01b3c6 100644 --- a/drivers/net/sfc/sfc_sw_stats.c +++ b/drivers/net/sfc/sfc_sw_stats.c @@ -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;