From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id A99D9C32C for ; Thu, 22 Oct 2015 17:49:14 +0200 (CEST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga103.jf.intel.com with ESMTP; 22 Oct 2015 08:49:14 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,183,1444719600"; d="scan'208";a="800293090" Received: from sie-lab-212-222.ir.intel.com (HELO silpixa00366884.ir.intel.com) ([10.237.212.222]) by orsmga001.jf.intel.com with ESMTP; 22 Oct 2015 08:49:14 -0700 From: Harry van Haaren To: dev@dpdk.org Date: Thu, 22 Oct 2015 16:48:32 +0100 Message-Id: <1445528914-27636-10-git-send-email-harry.van.haaren@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1445528914-27636-1-git-send-email-harry.van.haaren@intel.com> References: <1443606022-13581-2-git-send-email-harry.van.haaren@intel.com> <1445528914-27636-1-git-send-email-harry.van.haaren@intel.com> Subject: [dpdk-dev] [PATCH v3 09/11] i40e: add xstats() implementation X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 22 Oct 2015 15:49:15 -0000 Add xstats functions to i40e PMD, allowing extended statistics to be retrieved from the NIC and exposed to the DPDK. Signed-off-by: Harry van Haaren --- drivers/net/i40e/i40e_ethdev.c | 265 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 258 insertions(+), 7 deletions(-) diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 2dd9fdc..cf0199d 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -127,7 +127,10 @@ static int i40e_dev_set_link_up(struct rte_eth_dev *dev); static int i40e_dev_set_link_down(struct rte_eth_dev *dev); static void i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats); +static int i40e_dev_xstats_get(struct rte_eth_dev *dev, + struct rte_eth_xstats *xstats, unsigned n); static void i40e_dev_stats_reset(struct rte_eth_dev *dev); +static void i40e_dev_xstats_reset(struct rte_eth_dev *dev); static int i40e_dev_queue_stats_mapping_set(struct rte_eth_dev *dev, uint16_t queue_id, uint8_t stat_idx, @@ -232,6 +235,8 @@ static int i40e_timesync_read_rx_timestamp(struct rte_eth_dev *dev, uint32_t flags); static int i40e_timesync_read_tx_timestamp(struct rte_eth_dev *dev, struct timespec *timestamp); +static void i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw); + static const struct rte_pci_id pci_id_i40e_map[] = { #define RTE_PCI_DEV_ID_DECL_I40E(vend, dev) {RTE_PCI_DEVICE(vend, dev)}, @@ -252,7 +257,9 @@ static const struct eth_dev_ops i40e_eth_dev_ops = { .dev_set_link_down = i40e_dev_set_link_down, .link_update = i40e_dev_link_update, .stats_get = i40e_dev_stats_get, + .xstats_get = i40e_dev_xstats_get, .stats_reset = i40e_dev_stats_reset, + .xstats_reset = i40e_dev_xstats_reset, .queue_stats_mapping_set = i40e_dev_queue_stats_mapping_set, .dev_infos_get = i40e_dev_info_get, .vlan_filter_set = i40e_vlan_filter_set, @@ -291,6 +298,187 @@ static const struct eth_dev_ops i40e_eth_dev_ops = { .timesync_read_tx_timestamp = i40e_timesync_read_tx_timestamp, }; +/* store statistics names and its offset in stats structure */ +struct rte_i40e_xstats_name_off { + char name[RTE_ETH_XSTATS_NAME_SIZE]; + unsigned offset; +}; + +static const struct rte_i40e_xstats_name_off rte_i40e_stats_strings[] = { + {"rx_unicast_packets", offsetof(struct i40e_eth_stats, rx_unicast)}, + {"rx_multicast_packets", offsetof(struct i40e_eth_stats, rx_multicast)}, + {"rx_broadcast_packets", offsetof(struct i40e_eth_stats, rx_broadcast)}, + {"rx_dropped", offsetof(struct i40e_eth_stats, rx_discards)}, + {"rx_unknown_protocol_packets", offsetof(struct i40e_eth_stats, + rx_unknown_protocol)}, + {"tx_unicast_packets", offsetof(struct i40e_eth_stats, tx_unicast)}, + {"tx_multicast_packets", offsetof(struct i40e_eth_stats, tx_multicast)}, + {"tx_broadcast_packets", offsetof(struct i40e_eth_stats, tx_broadcast)}, + {"tx_dropped", offsetof(struct i40e_eth_stats, tx_discards)}, +}; + +static const struct rte_i40e_xstats_name_off rte_i40e_hw_port_strings[] = { + {"tx_link_down_dropped", offsetof(struct i40e_hw_port_stats, + tx_dropped_link_down)}, + {"rx_crc_errors", offsetof(struct i40e_hw_port_stats, crc_errors)}, + {"rx_illegal_bytes", offsetof(struct i40e_hw_port_stats, + illegal_bytes)}, + {"rx_error_bytes", offsetof(struct i40e_hw_port_stats, error_bytes)}, + {"mac_local_errors", offsetof(struct i40e_hw_port_stats, + mac_local_faults)}, + {"mac_remote_errors", offsetof(struct i40e_hw_port_stats, + mac_remote_faults)}, + {"rx_length_errors", offsetof(struct i40e_hw_port_stats, + rx_length_errors)}, + {"tx_xon_packets", offsetof(struct i40e_hw_port_stats, link_xon_tx)}, + {"rx_xon_packets", offsetof(struct i40e_hw_port_stats, link_xon_rx)}, + {"tx_xoff_packets", offsetof(struct i40e_hw_port_stats, link_xoff_tx)}, + {"rx_xoff_packets", offsetof(struct i40e_hw_port_stats, link_xoff_rx)}, + {"rx_size_64_packets", offsetof(struct i40e_hw_port_stats, rx_size_64)}, + {"rx_size_65_to_127_packets", offsetof(struct i40e_hw_port_stats, + rx_size_127)}, + {"rx_size_128_to_255_packets", offsetof(struct i40e_hw_port_stats, + rx_size_255)}, + {"rx_size_256_to_511_packets", offsetof(struct i40e_hw_port_stats, + rx_size_511)}, + {"rx_size_512_to_1023_packets", offsetof(struct i40e_hw_port_stats, + rx_size_1023)}, + {"rx_size_1024_to_1522_packets", offsetof(struct i40e_hw_port_stats, + rx_size_1522)}, + {"rx_size_1523_to_max_packets", offsetof(struct i40e_hw_port_stats, + rx_size_big)}, + {"rx_undersized_packets", offsetof(struct i40e_hw_port_stats, + rx_undersize)}, + {"rx_oversize_packets", offsetof(struct i40e_hw_port_stats, + rx_oversize)}, + {"rx_mac_short_dropped", offsetof(struct i40e_hw_port_stats, + mac_short_packet_dropped)}, + {"rx_fragmented_packets", offsetof(struct i40e_hw_port_stats, + rx_fragments)}, + {"rx_jabber_packets", offsetof(struct i40e_hw_port_stats, rx_jabber)}, + {"tx_size_64_packets", offsetof(struct i40e_hw_port_stats, tx_size_64)}, + {"tx_size_65_to_127_packets", offsetof(struct i40e_hw_port_stats, + tx_size_127)}, + {"tx_size_128_to_255_packets", offsetof(struct i40e_hw_port_stats, + tx_size_255)}, + {"tx_size_256_to_511_packets", offsetof(struct i40e_hw_port_stats, + tx_size_511)}, + {"tx_size_512_to_1023_packets", offsetof(struct i40e_hw_port_stats, + tx_size_1023)}, + {"tx_size_1024_to_1522_packets", offsetof(struct i40e_hw_port_stats, + tx_size_1522)}, + {"tx_size_1523_to_max_packets", offsetof(struct i40e_hw_port_stats, + tx_size_big)}, + {"rx_flow_director_atr_match_packets", + offsetof(struct i40e_hw_port_stats, fd_atr_match)}, + {"rx_flow_director_sb_match_packets", + offsetof(struct i40e_hw_port_stats, fd_sb_match)}, + {"tx_low_power_idle_status", offsetof(struct i40e_hw_port_stats, + tx_lpi_status)}, + {"rx_low_power_idle_status", offsetof(struct i40e_hw_port_stats, + rx_lpi_status)}, + {"tx_low_power_idle_count", offsetof(struct i40e_hw_port_stats, + tx_lpi_count)}, + {"rx_low_power_idle_count", offsetof(struct i40e_hw_port_stats, + rx_lpi_count)}, + + /* priority_xon_rx[8] */ + {"tx_q0_xon_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xon_tx[0])}, + {"tx_q1_xon_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xon_tx[1])}, + {"tx_q2_xon_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xon_tx[2])}, + {"tx_q3_xon_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xon_tx[3])}, + {"tx_q4_xon_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xon_tx[4])}, + {"tx_q5_xon_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xon_tx[5])}, + {"tx_q6_xon_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xon_tx[6])}, + {"tx_q7_xon_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xon_tx[7])}, + + /* priority_xon_rx[8] */ + {"rx_q0_xon_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xon_rx[0])}, + {"rx_q1_xon_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xon_rx[1])}, + {"rx_q2_xon_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xon_rx[2])}, + {"rx_q3_xon_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xon_rx[3])}, + {"rx_q4_xon_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xon_rx[4])}, + {"rx_q5_xon_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xon_rx[5])}, + {"rx_q6_xon_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xon_rx[6])}, + {"rx_q7_xon_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xon_rx[7])}, + + /* priority_xoff_tx[8] */ + {"tx_q0_xoff_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xoff_tx[0])}, + {"tx_q1_xoff_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xoff_tx[1])}, + {"tx_q2_xoff_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xoff_tx[2])}, + {"tx_q3_xoff_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xoff_tx[3])}, + {"tx_q4_xoff_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xoff_tx[4])}, + {"tx_q5_xoff_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xoff_tx[5])}, + {"tx_q6_xoff_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xoff_tx[6])}, + {"tx_q7_xoff_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xoff_tx[7])}, + + /* priority_xoff_rx[8] */ + {"rx_q0_xoff_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xoff_rx[0])}, + {"rx_q1_xoff_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xoff_rx[1])}, + {"rx_q2_xoff_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xoff_rx[2])}, + {"rx_q3_xoff_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xoff_rx[3])}, + {"rx_q4_xoff_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xoff_rx[4])}, + {"rx_q5_xoff_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xoff_rx[5])}, + {"rx_q6_xoff_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xoff_rx[6])}, + {"rx_q7_xoff_priority_packets", offsetof(struct i40e_hw_port_stats, + priority_xoff_rx[7])}, + + /* priority_xon_2_xoff[8] */ + {"xx_q0_xon_to_xoff_priority_packets", + offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[0])}, + {"xx_q1_xon_to_xoff_priority_packets", + offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[1])}, + {"xx_q2_xon_to_xoff_priority_packets", + offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[2])}, + {"xx_q3_xon_to_xoff_priority_packets", + offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[3])}, + {"xx_q4_xon_to_xoff_priority_packets", + offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[4])}, + {"xx_q5_xon_to_xoff_priority_packets", + offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[5])}, + {"xx_q6_xon_to_xoff_priority_packets", + offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[6])}, + {"xx_q7_xon_to_xoff_priority_packets", + offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[7])}, +}; + +#define I40E_NB_ETH_XSTATS (sizeof(rte_i40e_stats_strings) / \ + sizeof(rte_i40e_stats_strings[0])) +#define I40E_NB_HW_PORT_XSTATS (sizeof(rte_i40e_hw_port_strings) / \ + sizeof(rte_i40e_hw_port_strings[0])) +#define I40E_NB_XSTATS (I40E_NB_ETH_XSTATS + I40E_NB_HW_PORT_XSTATS) + static struct eth_driver rte_i40e_pmd = { .pci_drv = { .name = "rte_i40e_pmd", @@ -1322,16 +1510,12 @@ i40e_update_vsi_stats(struct i40e_vsi *vsi) vsi->vsi_id); } -/* Get all statistics of a port */ static void -i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) +i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw) { - uint32_t i; - struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); - struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); + unsigned int i; struct i40e_hw_port_stats *ns = &pf->stats; /* new stats */ struct i40e_hw_port_stats *os = &pf->stats_offset; /* old stats */ - /* Get statistics of struct i40e_eth_stats */ i40e_stat_update_48(hw, I40E_GLPRT_GORCH(hw->port), I40E_GLPRT_GORCL(hw->port), @@ -1508,8 +1692,21 @@ i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) pf->offset_loaded = true; - if (pf->main_vsi) + if(pf->main_vsi) i40e_update_vsi_stats(pf->main_vsi); +} + +/* Get all statistics of a port */ +static void +i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) +{ + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); + struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct i40e_hw_port_stats *ns = &pf->stats; /* new stats */ + unsigned i; + + /* call read registers - updates values, now write them to struct */ + i40e_read_stats_registers(pf, hw); stats->ipackets = ns->eth.rx_unicast + ns->eth.rx_multicast + ns->eth.rx_broadcast; @@ -1599,6 +1796,60 @@ i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) PMD_DRV_LOG(DEBUG, "***************** PF stats end ********************"); } +static void +i40e_dev_xstats_reset(struct rte_eth_dev *dev) +{ + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); + struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct i40e_hw_port_stats *hw_stats = &pf->stats; + + /* The hw registers are cleared on read */ + pf->offset_loaded = false; + i40e_read_stats_registers(pf, hw); + + /* reset software counters */ + memset(hw_stats, 0, sizeof(*hw_stats)); +} + +static int +i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, + unsigned n) +{ + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); + struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); + unsigned i, count = 0; + struct i40e_hw_port_stats *hw_stats = &pf->stats; + + if(n < I40E_NB_XSTATS) + return I40E_NB_XSTATS; + + i40e_read_stats_registers(pf, hw); + + /* Reset */ + if(xstats == NULL) + return 0; + + /* copy from i40e_eth_stats struct */ + for(i = 0; i < I40E_NB_ETH_XSTATS; i++) { + snprintf(xstats[count].name, sizeof(xstats[count].name), + "%s", rte_i40e_stats_strings[i].name); + xstats[count].value = *(uint64_t *)(((char *)&hw_stats->eth) + + rte_i40e_stats_strings[i].offset); + count++; + } + + /* copy from i40e_hw_port struct */ + for(i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) { + snprintf(xstats[count].name, sizeof(xstats[count].name), + "%s", rte_i40e_hw_port_strings[i].name); + xstats[count].value = *(uint64_t *)(((char *)hw_stats) + + rte_i40e_hw_port_strings[i].offset); + count++; + } + + return I40E_NB_XSTATS; +} + /* Reset the statistics */ static void i40e_dev_stats_reset(struct rte_eth_dev *dev) -- 1.9.1