From: Yanling Song <songyl@ramaxel.com>
To: <dev@dpdk.org>
Cc: <songyl@ramaxel.com>, <yanling.song@linux.dev>,
<yanggan@ramaxel.com>, <ferruh.yigit@intel.com>
Subject: [PATCH v1 22/25] net/spnic: net/spnic: support xstats statistics
Date: Sat, 18 Dec 2021 10:51:49 +0800 [thread overview]
Message-ID: <332ed0b3b8dedbf236fbeb63a40813f6d8357e58.1639636621.git.songyl@ramaxel.com> (raw)
In-Reply-To: <cover.1639636621.git.songyl@ramaxel.com>
This commit implements DFX statistics of
physical port, function, Rx queues and Tx queues,
which includes MAC statistic, unicast/multicast/broadcast
packets statistic, rx_mbuf, tx_busy and etc.
Signed-off-by: Yanling Song <songyl@ramaxel.com>
---
drivers/net/spnic/base/spnic_nic_cfg.c | 118 ++++++
drivers/net/spnic/base/spnic_nic_cfg.h | 206 +++++++++++
drivers/net/spnic/spnic_ethdev.c | 474 +++++++++++++++++++++++++
3 files changed, 798 insertions(+)
diff --git a/drivers/net/spnic/base/spnic_nic_cfg.c b/drivers/net/spnic/base/spnic_nic_cfg.c
index 24336a2096..ce77b306db 100644
--- a/drivers/net/spnic/base/spnic_nic_cfg.c
+++ b/drivers/net/spnic/base/spnic_nic_cfg.c
@@ -493,6 +493,124 @@ int spnic_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
return spnic_cfg_hw_pause(hwdev, SPNIC_CMD_OP_GET, nic_pause);
}
+int spnic_get_vport_stats(void *hwdev, struct spnic_vport_stats *stats)
+{
+ struct spnic_port_stats_info stats_info;
+ struct spnic_cmd_vport_stats vport_stats;
+ u16 out_size = sizeof(vport_stats);
+ int err;
+
+ if (!hwdev || !stats)
+ return -EINVAL;
+
+ memset(&stats_info, 0, sizeof(stats_info));
+ memset(&vport_stats, 0, sizeof(vport_stats));
+
+ stats_info.func_id = spnic_global_func_id(hwdev);
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_GET_VPORT_STAT,
+ &stats_info, sizeof(stats_info),
+ &vport_stats, &out_size);
+ if (err || !out_size || vport_stats.msg_head.status) {
+ PMD_DRV_LOG(ERR, "Get function stats failed, err: %d, status: 0x%x, out size: 0x%x",
+ err, vport_stats.msg_head.status, out_size);
+ return -EIO;
+ }
+
+ memcpy(stats, &vport_stats.stats, sizeof(*stats));
+
+ return 0;
+}
+
+int spnic_get_phy_port_stats(void *hwdev, struct mag_phy_port_stats *stats)
+{
+ struct mag_cmd_get_port_stat *port_stats = NULL;
+ struct mag_cmd_port_stats_info stats_info;
+ u16 out_size = sizeof(*port_stats);
+ int err;
+
+ port_stats = rte_zmalloc("port_stats", sizeof(*port_stats), 0);
+ if (!port_stats)
+ return -ENOMEM;
+
+ memset(&stats_info, 0, sizeof(stats_info));
+ stats_info.port_id = spnic_physical_port_id(hwdev);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_PORT_STAT,
+ &stats_info, sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ PMD_DRV_LOG(ERR,
+ "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+
+ memcpy(stats, &port_stats->counter, sizeof(*stats));
+
+out:
+ rte_free(port_stats);
+
+ return err;
+}
+
+int spnic_clear_vport_stats(void *hwdev)
+{
+ struct spnic_cmd_clear_vport_stats clear_vport_stats;
+ u16 out_size = sizeof(clear_vport_stats);
+ int err;
+
+ if (!hwdev) {
+ PMD_DRV_LOG(ERR, "Hwdev is NULL");
+ return -EINVAL;
+ }
+
+ memset(&clear_vport_stats, 0, sizeof(clear_vport_stats));
+ clear_vport_stats.func_id = spnic_global_func_id(hwdev);
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, SPNIC_CMD_CLEAN_VPORT_STAT,
+ &clear_vport_stats,
+ sizeof(clear_vport_stats),
+ &clear_vport_stats, &out_size);
+ if (err || !out_size || clear_vport_stats.msg_head.status) {
+ PMD_DRV_LOG(ERR, "Clear vport stats failed, err: %d, status: 0x%x, out size: 0x%x",
+ err, clear_vport_stats.msg_head.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int spnic_clear_phy_port_stats(void *hwdev)
+{
+ struct mag_cmd_clr_port_stat *port_stats = NULL;
+ u16 out_size = sizeof(*port_stats);
+ int err;
+
+ port_stats = rte_zmalloc("port_stats", sizeof(*port_stats), 0);
+ if (!port_stats)
+ return -ENOMEM;
+
+ port_stats->port_id = spnic_physical_port_id(hwdev);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_PORT_STAT,
+ &port_stats, sizeof(port_stats),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ PMD_DRV_LOG(ERR,
+ "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+
+out:
+ rte_free(port_stats);
+
+ return err;
+}
+
static int spnic_set_function_table(void *hwdev, u32 cfg_bitmap,
struct spnic_func_tbl_cfg *cfg)
{
diff --git a/drivers/net/spnic/base/spnic_nic_cfg.h b/drivers/net/spnic/base/spnic_nic_cfg.h
index 2cdaada2ea..e5e4ffea4b 100644
--- a/drivers/net/spnic/base/spnic_nic_cfg.h
+++ b/drivers/net/spnic/base/spnic_nic_cfg.h
@@ -259,6 +259,160 @@ struct spnic_cmd_clear_qp_resource {
u16 rsvd1;
};
+struct spnic_port_stats_info {
+ struct mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct spnic_vport_stats {
+ u64 tx_unicast_pkts_vport;
+ u64 tx_unicast_bytes_vport;
+ u64 tx_multicast_pkts_vport;
+ u64 tx_multicast_bytes_vport;
+ u64 tx_broadcast_pkts_vport;
+ u64 tx_broadcast_bytes_vport;
+
+ u64 rx_unicast_pkts_vport;
+ u64 rx_unicast_bytes_vport;
+ u64 rx_multicast_pkts_vport;
+ u64 rx_multicast_bytes_vport;
+ u64 rx_broadcast_pkts_vport;
+ u64 rx_broadcast_bytes_vport;
+
+ u64 tx_discard_vport;
+ u64 rx_discard_vport;
+ u64 tx_err_vport;
+ u64 rx_err_vport;
+};
+
+struct spnic_cmd_vport_stats {
+ struct mgmt_msg_head msg_head;
+
+ u32 stats_size;
+ u32 rsvd1;
+ struct spnic_vport_stats stats;
+ u64 rsvd2[6];
+};
+
+struct mag_phy_port_stats {
+ u64 mac_tx_fragment_pkt_num;
+ u64 mac_tx_undersize_pkt_num;
+ u64 mac_tx_undermin_pkt_num;
+ u64 mac_tx_64_oct_pkt_num;
+ u64 mac_tx_65_127_oct_pkt_num;
+ u64 mac_tx_128_255_oct_pkt_num;
+ u64 mac_tx_256_511_oct_pkt_num;
+ u64 mac_tx_512_1023_oct_pkt_num;
+ u64 mac_tx_1024_1518_oct_pkt_num;
+ u64 mac_tx_1519_2047_oct_pkt_num;
+ u64 mac_tx_2048_4095_oct_pkt_num;
+ u64 mac_tx_4096_8191_oct_pkt_num;
+ u64 mac_tx_8192_9216_oct_pkt_num;
+ u64 mac_tx_9217_12287_oct_pkt_num;
+ u64 mac_tx_12288_16383_oct_pkt_num;
+ u64 mac_tx_1519_max_bad_pkt_num;
+ u64 mac_tx_1519_max_good_pkt_num;
+ u64 mac_tx_oversize_pkt_num;
+ u64 mac_tx_jabber_pkt_num;
+ u64 mac_tx_bad_pkt_num;
+ u64 mac_tx_bad_oct_num;
+ u64 mac_tx_good_pkt_num;
+ u64 mac_tx_good_oct_num;
+ u64 mac_tx_total_pkt_num;
+ u64 mac_tx_total_oct_num;
+ u64 mac_tx_uni_pkt_num;
+ u64 mac_tx_multi_pkt_num;
+ u64 mac_tx_broad_pkt_num;
+ u64 mac_tx_pause_num;
+ u64 mac_tx_pfc_pkt_num;
+ u64 mac_tx_pfc_pri0_pkt_num;
+ u64 mac_tx_pfc_pri1_pkt_num;
+ u64 mac_tx_pfc_pri2_pkt_num;
+ u64 mac_tx_pfc_pri3_pkt_num;
+ u64 mac_tx_pfc_pri4_pkt_num;
+ u64 mac_tx_pfc_pri5_pkt_num;
+ u64 mac_tx_pfc_pri6_pkt_num;
+ u64 mac_tx_pfc_pri7_pkt_num;
+ u64 mac_tx_control_pkt_num;
+ u64 mac_tx_err_all_pkt_num;
+ u64 mac_tx_from_app_good_pkt_num;
+ u64 mac_tx_from_app_bad_pkt_num;
+
+ u64 mac_rx_fragment_pkt_num;
+ u64 mac_rx_undersize_pkt_num;
+ u64 mac_rx_undermin_pkt_num;
+ u64 mac_rx_64_oct_pkt_num;
+ u64 mac_rx_65_127_oct_pkt_num;
+ u64 mac_rx_128_255_oct_pkt_num;
+ u64 mac_rx_256_511_oct_pkt_num;
+ u64 mac_rx_512_1023_oct_pkt_num;
+ u64 mac_rx_1024_1518_oct_pkt_num;
+ u64 mac_rx_1519_2047_oct_pkt_num;
+ u64 mac_rx_2048_4095_oct_pkt_num;
+ u64 mac_rx_4096_8191_oct_pkt_num;
+ u64 mac_rx_8192_9216_oct_pkt_num;
+ u64 mac_rx_9217_12287_oct_pkt_num;
+ u64 mac_rx_12288_16383_oct_pkt_num;
+ u64 mac_rx_1519_max_bad_pkt_num;
+ u64 mac_rx_1519_max_good_pkt_num;
+ u64 mac_rx_oversize_pkt_num;
+ u64 mac_rx_jabber_pkt_num;
+ u64 mac_rx_bad_pkt_num;
+ u64 mac_rx_bad_oct_num;
+ u64 mac_rx_good_pkt_num;
+ u64 mac_rx_good_oct_num;
+ u64 mac_rx_total_pkt_num;
+ u64 mac_rx_total_oct_num;
+ u64 mac_rx_uni_pkt_num;
+ u64 mac_rx_multi_pkt_num;
+ u64 mac_rx_broad_pkt_num;
+ u64 mac_rx_pause_num;
+ u64 mac_rx_pfc_pkt_num;
+ u64 mac_rx_pfc_pri0_pkt_num;
+ u64 mac_rx_pfc_pri1_pkt_num;
+ u64 mac_rx_pfc_pri2_pkt_num;
+ u64 mac_rx_pfc_pri3_pkt_num;
+ u64 mac_rx_pfc_pri4_pkt_num;
+ u64 mac_rx_pfc_pri5_pkt_num;
+ u64 mac_rx_pfc_pri6_pkt_num;
+ u64 mac_rx_pfc_pri7_pkt_num;
+ u64 mac_rx_control_pkt_num;
+ u64 mac_rx_sym_err_pkt_num;
+ u64 mac_rx_fcs_err_pkt_num;
+ u64 mac_rx_send_app_good_pkt_num;
+ u64 mac_rx_send_app_bad_pkt_num;
+ u64 mac_rx_unfilter_pkt_num;
+};
+
+struct mag_cmd_port_stats_info {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd0[3];
+};
+
+struct mag_cmd_get_port_stat {
+ struct mgmt_msg_head head;
+
+ struct mag_phy_port_stats counter;
+ u64 rsvd1[15];
+};
+
+struct mag_cmd_clr_port_stat {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd0[3];
+};
+
+struct spnic_cmd_clear_vport_stats {
+ struct mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd;
+};
enum spnic_func_tbl_cfg_bitmap {
FUNC_CFG_INIT,
@@ -586,6 +740,58 @@ int spnic_set_pause_info(void *hwdev, struct nic_pause_config nic_pause);
*/
int spnic_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause);
+/**
+ * Get function stats
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[out] stats
+ * Function stats
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int spnic_get_vport_stats(void *hwdev, struct spnic_vport_stats *stats);
+
+/**
+ * Get port stats
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[out] stats
+ * Port stats
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int spnic_get_phy_port_stats(void *hwdev, struct mag_phy_port_stats *stats);
+
+/**
+ * Clear function stats
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[out] stats
+ * Function stats
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int spnic_clear_vport_stats(void *hwdev);
+
+/**
+ * Clear port stats
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[out] stats
+ * Port stats
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int spnic_clear_phy_port_stats(void *hwdev);
+
/**
* Init nic hwdev
*
diff --git a/drivers/net/spnic/spnic_ethdev.c b/drivers/net/spnic/spnic_ethdev.c
index 2cd68e0178..4de86fd08a 100644
--- a/drivers/net/spnic/spnic_ethdev.c
+++ b/drivers/net/spnic/spnic_ethdev.c
@@ -66,6 +66,171 @@ enum spnic_rx_mod {
#define SPNIC_DEFAULT_RX_MODE (SPNIC_RX_MODE_UC | SPNIC_RX_MODE_MC | \
SPNIC_RX_MODE_BC)
+struct spnic_xstats_name_off {
+ char name[RTE_ETH_XSTATS_NAME_SIZE];
+ u32 offset;
+};
+
+#define SPNIC_FUNC_STAT(_stat_item) { \
+ .name = #_stat_item, \
+ .offset = offsetof(struct spnic_vport_stats, _stat_item) \
+}
+
+#define SPNIC_PORT_STAT(_stat_item) { \
+ .name = #_stat_item, \
+ .offset = offsetof(struct mag_phy_port_stats, _stat_item) \
+}
+
+static const struct spnic_xstats_name_off spnic_vport_stats_strings[] = {
+ SPNIC_FUNC_STAT(tx_unicast_pkts_vport),
+ SPNIC_FUNC_STAT(tx_unicast_bytes_vport),
+ SPNIC_FUNC_STAT(tx_multicast_pkts_vport),
+ SPNIC_FUNC_STAT(tx_multicast_bytes_vport),
+ SPNIC_FUNC_STAT(tx_broadcast_pkts_vport),
+ SPNIC_FUNC_STAT(tx_broadcast_bytes_vport),
+
+ SPNIC_FUNC_STAT(rx_unicast_pkts_vport),
+ SPNIC_FUNC_STAT(rx_unicast_bytes_vport),
+ SPNIC_FUNC_STAT(rx_multicast_pkts_vport),
+ SPNIC_FUNC_STAT(rx_multicast_bytes_vport),
+ SPNIC_FUNC_STAT(rx_broadcast_pkts_vport),
+ SPNIC_FUNC_STAT(rx_broadcast_bytes_vport),
+
+ SPNIC_FUNC_STAT(tx_discard_vport),
+ SPNIC_FUNC_STAT(rx_discard_vport),
+ SPNIC_FUNC_STAT(tx_err_vport),
+ SPNIC_FUNC_STAT(rx_err_vport),
+};
+
+#define SPNIC_VPORT_XSTATS_NUM (sizeof(spnic_vport_stats_strings) / \
+ sizeof(spnic_vport_stats_strings[0]))
+
+static const struct spnic_xstats_name_off spnic_phyport_stats_strings[] = {
+ SPNIC_PORT_STAT(mac_tx_fragment_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_undersize_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_undermin_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_64_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_65_127_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_128_255_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_256_511_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_512_1023_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_1024_1518_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_1519_2047_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_2048_4095_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_4096_8191_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_8192_9216_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_9217_12287_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_12288_16383_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_1519_max_bad_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_1519_max_good_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_oversize_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_jabber_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_bad_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_bad_oct_num),
+ SPNIC_PORT_STAT(mac_tx_good_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_good_oct_num),
+ SPNIC_PORT_STAT(mac_tx_total_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_total_oct_num),
+ SPNIC_PORT_STAT(mac_tx_uni_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_multi_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_broad_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_pause_num),
+ SPNIC_PORT_STAT(mac_tx_pfc_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_pfc_pri0_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_pfc_pri1_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_pfc_pri2_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_pfc_pri3_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_pfc_pri4_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_pfc_pri5_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_pfc_pri6_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_pfc_pri7_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_control_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_err_all_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_from_app_good_pkt_num),
+ SPNIC_PORT_STAT(mac_tx_from_app_bad_pkt_num),
+
+ SPNIC_PORT_STAT(mac_rx_fragment_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_undersize_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_undermin_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_64_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_65_127_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_128_255_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_256_511_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_512_1023_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_1024_1518_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_1519_2047_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_2048_4095_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_4096_8191_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_8192_9216_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_9217_12287_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_12288_16383_oct_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_1519_max_bad_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_1519_max_good_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_oversize_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_jabber_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_bad_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_bad_oct_num),
+ SPNIC_PORT_STAT(mac_rx_good_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_good_oct_num),
+ SPNIC_PORT_STAT(mac_rx_total_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_total_oct_num),
+ SPNIC_PORT_STAT(mac_rx_uni_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_multi_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_broad_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_pause_num),
+ SPNIC_PORT_STAT(mac_rx_pfc_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_pfc_pri0_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_pfc_pri1_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_pfc_pri2_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_pfc_pri3_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_pfc_pri4_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_pfc_pri5_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_pfc_pri6_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_pfc_pri7_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_control_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_sym_err_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_fcs_err_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_send_app_good_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_send_app_bad_pkt_num),
+ SPNIC_PORT_STAT(mac_rx_unfilter_pkt_num)
+};
+
+#define SPNIC_PHYPORT_XSTATS_NUM (sizeof(spnic_phyport_stats_strings) / \
+ sizeof(spnic_phyport_stats_strings[0]))
+
+static const struct spnic_xstats_name_off spnic_rxq_stats_strings[] = {
+ {"rx_nombuf", offsetof(struct spnic_rxq_stats, rx_nombuf)},
+ {"burst_pkt", offsetof(struct spnic_rxq_stats, burst_pkts)},
+};
+
+#define SPNIC_RXQ_XSTATS_NUM (sizeof(spnic_rxq_stats_strings) / \
+ sizeof(spnic_rxq_stats_strings[0]))
+
+static const struct spnic_xstats_name_off spnic_txq_stats_strings[] = {
+ {"tx_busy", offsetof(struct spnic_txq_stats, tx_busy)},
+ {"offload_errors", offsetof(struct spnic_txq_stats, off_errs)},
+ {"burst_pkts", offsetof(struct spnic_txq_stats, burst_pkts)},
+ {"sge_len0", offsetof(struct spnic_txq_stats, sge_len0)},
+ {"mbuf_null", offsetof(struct spnic_txq_stats, mbuf_null)},
+};
+
+#define SPNIC_TXQ_XSTATS_NUM (sizeof(spnic_txq_stats_strings) / \
+ sizeof(spnic_txq_stats_strings[0]))
+
+static int spnic_xstats_calc_num(struct spnic_nic_dev *nic_dev)
+{
+ if (SPNIC_IS_VF(nic_dev->hwdev)) {
+ return (SPNIC_VPORT_XSTATS_NUM +
+ SPNIC_RXQ_XSTATS_NUM * nic_dev->num_rqs +
+ SPNIC_TXQ_XSTATS_NUM * nic_dev->num_sqs);
+ } else {
+ return (SPNIC_VPORT_XSTATS_NUM +
+ SPNIC_PHYPORT_XSTATS_NUM +
+ SPNIC_RXQ_XSTATS_NUM * nic_dev->num_rqs +
+ SPNIC_TXQ_XSTATS_NUM * nic_dev->num_sqs);
+ }
+}
+
#define SPNIC_MAX_QUEUE_DEPTH 16384
#define SPNIC_MIN_QUEUE_DEPTH 128
#define SPNIC_TXD_ALIGN 1
@@ -1846,6 +2011,305 @@ static int spnic_rss_reta_update(struct rte_eth_dev *dev,
return err;
}
+/**
+ * Get device generic statistics.
+ *
+ * @param[in] dev
+ * Pointer to ethernet device structure.
+ * @param[out] stats
+ * Stats structure output buffer.
+ *
+ * @retval zero: Success
+ * @retval non-zero: Failure
+ */
+static int spnic_dev_stats_get(struct rte_eth_dev *dev,
+ struct rte_eth_stats *stats)
+{
+ struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
+ struct spnic_vport_stats vport_stats;
+ struct spnic_rxq *rxq = NULL;
+ struct spnic_txq *txq = NULL;
+ int i, err, q_num;
+ u64 rx_discards_pmd = 0;
+
+ err = spnic_get_vport_stats(nic_dev->hwdev, &vport_stats);
+ if (err) {
+ PMD_DRV_LOG(ERR, "Get vport stats from fw failed, nic_dev: %s",
+ nic_dev->dev_name);
+ return err;
+ }
+
+ dev->data->rx_mbuf_alloc_failed = 0;
+
+ /* Rx queue stats */
+ q_num = (nic_dev->num_rqs < RTE_ETHDEV_QUEUE_STAT_CNTRS) ?
+ nic_dev->num_rqs : RTE_ETHDEV_QUEUE_STAT_CNTRS;
+ for (i = 0; i < q_num; i++) {
+ rxq = nic_dev->rxqs[i];
+ stats->q_ipackets[i] = rxq->rxq_stats.packets;
+ stats->q_ibytes[i] = rxq->rxq_stats.bytes;
+ stats->q_errors[i] = rxq->rxq_stats.dropped;
+
+ stats->ierrors += rxq->rxq_stats.errors;
+ rx_discards_pmd += rxq->rxq_stats.dropped;
+ dev->data->rx_mbuf_alloc_failed += rxq->rxq_stats.rx_nombuf;
+ }
+
+ /* Tx queue stats */
+ q_num = (nic_dev->num_sqs < RTE_ETHDEV_QUEUE_STAT_CNTRS) ?
+ nic_dev->num_sqs : RTE_ETHDEV_QUEUE_STAT_CNTRS;
+ for (i = 0; i < q_num; i++) {
+ txq = nic_dev->txqs[i];
+ stats->q_opackets[i] = txq->txq_stats.packets;
+ stats->q_obytes[i] = txq->txq_stats.bytes;
+ stats->oerrors += (txq->txq_stats.tx_busy +
+ txq->txq_stats.off_errs);
+ }
+
+ /* Vport stats */
+ stats->oerrors += vport_stats.tx_discard_vport;
+
+ stats->imissed = vport_stats.rx_discard_vport + rx_discards_pmd;
+
+ stats->ipackets = (vport_stats.rx_unicast_pkts_vport +
+ vport_stats.rx_multicast_pkts_vport +
+ vport_stats.rx_broadcast_pkts_vport -
+ rx_discards_pmd);
+
+ stats->opackets = (vport_stats.tx_unicast_pkts_vport +
+ vport_stats.tx_multicast_pkts_vport +
+ vport_stats.tx_broadcast_pkts_vport);
+
+ stats->ibytes = (vport_stats.rx_unicast_bytes_vport +
+ vport_stats.rx_multicast_bytes_vport +
+ vport_stats.rx_broadcast_bytes_vport);
+
+ stats->obytes = (vport_stats.tx_unicast_bytes_vport +
+ vport_stats.tx_multicast_bytes_vport +
+ vport_stats.tx_broadcast_bytes_vport);
+ return 0;
+}
+
+/**
+ * Clear device generic statistics.
+ *
+ * @param[in] dev
+ * Pointer to ethernet device structure.
+ *
+ * @retval zero: Success
+ * @retval non-zero: Failure
+ */
+static int spnic_dev_stats_reset(struct rte_eth_dev *dev)
+{
+ struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
+ struct spnic_rxq *rxq = NULL;
+ struct spnic_txq *txq = NULL;
+ int qid;
+ int err;
+
+ err = spnic_clear_vport_stats(nic_dev->hwdev);
+ if (err)
+ return err;
+
+ for (qid = 0; qid < nic_dev->num_rqs; qid++) {
+ rxq = nic_dev->rxqs[qid];
+ memset(&rxq->rxq_stats, 0, sizeof(struct spnic_rxq_stats));
+ }
+
+ for (qid = 0; qid < nic_dev->num_sqs; qid++) {
+ txq = nic_dev->txqs[qid];
+ memset(&txq->txq_stats, 0, sizeof(struct spnic_txq_stats));
+ }
+
+ return 0;
+}
+
+/**
+ * Get device extended statistics.
+ *
+ * @param[in] dev
+ * Pointer to ethernet device structure.
+ * @param[out] xstats
+ * Pointer to rte extended stats table.
+ * @param[in] n
+ * The size of the stats table.
+ *
+ * @retval positive: Number of extended stats on success and stats is filled
+ * @retval negative: Failure
+ */
+static int spnic_dev_xstats_get(struct rte_eth_dev *dev,
+ struct rte_eth_xstat *xstats, unsigned int n)
+{
+ struct spnic_nic_dev *nic_dev;
+ struct mag_phy_port_stats port_stats;
+ struct spnic_vport_stats vport_stats;
+ struct spnic_rxq *rxq = NULL;
+ struct spnic_rxq_stats rxq_stats;
+ struct spnic_txq *txq = NULL;
+ struct spnic_txq_stats txq_stats;
+ u16 qid;
+ u32 i;
+ int err, count;
+
+ nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
+ count = spnic_xstats_calc_num(nic_dev);
+ if ((int)n < count)
+ return count;
+
+ count = 0;
+
+ /* Get stats from rxq stats structure */
+ for (qid = 0; qid < nic_dev->num_rqs; qid++) {
+ rxq = nic_dev->rxqs[qid];
+ memcpy(&rxq_stats, &rxq->rxq_stats, sizeof(rxq->rxq_stats));
+
+ for (i = 0; i < SPNIC_RXQ_XSTATS_NUM; i++) {
+ xstats[count].value =
+ *(uint64_t *)(((char *)&rxq_stats) +
+ spnic_rxq_stats_strings[i].offset);
+ xstats[count].id = count;
+ count++;
+ }
+ }
+
+ /* Get stats from txq stats structure */
+ for (qid = 0; qid < nic_dev->num_sqs; qid++) {
+ txq = nic_dev->txqs[qid];
+ memcpy(&txq_stats, &txq->txq_stats, sizeof(txq->txq_stats));
+
+ for (i = 0; i < SPNIC_TXQ_XSTATS_NUM; i++) {
+ xstats[count].value =
+ *(uint64_t *)(((char *)&txq_stats) +
+ spnic_txq_stats_strings[i].offset);
+ xstats[count].id = count;
+ count++;
+ }
+ }
+
+ /* Get stats from vport stats structure */
+ err = spnic_get_vport_stats(nic_dev->hwdev, &vport_stats);
+ if (err)
+ return err;
+
+ for (i = 0; i < SPNIC_VPORT_XSTATS_NUM; i++) {
+ xstats[count].value =
+ *(uint64_t *)(((char *)&vport_stats) +
+ spnic_vport_stats_strings[i].offset);
+ xstats[count].id = count;
+ count++;
+ }
+
+ if (SPNIC_IS_VF(nic_dev->hwdev))
+ return count;
+
+ /* Get stats from phy port stats structure */
+ err = spnic_get_phy_port_stats(nic_dev->hwdev, &port_stats);
+ if (err)
+ return err;
+
+ for (i = 0; i < SPNIC_PHYPORT_XSTATS_NUM; i++) {
+ xstats[count].value = *(uint64_t *)(((char *)&port_stats) +
+ spnic_phyport_stats_strings[i].offset);
+ xstats[count].id = count;
+ count++;
+ }
+
+ return count;
+}
+
+/**
+ * Clear device extended statistics.
+ *
+ * @param[in] dev
+ * Pointer to ethernet device structure.
+ *
+ * @retval zero: Success
+ * @retval non-zero: Failure
+ */
+static int spnic_dev_xstats_reset(struct rte_eth_dev *dev)
+{
+ struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
+ int err;
+
+ err = spnic_dev_stats_reset(dev);
+ if (err)
+ return err;
+
+ if (spnic_func_type(nic_dev->hwdev) != TYPE_VF) {
+ err = spnic_clear_phy_port_stats(nic_dev->hwdev);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+/**
+ * Retrieve names of extended device statistics
+ *
+ * @param[in] dev
+ * Pointer to ethernet device structure.
+ * @param[out] xstats_names
+ * Buffer to insert names into.
+ *
+ * @return
+ * Number of xstats names.
+ */
+static int spnic_dev_xstats_get_names(struct rte_eth_dev *dev,
+ struct rte_eth_xstat_name *xstats_names,
+ __rte_unused unsigned int limit)
+{
+ struct spnic_nic_dev *nic_dev = SPNIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
+ int count = 0;
+ u16 i, q_num;
+
+ if (xstats_names == NULL)
+ return spnic_xstats_calc_num(nic_dev);
+
+ /* Get pmd rxq stats name */
+ for (q_num = 0; q_num < nic_dev->num_rqs; q_num++) {
+ for (i = 0; i < SPNIC_RXQ_XSTATS_NUM; i++) {
+ snprintf(xstats_names[count].name,
+ sizeof(xstats_names[count].name),
+ "rxq%d_%s_pmd", q_num,
+ spnic_rxq_stats_strings[i].name);
+ count++;
+ }
+ }
+
+ /* Get pmd txq stats name */
+ for (q_num = 0; q_num < nic_dev->num_sqs; q_num++) {
+ for (i = 0; i < SPNIC_TXQ_XSTATS_NUM; i++) {
+ snprintf(xstats_names[count].name,
+ sizeof(xstats_names[count].name),
+ "txq%d_%s_pmd", q_num,
+ spnic_txq_stats_strings[i].name);
+ count++;
+ }
+ }
+
+ /* Get vport stats name */
+ for (i = 0; i < SPNIC_VPORT_XSTATS_NUM; i++) {
+ snprintf(xstats_names[count].name,
+ sizeof(xstats_names[count].name),
+ "%s", spnic_vport_stats_strings[i].name);
+ count++;
+ }
+
+ if (SPNIC_IS_VF(nic_dev->hwdev))
+ return count;
+
+ /* Get phy port stats name */
+ for (i = 0; i < SPNIC_PHYPORT_XSTATS_NUM; i++) {
+ snprintf(xstats_names[count].name,
+ sizeof(xstats_names[count].name),
+ "%s", spnic_phyport_stats_strings[i].name);
+ count++;
+ }
+
+ return count;
+}
+
static void spnic_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
struct rte_eth_rxq_info *rxq_info)
{
@@ -2082,6 +2546,11 @@ static const struct eth_dev_ops spnic_pmd_ops = {
.rss_hash_conf_get = spnic_rss_conf_get,
.reta_update = spnic_rss_reta_update,
.reta_query = spnic_rss_reta_query,
+ .stats_get = spnic_dev_stats_get,
+ .stats_reset = spnic_dev_stats_reset,
+ .xstats_get = spnic_dev_xstats_get,
+ .xstats_reset = spnic_dev_xstats_reset,
+ .xstats_get_names = spnic_dev_xstats_get_names,
.rxq_info_get = spnic_rxq_info_get,
.txq_info_get = spnic_txq_info_get,
.mac_addr_set = spnic_set_mac_addr,
@@ -2111,6 +2580,11 @@ static const struct eth_dev_ops spnic_pmd_vf_ops = {
.rss_hash_conf_get = spnic_rss_conf_get,
.reta_update = spnic_rss_reta_update,
.reta_query = spnic_rss_reta_query,
+ .stats_get = spnic_dev_stats_get,
+ .stats_reset = spnic_dev_stats_reset,
+ .xstats_get = spnic_dev_xstats_get,
+ .xstats_reset = spnic_dev_xstats_reset,
+ .xstats_get_names = spnic_dev_xstats_get_names,
.rxq_info_get = spnic_rxq_info_get,
.txq_info_get = spnic_txq_info_get,
.mac_addr_set = spnic_set_mac_addr,
--
2.27.0
next prev parent reply other threads:[~2021-12-18 2:55 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-18 2:51 [PATCH v1 00/25] Net/SPNIC: support SPNIC into DPDK 22.03 Yanling Song
2021-12-18 2:51 ` [PATCH v1 01/25] drivers/net: introduce a new PMD driver Yanling Song
2021-12-19 19:40 ` Stephen Hemminger
2021-12-22 0:54 ` Yanling Song
2021-12-22 16:55 ` Stephen Hemminger
2021-12-23 8:10 ` Yanling Song
2021-12-18 2:51 ` [PATCH v1 02/25] net/spnic: initialize the HW interface Yanling Song
2021-12-18 2:51 ` [PATCH v1 03/25] net/spnic: add mbox message channel Yanling Song
2021-12-18 2:51 ` [PATCH v1 04/25] net/spnic: introduce event queue Yanling Song
2021-12-18 2:51 ` [PATCH v1 05/25] net/spnic: add mgmt module Yanling Song
2021-12-18 2:51 ` [PATCH v1 06/25] net/spnic: add cmdq and work queue Yanling Song
2021-12-18 2:51 ` [PATCH v1 07/25] net/spnic: add interface handling cmdq message Yanling Song
2021-12-18 2:51 ` [PATCH v1 08/25] net/spnic: add hardware info initialization Yanling Song
2021-12-18 2:51 ` [PATCH v1 09/25] net/spnic: support MAC and link event handling Yanling Song
2021-12-18 2:51 ` [PATCH v1 10/25] net/spnic: add function info initialization Yanling Song
2021-12-18 2:51 ` [PATCH v1 11/25] net/spnic: add queue pairs context initialization Yanling Song
2021-12-18 2:51 ` [PATCH v1 12/25] net/spnic: support mbuf handling of Tx/Rx Yanling Song
2021-12-18 2:51 ` [PATCH v1 13/25] net/spnic: support Rx congfiguration Yanling Song
2021-12-18 2:51 ` [PATCH v1 14/25] net/spnic: add port/vport enable Yanling Song
2021-12-18 2:51 ` [PATCH v1 15/25] net/spnic: support IO packets handling Yanling Song
2021-12-18 2:51 ` [PATCH v1 16/25] net/spnic: add device configure/version/info Yanling Song
2021-12-20 0:23 ` Stephen Hemminger
2021-12-22 0:56 ` Yanling Song
2021-12-18 2:51 ` [PATCH v1 17/25] net/spnic: support RSS configuration update and get Yanling Song
2021-12-18 2:51 ` [PATCH v1 18/25] net/spnic: support VLAN filtering and offloading Yanling Song
2021-12-18 2:51 ` [PATCH v1 19/25] net/spnic: support promiscuous and allmulticast Rx modes Yanling Song
2021-12-18 2:51 ` [PATCH v1 20/25] net/spnic: support flow control Yanling Song
2021-12-18 2:51 ` [PATCH v1 21/25] net/spnic: support getting Tx/Rx queues info Yanling Song
2021-12-18 2:51 ` Yanling Song [this message]
2021-12-18 2:51 ` [PATCH v1 23/25] net/spnic: support VFIO interrupt Yanling Song
2021-12-18 2:51 ` [PATCH v1 24/25] net/spnic: support Tx/Rx queue start/stop Yanling Song
2021-12-18 2:51 ` [PATCH v1 25/25] net/spnic: add doc infrastructure Yanling Song
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=332ed0b3b8dedbf236fbeb63a40813f6d8357e58.1639636621.git.songyl@ramaxel.com \
--to=songyl@ramaxel.com \
--cc=dev@dpdk.org \
--cc=ferruh.yigit@intel.com \
--cc=yanggan@ramaxel.com \
--cc=yanling.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).