summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHanoh Haim <hhaim@cisco.com>2016-04-13 12:40:21 +0300
committerHanoh Haim <hhaim@cisco.com>2016-04-13 12:40:21 +0300
commit8076b8111991a790886537a5c1d7b54a01f479e4 (patch)
treed3615814b3a62a4e19d64fd9cf1269c36ba62ed0 /src
parent1f450703d3a51ed454af26aa494a7c6e2579686d (diff)
parent0b39ec305e80999c7dbe36d4b0d3850b04709571 (diff)
Merge v2.0
Diffstat (limited to 'src')
-rw-r--r--src/dpdk22/drivers/net/i40e/i40e_ethdev.c24
-rw-r--r--src/dpdk22/lib/librte_ether/rte_ethdev.c17
-rw-r--r--src/main_dpdk.cpp50
-rw-r--r--src/stateless/cp/trex_api_class.h30
-rw-r--r--src/stateless/cp/trex_stateless.cpp2
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);
}
/**