summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIdo Barnea <ibarnea@cisco.com>2016-04-13 17:45:50 +0300
committerIdo Barnea <ibarnea@cisco.com>2016-04-13 17:45:50 +0300
commiteb899d6876327b3a3f0e2ada53dd9fd0845b74e9 (patch)
treeed4c59e77891cda7dd808952a5afc542ebb2e592
parent8076b8111991a790886537a5c1d7b54a01f479e4 (diff)
Fix to trex-199 Fdir counters stuck to 2^32
-rw-r--r--src/main_dpdk.cpp45
-rw-r--r--src/trex_defs.h2
2 files changed, 33 insertions, 14 deletions
diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp
index e20221d9..65f8332e 100644
--- a/src/main_dpdk.cpp
+++ b/src/main_dpdk.cpp
@@ -289,7 +289,7 @@ class CTRexExtendedDriverBase40G : public CTRexExtendedDriverBase10G {
public:
CTRexExtendedDriverBase40G(){
// Since we support only 128 counters per if, it is OK to configure here 4 statically.
- // If we want to support more counters in case in case of card having less interfaces, we
+ // If we want to support more counters in case of card having less interfaces, we
// Will have to identify the number of interfaces dynamically.
m_if_per_card = 4;
}
@@ -4998,6 +4998,9 @@ void CTRexExtendedDriverBase40G::update_configuration(port_cfg_t * cfg){
cfg->update_global_config_fdir_40g();
}
+// What is the type of the rule the respective hw_id counter counts.
+static uint16_t fdir_hw_id_rule_type[512];
+
/* Add rule to send packets with protocol 'type', and ttl 'ttl' to rx queue 1 */
// ttl is used in statefull mode, and ip_id in stateless. We configure the driver registers so that only one of them applies.
// So, the rule will apply if packet has either the correct ttl or IP ID, depending if we are in statfull or stateless.
@@ -5027,6 +5030,10 @@ void CTRexExtendedDriverBase40G::add_del_rules(enum rte_filter_op op, uint8_t po
filter.soft_id = filter_soft_id++;
filter.input.flow_type = type;
+ if (op == RTE_ETH_FILTER_ADD) {
+ fdir_hw_id_rule_type[stat_idx] = type;
+ }
+
switch (type) {
case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
filter.input.flow.ip4_flow.ttl=ttl;
@@ -5095,6 +5102,7 @@ int CTRexExtendedDriverBase40G::configure_rx_filter_rules_statfull(CPhyEthIF * _
add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_TCP, ttl, 0, MAIN_DPDK_RX_Q, 0);
add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV6_UDP, ttl, 0, MAIN_DPDK_RX_Q, 0);
add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV6_TCP, ttl, 0, MAIN_DPDK_RX_Q, 0);
+
}
/* Configure rules for latency measurement packets */
@@ -5104,8 +5112,10 @@ int CTRexExtendedDriverBase40G::configure_rx_filter_rules_statfull(CPhyEthIF * _
return 0;
}
+const uint32_t TEMP_FDIR_HW_ID = 511;
int CTRexExtendedDriverBase40G::configure_rx_filter_rules(CPhyEthIF * _if) {
if (get_is_stateless()) {
+ rte_eth_fdir_stats_reset(_if->get_port_id(), NULL, TEMP_FDIR_HW_ID, 1);
return 0; // Rules are configured dynamically in stateless
} else {
return configure_rx_filter_rules_statfull(_if);
@@ -5114,13 +5124,14 @@ int CTRexExtendedDriverBase40G::configure_rx_filter_rules(CPhyEthIF * _if) {
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);
+ uint32_t rule_id = (port_id % m_if_per_card) * MAX_FLOW_STATS + min;
+
+ // 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, len);
+
+ for (int i =0; i < len; i++) {
+ stats[i] = 0;
}
}
@@ -5146,11 +5157,19 @@ 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 (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];
+ // When x710 fdir counters reach max of 32 bits (4G), the get stuck. To handle this, we temporarily
+ // move to temp counter, reset the counter in danger, and go back to using it.
+ // see trex-199 for more details
+ uint32_t counter, temp_count;
+ uint32_t hw_id = start - min + i;
+
+ add_del_rules( RTE_ETH_FILTER_ADD, port_id, fdir_hw_id_rule_type[hw_id], 0, IP_ID_RESERVE_BASE + i, MAIN_DPDK_DATA_Q, TEMP_FDIR_HW_ID);
+ delay(100);
+ rte_eth_fdir_stats_reset(port_id, &counter, hw_id, 1);
+ add_del_rules( RTE_ETH_FILTER_ADD, port_id, fdir_hw_id_rule_type[hw_id], 0, IP_ID_RESERVE_BASE + i, MAIN_DPDK_DATA_Q, hw_id);
+ delay(100);
+ rte_eth_fdir_stats_reset(port_id, &temp_count, TEMP_FDIR_HW_ID, 1);
+ pkts[i] = counter + temp_count - prev_pkts[i];
prev_pkts[i] = 0;
} else {
pkts[i] = hw_stats[i - min] - prev_pkts[i];
diff --git a/src/trex_defs.h b/src/trex_defs.h
index 4ecee1d5..50bb282a 100644
--- a/src/trex_defs.h
+++ b/src/trex_defs.h
@@ -20,7 +20,7 @@ limitations under the License.
#define TREX_MAX_PORTS 12
-#define MAX_FLOW_STATS 128
+#define MAX_FLOW_STATS 127
#ifndef UINT8_MAX
#define UINT8_MAX 255