diff options
author | Hanoh Haim <hhaim@cisco.com> | 2016-04-13 12:40:21 +0300 |
---|---|---|
committer | Hanoh Haim <hhaim@cisco.com> | 2016-04-13 12:40:21 +0300 |
commit | 8076b8111991a790886537a5c1d7b54a01f479e4 (patch) | |
tree | d3615814b3a62a4e19d64fd9cf1269c36ba62ed0 /src | |
parent | 1f450703d3a51ed454af26aa494a7c6e2579686d (diff) | |
parent | 0b39ec305e80999c7dbe36d4b0d3850b04709571 (diff) |
Merge v2.0
Diffstat (limited to 'src')
-rw-r--r-- | src/dpdk22/drivers/net/i40e/i40e_ethdev.c | 24 | ||||
-rw-r--r-- | src/dpdk22/lib/librte_ether/rte_ethdev.c | 17 | ||||
-rw-r--r-- | src/main_dpdk.cpp | 50 | ||||
-rw-r--r-- | src/stateless/cp/trex_api_class.h | 30 | ||||
-rw-r--r-- | src/stateless/cp/trex_stateless.cpp | 2 |
5 files changed, 96 insertions, 27 deletions
diff --git a/src/dpdk22/drivers/net/i40e/i40e_ethdev.c b/src/dpdk22/drivers/net/i40e/i40e_ethdev.c index dff4ec3c..ae195683 100644 --- a/src/dpdk22/drivers/net/i40e/i40e_ethdev.c +++ b/src/dpdk22/drivers/net/i40e/i40e_ethdev.c @@ -2114,6 +2114,21 @@ i40e_trex_fdir_stats_get(struct rte_eth_dev *dev, uint32_t *stats, uint32_t star } } +// TREX_PATCH +void +i40e_trex_fdir_stats_reset(struct rte_eth_dev *dev, uint32_t *stats, uint32_t start, uint32_t len) +{ + int i; + struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + for (i = 0; i < len; i++) { + if (stats) { + stats[i] = I40E_READ_REG(hw, I40E_GLQF_PCNT(i + start)); + } + I40E_WRITE_REG(hw, I40E_GLQF_PCNT(i + start), 0xffffffff); + } +} + /* Get all statistics of a port */ static void i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) @@ -8413,6 +8428,7 @@ i40e_dcb_hw_configure(struct i40e_pf *pf, * * Returns 0 on success, negative value on failure */ +//TREX_PATCH - changed all ERR to INFO in below func static int i40e_dcb_init_configure(struct rte_eth_dev *dev, bool sw_dcb) { @@ -8421,7 +8437,7 @@ i40e_dcb_init_configure(struct rte_eth_dev *dev, bool sw_dcb) int ret = 0; if ((pf->flags & I40E_FLAG_DCB) == 0) { - PMD_INIT_LOG(ERR, "HW doesn't support DCB"); + PMD_INIT_LOG(INFO, "HW doesn't support DCB"); return -ENOTSUP; } @@ -8463,7 +8479,7 @@ i40e_dcb_init_configure(struct rte_eth_dev *dev, bool sw_dcb) I40E_APP_PROTOID_FCOE; ret = i40e_set_dcb_config(hw); if (ret) { - PMD_INIT_LOG(ERR, "default dcb config fails." + PMD_INIT_LOG(INFO, "default dcb config fails." " err = %d, aq_err = %d.", ret, hw->aq.asq_last_status); return -ENOSYS; @@ -8482,12 +8498,12 @@ i40e_dcb_init_configure(struct rte_eth_dev *dev, bool sw_dcb) ret = i40e_init_dcb(hw); if (!ret) { if (hw->dcbx_status == I40E_DCBX_STATUS_DISABLED) { - PMD_INIT_LOG(ERR, "HW doesn't support" + PMD_INIT_LOG(INFO, "HW doesn't support" " DCBX offload."); return -ENOTSUP; } } else { - PMD_INIT_LOG(ERR, "DCBX configuration failed, err = %d," + PMD_INIT_LOG(INFO, "DCBX configuration failed, err = %d," " aq_err = %d.", ret, hw->aq.asq_last_status); return -ENOTSUP; diff --git a/src/dpdk22/lib/librte_ether/rte_ethdev.c b/src/dpdk22/lib/librte_ether/rte_ethdev.c index 383ad120..44b4b640 100644 --- a/src/dpdk22/lib/librte_ether/rte_ethdev.c +++ b/src/dpdk22/lib/librte_ether/rte_ethdev.c @@ -1462,6 +1462,23 @@ rte_eth_fdir_stats_get(uint8_t port_id, uint32_t *stats, uint32_t start, uint32_ return 0; } +// TREX_PATCH +// zero statistics counters, starting from start, for len counters. +int +rte_eth_fdir_stats_reset(uint8_t port_id, uint32_t *stats, uint32_t start, uint32_t len) +{ + struct rte_eth_dev *dev; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); + + dev = &rte_eth_devices[port_id]; + + // Only xl710 support this + i40e_trex_fdir_stats_reset(dev, stats, start, len); + + return 0; +} + int rte_eth_stats_get(uint8_t port_id, struct rte_eth_stats *stats) { diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 652e6947..e20221d9 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -144,7 +144,7 @@ public: virtual bool hw_rx_stat_supported(){return false;} virtual int get_rx_stats(CPhyEthIF * _if, uint32_t *pkts, uint32_t *prev_pkts, uint32_t *bytes, uint32_t *prev_bytes , int min, int max) {return -1;} - virtual int reset_rx_stats(CPhyEthIF * _if, uint32_t *stats) {return 0;} + virtual void reset_rx_stats(CPhyEthIF * _if, uint32_t *stats, int min, int len) {} virtual int dump_fdir_global_stats(CPhyEthIF * _if, FILE *fd) { return -1;} virtual int get_stat_counters_num() {return 0;} virtual int get_rx_stat_capabilities() {return 0;} @@ -325,7 +325,7 @@ public: } virtual void get_extended_stats(CPhyEthIF * _if,CPhyEthIFStats *stats); virtual void clear_extended_stats(CPhyEthIF * _if); - virtual int reset_rx_stats(CPhyEthIF * _if, uint32_t *stats); + virtual void reset_rx_stats(CPhyEthIF * _if, uint32_t *stats, int min, int len); virtual int get_rx_stats(CPhyEthIF * _if, uint32_t *pkts, uint32_t *prev_pkts, uint32_t *bytes, uint32_t *prev_bytes, int min, int max); virtual int dump_fdir_global_stats(CPhyEthIF * _if, FILE *fd); virtual int get_stat_counters_num() {return MAX_FLOW_STATS;} @@ -2368,6 +2368,7 @@ void CGlobalStats::dump_json(std::string & json, bool baseline,uint32_t stats_ti #define GET_FIELD_PORT(p,f) get_field_port(p,std::string(#f),lp->f) json+=GET_FIELD(m_cpu_util); + json+=GET_FIELD(m_rx_cpu_util); json+=GET_FIELD(m_platform_factor); json+=GET_FIELD(m_tx_bps); json+=GET_FIELD(m_rx_bps); @@ -4008,9 +4009,7 @@ static CGlobalTRex g_trex; int CPhyEthIF::reset_hw_flow_stats() { if (get_ex_drv()->hw_rx_stat_supported()) { - if (get_ex_drv()->reset_rx_stats(this, m_stats.m_fdir_prev_pkts) < 0) { - return -1; - } + get_ex_drv()->reset_rx_stats(this, m_stats.m_fdir_prev_pkts, 0, MAX_FLOW_STATS); } else { g_trex.m_rx_sl.reset_rx_stats(get_port_id()); } @@ -4046,6 +4045,8 @@ int CPhyEthIF::get_flow_stats(rx_per_flow_t *rx_stats, tx_per_flow_t *tx_stats, } m_stats.m_rx_per_flow_pkts[i] = 0; m_stats.m_rx_per_flow_bytes[i] = 0; + get_ex_drv()->reset_rx_stats(this, &m_stats.m_fdir_prev_pkts[i], i, 1); + } if (tx_stats != NULL) { tx_stats[i - min] = g_trex.clear_flow_tx_stats(m_port_id, i); @@ -5058,6 +5059,8 @@ void CTRexExtendedDriverBase40G::add_del_rules(enum rte_filter_op op, uint8_t po } } +extern "C" int rte_eth_fdir_stats_reset(uint8_t port_id, uint32_t *stats, uint32_t start, uint32_t len); + // type - rule type. Currently we only support rules in IP ID. // proto - Packet protocol: UDP or TCP // id - Counter id in HW. We assume it is in the range 0..MAX_FLOW_STATS @@ -5085,6 +5088,7 @@ int CTRexExtendedDriverBase40G::configure_rx_filter_rules_statfull(CPhyEthIF * _ uint16_t hops = get_rx_check_hops(); int i; + rte_eth_fdir_stats_reset(port_id, NULL, 0, 1); for (i = 0; i < 2; i++) { uint8_t ttl = TTL_RESERVE_DUPLICATE - i - hops; add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_UDP, ttl, 0, MAIN_DPDK_RX_Q, 0); @@ -5108,18 +5112,24 @@ int CTRexExtendedDriverBase40G::configure_rx_filter_rules(CPhyEthIF * _if) { } } -int CTRexExtendedDriverBase40G::reset_rx_stats(CPhyEthIF * _if, uint32_t *stats) { - uint32_t diff_stats[MAX_FLOW_STATS]; - uint32_t diff_bytes[MAX_FLOW_STATS]; - - // The HW counters start from some random values. The driver give us the diffs from previous, - // each time we do get_rx_stats. We need to make one first call, at system startup, - // and ignore the returned diffs - return get_rx_stats(_if, diff_stats, stats, diff_bytes, NULL, 0, MAX_FLOW_STATS - 1); +void CTRexExtendedDriverBase40G::reset_rx_stats(CPhyEthIF * _if, uint32_t *stats, int min, int len) { + uint32_t port_id = _if->get_port_id(); + // Since the xl710 fdir counter stuck at 0xffffffff issue, we zero the HW counters, so should zero here also. + for (int i = min; i <= min - len + 1; i++) { + uint32_t rule_id = (port_id % m_if_per_card) * MAX_FLOW_STATS + i; + stats[i - min] = 0; + // Since flow dir counters are not wrapped around as promised in the data sheet, but rather get stuck at 0xffffffff + // we reset the HW value + rte_eth_fdir_stats_reset(port_id, NULL, rule_id, 1); + } } // instead of adding this to rte_ethdev.h extern "C" int rte_eth_fdir_stats_get(uint8_t port_id, uint32_t *stats, uint32_t start, uint32_t len); +// we read every 0.5 second. We want to catch the counter when it approach the maximum (where it will stuck, +// and we will start losing packets). +const uint32_t X710_FDIR_RESET_THRESHOLD = 0xffffffff - 1000000000/8/64*40; + // get rx stats on _if, between min and max // prev_pkts should be the previous values read from the hardware. // Getting changed to be equal to current HW values. @@ -5135,13 +5145,17 @@ int CTRexExtendedDriverBase40G::get_rx_stats(CPhyEthIF * _if, uint32_t *pkts, ui rte_eth_fdir_stats_get(port_id, hw_stats, start, len); for (int i = loop_start; i < loop_start + len; i++) { - if (hw_stats[i - min] >= prev_pkts[i]) { - pkts[i] = (uint64_t)(hw_stats[i - min] - prev_pkts[i]); + if (unlikely(hw_stats[i - min] > X710_FDIR_RESET_THRESHOLD)) { + // read again, and reset. Trying to lose minimal amount of packets. + // better solution is on its way - see trex-199 for details + uint32_t counter; + rte_eth_fdir_stats_reset(port_id, &counter, start + i, 1); + pkts[i] = counter - prev_pkts[i]; + prev_pkts[i] = 0; } else { - // Wrap around - pkts[i] = (uint64_t)((hw_stats[i - min] + ((uint64_t)1 << 32)) - prev_pkts[i]); + pkts[i] = hw_stats[i - min] - prev_pkts[i]; + prev_pkts[i] = hw_stats[i - min]; } - prev_pkts[i] = hw_stats[i - min]; bytes[i] = 0; } diff --git a/src/stateless/cp/trex_api_class.h b/src/stateless/cp/trex_api_class.h index 78933d23..748d1478 100644 --- a/src/stateless/cp/trex_api_class.h +++ b/src/stateless/cp/trex_api_class.h @@ -75,20 +75,42 @@ public: m_handler = utl_generate_random_str(seed, 8); } + std::string ver(int major, int minor) { + std::stringstream ss; + ss << major << "." << minor; + return ss.str(); + } + + std::string get_server_ver() { + return ver(m_major, m_major); + } + std::string & verify_api(int major, int minor) { std::stringstream ss; ss << "API type '" << type_to_name(m_type) << "': "; - + assert(m_type < API_CLASS_TYPE_MAX); + bool fail = false; + /* for now a simple major check */ if (major < m_major) { - ss << "server has a major newer API version - server: '" << m_major << "', client: '" << major << "'"; - throw TrexAPIException(ss.str()); + ss << "server has a newer major API version"; + fail = true; } if (major > m_major) { - ss << "server has an older API version - server: '" << m_major << "', client: '" << major << "'"; + ss << "server has an older major API version"; + fail = true; + } + + if (minor > m_minor) { + ss << "client revision API is newer than server"; + fail = true; + } + + if (fail) { + ss << " - server: '" << get_server_ver() << "', client: '" << ver(major, minor) << "'"; throw TrexAPIException(ss.str()); } diff --git a/src/stateless/cp/trex_stateless.cpp b/src/stateless/cp/trex_stateless.cpp index f6f81b96..c86c5f65 100644 --- a/src/stateless/cp/trex_stateless.cpp +++ b/src/stateless/cp/trex_stateless.cpp @@ -54,7 +54,7 @@ TrexStateless::TrexStateless(const TrexStatelessCfg &cfg) { m_publisher = cfg.m_publisher; /* API core version */ - m_api_classes[APIClass::API_CLASS_TYPE_CORE].init(APIClass::API_CLASS_TYPE_CORE, 1, 0); + m_api_classes[APIClass::API_CLASS_TYPE_CORE].init(APIClass::API_CLASS_TYPE_CORE, 1, 1); } /** |