summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIdo Barnea <ibarnea@cisco.com>2016-09-27 14:24:32 +0300
committerIdo Barnea <ibarnea@cisco.com>2016-10-05 10:45:29 +0300
commitefb8873783d59ae2e5a870a99f05e40ebf661c16 (patch)
treed1ad7c06f55a532ae1b1349a24bb0aa067def4a8
parent2223955b8eb3b378c1ab79e3735ed340852b04b9 (diff)
pre test: Code review fixes
-rwxr-xr-xlinux/ws_main.py4
-rwxr-xr-xlinux_dpdk/ws_main.py4
-rwxr-xr-xsrc/bp_gtest.cpp2
-rwxr-xr-xsrc/bp_sim.cpp2
-rw-r--r--src/debug.cpp8
-rw-r--r--src/flow_stat_parser.cpp2
-rw-r--r--src/main_dpdk.cpp264
-rw-r--r--src/main_dpdk.h30
-rw-r--r--src/pkt_gen.cpp (renamed from src/test_pkt_gen.cpp)2
-rw-r--r--src/pkt_gen.h (renamed from src/test_pkt_gen.h)7
-rw-r--r--src/pre_test.cpp80
-rw-r--r--src/pre_test.h15
-rw-r--r--src/stateful_rx_core.cpp (renamed from src/latency.cpp)140
-rw-r--r--src/stateful_rx_core.h (renamed from src/latency.h)39
-rw-r--r--src/stateless/rx/trex_stateless_rx_core.cpp2
-rw-r--r--src/stateless/rx/trex_stateless_rx_core.h2
16 files changed, 363 insertions, 240 deletions
diff --git a/linux/ws_main.py b/linux/ws_main.py
index f20afcce..2a0d7286 100755
--- a/linux/ws_main.py
+++ b/linux/ws_main.py
@@ -112,14 +112,14 @@ main_src = SrcGroup(dir='src',
'rx_check_header.cpp',
'nat_check.cpp',
'nat_check_flow_table.cpp',
- 'test_pkt_gen.cpp',
+ 'pkt_gen.cpp',
'timer_wheel_pq.cpp',
'time_histogram.cpp',
'utl_json.cpp',
'utl_cpuu.cpp',
'msg_manager.cpp',
'publisher/trex_publisher.cpp',
- 'latency.cpp',
+ 'stateful_rx_core.cpp',
'flow_stat.cpp',
'flow_stat_parser.cpp',
'trex_watchdog.cpp',
diff --git a/linux_dpdk/ws_main.py b/linux_dpdk/ws_main.py
index 47c479c4..0a2c9dfa 100755
--- a/linux_dpdk/ws_main.py
+++ b/linux_dpdk/ws_main.py
@@ -115,13 +115,13 @@ main_src = SrcGroup(dir='src',
'flow_stat.cpp',
'flow_stat_parser.cpp',
'bp_sim.cpp',
- 'latency.cpp',
+ 'pkt_gen.cpp',
'platform_cfg.cpp',
'pre_test.cpp',
'tuple_gen.cpp',
'rx_check.cpp',
'rx_check_header.cpp',
- 'test_pkt_gen.cpp',
+ 'stateful_rx_core.cpp',
'timer_wheel_pq.cpp',
'time_histogram.cpp',
'os_time.cpp',
diff --git a/src/bp_gtest.cpp b/src/bp_gtest.cpp
index a1f80407..ca514c88 100755
--- a/src/bp_gtest.cpp
+++ b/src/bp_gtest.cpp
@@ -31,7 +31,7 @@ limitations under the License.
#include "msg_manager.h"
#include <common/cgen_map.h>
#include "platform_cfg.h"
-#include "latency.h"
+#include "stateful_rx_core.h"
#include "nat_check_flow_table.h"
int test_policer(){
diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp
index 773e82fc..b276d4ff 100755
--- a/src/bp_sim.cpp
+++ b/src/bp_sim.cpp
@@ -20,7 +20,7 @@ limitations under the License.
*/
#include "bp_sim.h"
-#include "latency.h"
+#include "stateful_rx_core.h"
#include "utl_json.h"
#include "utl_yaml.h"
#include "msg_manager.h"
diff --git a/src/debug.cpp b/src/debug.cpp
index 5abdbdc6..542d2fa1 100644
--- a/src/debug.cpp
+++ b/src/debug.cpp
@@ -27,7 +27,7 @@
#include <rte_pci.h>
#include <rte_ethdev.h>
#include <common/basic_utils.h>
-#include "test_pkt_gen.h"
+#include "pkt_gen.h"
#include "main_dpdk.h"
#include "debug.h"
@@ -446,7 +446,7 @@ int CTrexDebug::test_send(uint pkt_type) {
} else {
ip_ver = 4;
}
- if (pkt_type > 3) {
+ if (pkt_type > D_PKT_TYPE_ARP) {
printf("Packet type not supported\n");
exit(1);
}
@@ -462,6 +462,10 @@ int CTrexDebug::test_send(uint pkt_type) {
case D_PKT_TYPE_TCP:
l4_proto = IPPROTO_TCP;
break;
+ case D_PKT_TYPE_ARP:
+ ip_ver = 1;
+ l4_proto = IPPROTO_TCP; //just to prevenet compilation warning. Not used in this case.
+ break;
}
d = create_test_pkt(ip_ver, l4_proto, 254, FLOW_STAT_PAYLOAD_IP_ID, 0);
}
diff --git a/src/flow_stat_parser.cpp b/src/flow_stat_parser.cpp
index b809b0f9..7335a6a2 100644
--- a/src/flow_stat_parser.cpp
+++ b/src/flow_stat_parser.cpp
@@ -25,7 +25,7 @@
#include "common/Network/Packet/IPHeader.h"
#include "common/Network/Packet/IPv6Header.h"
#include "common/Network/Packet/TcpHeader.h"
-#include "test_pkt_gen.h"
+#include "pkt_gen.h"
#include "flow_stat_parser.h"
void CFlowStatParser::reset() {
diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp
index a6ea3876..edeeb3ee 100644
--- a/src/main_dpdk.cpp
+++ b/src/main_dpdk.cpp
@@ -74,9 +74,9 @@ extern "C" {
#include "msg_manager.h"
#include "platform_cfg.h"
#include "pre_test.h"
-#include "latency.h"
+#include "stateful_rx_core.h"
#include "debug.h"
-#include "test_pkt_gen.h"
+#include "pkt_gen.h"
#include "internal_api/trex_platform_api.h"
#include "main_dpdk.h"
#include "trex_watchdog.h"
@@ -653,7 +653,7 @@ static int usage(){
printf(" -m : factor of bandwidth \n");
printf(" \n");
printf(" --send-debug-pkt [proto] : Do not run traffic generator. Just send debug packet and dump receive queue.");
- printf(" Supported protocols are 1 for icmp, 2 for UDP, 3 for TCP, 4 for 9K UDP\n");
+ printf(" Supported protocols are 1 for icmp, 2 for UDP, 3 for TCP, 4 for ARP, 5 for 9K UDP\n");
printf(" \n");
printf(" -k [sec] : run latency test before starting the test. it will wait for x sec sending packet and x sec after that \n");
printf(" \n");
@@ -1014,7 +1014,8 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t
"if you think it is important,open a defect \n");
}
- if (po->preview.get_is_rx_check_enable() || po->is_latency_enabled() || CGlobalInfo::is_learn_mode()) {
+ if (po->preview.get_is_rx_check_enable() || po->is_latency_enabled() || CGlobalInfo::is_learn_mode()
+ || (CGlobalInfo::m_options.m_arp_ref_per != 0)) {
po->set_rx_enabled();
}
@@ -1212,7 +1213,7 @@ typedef struct cnt_name_ {
#define MY_REG(a) {a,(char *)#a}
-void CPhyEthIFStats::Clear(){
+void CPhyEthIFStats::Clear() {
ipackets = 0;
ibytes = 0;
f_ipackets = 0;
@@ -1223,13 +1224,13 @@ void CPhyEthIFStats::Clear(){
oerrors = 0;
imcasts = 0;
rx_nombuf = 0;
+ memset(&m_prev_stats, 0, sizeof(m_prev_stats));
memset(m_rx_per_flow_pkts, 0, sizeof(m_rx_per_flow_pkts));
memset(m_rx_per_flow_bytes, 0, sizeof(m_rx_per_flow_bytes));
}
-
-void CPhyEthIFStats::DumpAll(FILE *fd){
-
+// dump all counters (even ones that equal 0)
+void CPhyEthIFStats::DumpAll(FILE *fd) {
#define DP_A4(f) printf(" %-40s : %llu \n",#f, (unsigned long long)f)
#define DP_A(f) if (f) printf(" %-40s : %llu \n",#f, (unsigned long long)f)
DP_A4(opackets);
@@ -1238,18 +1239,14 @@ void CPhyEthIFStats::DumpAll(FILE *fd){
DP_A4(ibytes);
DP_A(ierrors);
DP_A(oerrors);
-
}
-
-void CPhyEthIFStats::Dump(FILE *fd){
-
+// dump all non zero counters
+void CPhyEthIFStats::Dump(FILE *fd) {
DP_A(opackets);
DP_A(obytes);
-
DP_A(f_ipackets);
DP_A(f_ibytes);
-
DP_A(ipackets);
DP_A(ibytes);
DP_A(ierrors);
@@ -1258,6 +1255,15 @@ void CPhyEthIFStats::Dump(FILE *fd){
DP_A(rx_nombuf);
}
+void CPhyEthIgnoreStats::dump(FILE *fd) {
+ DP_A4(opackets);
+ DP_A4(obytes);
+ DP_A4(ipackets);
+ DP_A4(ibytes);
+ DP_A4(m_tx_arp);
+ DP_A4(m_rx_arp);
+}
+
// Clear the RX queue of an interface, dropping all packets
void CPhyEthIF::flush_rx_queue(void){
@@ -1565,51 +1571,6 @@ void CPhyEthIF::macaddr_get(struct ether_addr *mac_addr){
rte_eth_macaddr_get(m_port_id , mac_addr);
}
-
-void CPhyEthIF::get_stats_1g(CPhyEthIFStats *stats){
-
- stats->ipackets += pci_reg_read(E1000_GPRC) ;
-
- stats->ibytes += (pci_reg_read(E1000_GORCL) );
- stats->ibytes += (((uint64_t)pci_reg_read(E1000_GORCH))<<32);
-
-
- stats->opackets += pci_reg_read(E1000_GPTC);
- stats->obytes += pci_reg_read(E1000_GOTCL) ;
- stats->obytes += ( (((uint64_t)pci_reg_read(IXGBE_GOTCH))<<32) );
-
- stats->f_ipackets += 0;
- stats->f_ibytes += 0;
-
-
- stats->ierrors += ( pci_reg_read(E1000_RNBC) +
- pci_reg_read(E1000_CRCERRS) +
- pci_reg_read(E1000_ALGNERRC ) +
- pci_reg_read(E1000_SYMERRS ) +
- pci_reg_read(E1000_RXERRC ) +
-
- pci_reg_read(E1000_ROC)+
- pci_reg_read(E1000_RUC)+
- pci_reg_read(E1000_RJC) +
-
- pci_reg_read(E1000_XONRXC)+
- pci_reg_read(E1000_XONTXC)+
- pci_reg_read(E1000_XOFFRXC)+
- pci_reg_read(E1000_XOFFTXC)+
- pci_reg_read(E1000_FCRUC)
- );
-
- stats->oerrors += 0;
- stats->imcasts = 0;
- stats->rx_nombuf = 0;
-
- m_last_tx_rate = m_bw_tx.add(stats->obytes);
- m_last_rx_rate = m_bw_rx.add(stats->ibytes);
- m_last_tx_pps = m_pps_tx.add(stats->opackets);
- m_last_rx_pps = m_pps_rx.add(stats->ipackets);
-
-}
-
int CPhyEthIF::dump_fdir_global_stats(FILE *fd) {
return get_ex_drv()->dump_fdir_global_stats(this, fd);
}
@@ -1672,8 +1633,8 @@ void dump_hw_state(FILE *fd,struct ixgbe_hw_stats *hs ){
DP_A1(mptc);
DP_A1(bptc);
DP_A1(xec);
- DP_A2(qprc,16)
- DP_A2(qptc,16);
+ DP_A2(qprc,16);
+ DP_A2(qptc,16);
DP_A2(qbrc,16);
DP_A2(qbtc,16);
DP_A2(qprdc,16);
@@ -1701,14 +1662,27 @@ void dump_hw_state(FILE *fd,struct ixgbe_hw_stats *hs ){
DP_A1(o2bspc);
}
-
-void CPhyEthIF::update_counters(){
+void CPhyEthIF::set_ignore_stats_base(CPreTestStats &pre_stats) {
+ // reading m_stats, so drivers saving prev in m_stats will be updated.
+ // Actually, we want m_stats to be cleared
get_ex_drv()->get_extended_stats(this, &m_stats);
- m_last_tx_rate = m_bw_tx.add(m_stats.obytes);
- m_last_rx_rate = m_bw_rx.add(m_stats.ibytes);
- m_last_tx_pps = m_pps_tx.add(m_stats.opackets);
- m_last_rx_pps = m_pps_rx.add(m_stats.ipackets);
+ m_ignore_stats.ipackets = m_stats.ipackets;
+ m_ignore_stats.ibytes = m_stats.ibytes;
+ m_ignore_stats.opackets = m_stats.opackets;
+ m_ignore_stats.obytes = m_stats.obytes;
+ m_stats.ipackets = 0;
+ m_stats.opackets = 0;
+ m_stats.ibytes = 0;
+ m_stats.obytes = 0;
+
+ m_ignore_stats.m_tx_arp = pre_stats.m_tx_arp;
+ m_ignore_stats.m_rx_arp = pre_stats.m_rx_arp;
+
+ if (CGlobalInfo::m_options.preview.getVMode() >= 3) {
+ fprintf(stdout, "Pre test statistics for port %d\n", get_port_id());
+ m_ignore_stats.dump(stdout);
+ }
}
void CPhyEthIF::dump_stats(FILE *fd){
@@ -2842,7 +2816,6 @@ public:
void rx_sl_configure();
bool is_all_links_are_up(bool dump=false);
void pre_test();
- int reset_counters();
/**
* mark for shutdown
@@ -3011,7 +2984,13 @@ void CGlobalTRex::pre_test() {
}
pretest.send_grat_arp_all();
- pretest.resolve_all();
+ bool ret;
+ int count = 0;
+ do {
+ ret = pretest.resolve_all();
+ count++;
+ } while ((ret != true) && (count < 3));
+
if ( CGlobalInfo::m_options.preview.getVMode() > 0) {
pretest.dump(stdout);
}
@@ -3031,22 +3010,16 @@ void CGlobalTRex::pre_test() {
CGlobalInfo::m_options.m_ip_cfg[port_id].set_grat_arp_needed(false);
}
+ // update statistics baseline, so we can ignore what happened in pre test phase
CPhyEthIF *pif = &m_ports[port_id];
+ CPreTestStats pre_stats = pretest.get_stats(port_id);
+ pif->set_ignore_stats_base(pre_stats);
+
// Configure port back to normal mode. Only relevant packets handled by software.
CTRexExtendedDriverDb::Ins()->get_drv()->set_rcv_all(pif, false);
}
}
-int CGlobalTRex::reset_counters(){
- int i;
- for (i=0; i<m_max_ports; i++) {
- CPhyEthIF * _if=&m_ports[i];
- _if->stats_clear();
- }
-
- return (0);
-}
-
/**
* check for a single core
*
@@ -3175,8 +3148,14 @@ void CGlobalTRex::ixgbe_configure_mg(void) {
if ( latency_rate ) {
mg_cfg.m_cps = (double)latency_rate ;
- }else{
- mg_cfg.m_cps = 1.0;
+ } else {
+ // If RX core needed, we need something to make the scheduler running.
+ // If nothing configured, send 1 CPS latency measurement packets.
+ if (CGlobalInfo::m_options.m_arp_ref_per == 0) {
+ mg_cfg.m_cps = 1.0;
+ } else {
+ mg_cfg.m_cps = 0;
+ }
}
if ( get_vm_one_queue_enable() ) {
@@ -3657,6 +3636,8 @@ void CGlobalTRex::dump_post_test_stats(FILE *fd){
uint64_t sw_pkt_out=0;
uint64_t sw_pkt_out_err=0;
uint64_t sw_pkt_out_bytes=0;
+ uint64_t tx_arp = 0;
+ uint64_t rx_arp = 0;
int i;
for (i=0; i<get_cores_tx(); i++) {
@@ -3675,6 +3656,8 @@ void CGlobalTRex::dump_post_test_stats(FILE *fd){
pkt_in_bytes +=_if->get_stats().ibytes;
pkt_out +=_if->get_stats().opackets;
pkt_out_bytes +=_if->get_stats().obytes;
+ tx_arp += _if->get_ignore_stats().get_tx_arp();
+ rx_arp += _if->get_ignore_stats().get_rx_arp();
}
if ( CGlobalInfo::m_options.is_latency_enabled() ){
sw_pkt_out += m_mg.get_total_pkt();
@@ -3703,6 +3686,8 @@ void CGlobalTRex::dump_post_test_stats(FILE *fd){
fprintf (fd," Total-rx-pkt : %llu pkts \n", (unsigned long long)pkt_in);
fprintf (fd," Total-sw-tx-pkt : %llu pkts \n", (unsigned long long)sw_pkt_out);
fprintf (fd," Total-sw-err : %llu pkts \n", (unsigned long long)sw_pkt_out_err);
+ fprintf (fd," Total ARP sent : %llu pkts \n", (unsigned long long)tx_arp);
+ fprintf (fd," Total ARP received : %llu pkts \n", (unsigned long long)rx_arp);
if ( CGlobalInfo::m_options.is_latency_enabled() ){
@@ -4550,6 +4535,22 @@ int CGlobalTRex::start_master_statefull() {
////////////////////////////////////////////
static CGlobalTRex g_trex;
+void CPhyEthIF::update_counters() {
+ get_ex_drv()->get_extended_stats(this, &m_stats);
+ CRXCoreIgnoreStat ign_stats;
+ g_trex.m_mg.get_ignore_stats(m_port_id, ign_stats, true);
+ m_stats.obytes -= ign_stats.get_tx_bytes();
+ m_stats.opackets -= ign_stats.get_tx_pkts();
+ m_ignore_stats.opackets += ign_stats.get_tx_pkts();
+ m_ignore_stats.obytes += ign_stats.get_tx_bytes();
+ m_ignore_stats.m_tx_arp += ign_stats.get_tx_arp();
+
+ m_last_tx_rate = m_bw_tx.add(m_stats.obytes);
+ m_last_rx_rate = m_bw_rx.add(m_stats.ibytes);
+ m_last_tx_pps = m_pps_tx.add(m_stats.opackets);
+ m_last_rx_pps = m_pps_rx.add(m_stats.ipackets);
+}
+
bool CPhyEthIF::Create(uint8_t portid) {
m_port_id = portid;
m_last_rx_rate = 0.0;
@@ -5140,18 +5141,6 @@ int main_test(int argc , char * argv[]){
/* set dump mode */
g_trex.m_io_modes.set_mode((CTrexGlobalIoMode::CliDumpMode)CGlobalInfo::m_options.m_io_mode);
- if ( CGlobalInfo::m_options.is_latency_enabled()
- && (CGlobalInfo::m_options.m_latency_prev > 0)) {
- uint32_t pkts = CGlobalInfo::m_options.m_latency_prev *
- CGlobalInfo::m_options.m_latency_rate;
- printf("Starting pre latency check for %d sec\n",CGlobalInfo::m_options.m_latency_prev);
- g_trex.m_mg.start(pkts, NULL);
- delay(CGlobalInfo::m_options.m_latency_prev* 1000);
- printf("Finished \n");
- g_trex.m_mg.reset();
- g_trex.reset_counters();
- }
-
/* disable WD if needed */
bool wd_enable = (CGlobalInfo::m_options.preview.getWDDisable() ? false : true);
TrexWatchDog::getInstance().init(wd_enable);
@@ -5211,6 +5200,7 @@ int main_test(int argc , char * argv[]){
}
g_trex.pre_test();
+
// after doing all needed ARP resolution, we need to flush queues, and stop our drop queue
g_trex.ixgbe_rx_queue_flush();
for (int i = 0; i < g_trex.m_max_ports; i++) {
@@ -5218,6 +5208,17 @@ int main_test(int argc , char * argv[]){
_if->stop_rx_drop_queue();
}
+ if ( CGlobalInfo::m_options.is_latency_enabled()
+ && (CGlobalInfo::m_options.m_latency_prev > 0)) {
+ uint32_t pkts = CGlobalInfo::m_options.m_latency_prev *
+ CGlobalInfo::m_options.m_latency_rate;
+ printf("Starting warm up phase for %d sec\n",CGlobalInfo::m_options.m_latency_prev);
+ g_trex.m_mg.start(pkts, NULL);
+ delay(CGlobalInfo::m_options.m_latency_prev* 1000);
+ printf("Finished \n");
+ g_trex.m_mg.reset();
+ }
+
if ( CGlobalInfo::m_options.preview.getOnlyLatency() ){
rte_eal_mp_remote_launch(latency_one_lcore, NULL, CALL_MASTER);
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
@@ -6054,20 +6055,32 @@ int CTRexExtendedDriverBase40G::dump_fdir_global_stats(CPhyEthIF * _if, FILE *fd
}
}
-void CTRexExtendedDriverBase40G::get_extended_stats(CPhyEthIF * _if,CPhyEthIFStats *stats){
+void CTRexExtendedDriverBase40G::get_extended_stats(CPhyEthIF * _if,CPhyEthIFStats *stats) {
struct rte_eth_stats stats1;
+ struct rte_eth_stats *prev_stats = &stats->m_prev_stats;
rte_eth_stats_get(_if->get_port_id(), &stats1);
- stats->ipackets = stats1.ipackets;
- stats->ibytes = stats1.ibytes ;
- stats->opackets = stats1.opackets;
- stats->obytes = stats1.obytes + (stats1.opackets<<2);
- stats->f_ipackets = 0;
- stats->f_ibytes = 0;
- stats->ierrors = stats1.imissed + stats1.ierrors + stats1.rx_nombuf;
- stats->oerrors = stats1.oerrors;;
- stats->imcasts = 0;
- stats->rx_nombuf = stats1.rx_nombuf;
+ stats->ipackets += stats1.ipackets - prev_stats->ipackets;
+ stats->ibytes += stats1.ibytes - prev_stats->ibytes;
+ stats->opackets += stats1.opackets - prev_stats->opackets;
+ stats->obytes += stats1.obytes - prev_stats->obytes
+ + (stats1.opackets << 2) - (prev_stats->opackets << 2);
+ stats->f_ipackets += 0;
+ stats->f_ibytes += 0;
+ stats->ierrors += stats1.imissed + stats1.ierrors + stats1.rx_nombuf
+ - prev_stats->imissed - prev_stats->ierrors - prev_stats->rx_nombuf;
+ stats->oerrors += stats1.oerrors - prev_stats->oerrors;
+ stats->imcasts += 0;
+ stats->rx_nombuf += stats1.rx_nombuf - prev_stats->rx_nombuf;
+
+ prev_stats->ipackets = stats1.ipackets;
+ prev_stats->ibytes = stats1.ibytes;
+ prev_stats->opackets = stats1.opackets;
+ prev_stats->obytes = stats1.obytes;
+ prev_stats->imissed = stats1.imissed;
+ prev_stats->oerrors = stats1.oerrors;
+ prev_stats->ierrors = stats1.ierrors;
+ prev_stats->rx_nombuf = stats1.rx_nombuf;
}
int CTRexExtendedDriverBase40G::wait_for_stable_link(){
@@ -6154,31 +6167,30 @@ int CTRexExtendedDriverBase1GVm::stop_queue(CPhyEthIF * _if, uint16_t q_num) {
}
void CTRexExtendedDriverBase1GVm::get_extended_stats(CPhyEthIF * _if,CPhyEthIFStats *stats){
-
struct rte_eth_stats stats1;
+ struct rte_eth_stats *prev_stats = &stats->m_prev_stats;
rte_eth_stats_get(_if->get_port_id(), &stats1);
-
- stats->ipackets = stats1.ipackets;
- stats->ibytes = stats1.ibytes;
-
- stats->opackets = stats1.opackets;
- stats->obytes = stats1.obytes;
-
- stats->f_ipackets = 0;
- stats->f_ibytes = 0;
-
-
- stats->ierrors = stats1.imissed +
- stats1.ierrors +
- stats1.oerrors +
- stats1.rx_nombuf;
-
-
- stats->oerrors = stats1.oerrors;;
- stats->imcasts = 0;
- stats->rx_nombuf = stats1.rx_nombuf;
-
+ stats->ipackets += stats1.ipackets - prev_stats->ipackets;
+ stats->ibytes += stats1.ibytes - prev_stats->ibytes;
+ stats->opackets += stats1.opackets - prev_stats->opackets;
+ stats->obytes += stats1.obytes - prev_stats->obytes;
+ stats->f_ipackets += 0;
+ stats->f_ibytes += 0;
+ stats->ierrors += stats1.imissed + stats1.ierrors + stats1.rx_nombuf
+ - prev_stats->imissed - prev_stats->ierrors - prev_stats->rx_nombuf;
+ stats->oerrors += stats1.oerrors - prev_stats->oerrors;
+ stats->imcasts += 0;
+ stats->rx_nombuf += stats1.rx_nombuf - prev_stats->rx_nombuf;
+
+ prev_stats->ipackets = stats1.ipackets;
+ prev_stats->ibytes = stats1.ibytes;
+ prev_stats->opackets = stats1.opackets;
+ prev_stats->obytes = stats1.obytes;
+ prev_stats->imissed = stats1.imissed;
+ prev_stats->oerrors = stats1.oerrors;
+ prev_stats->ierrors = stats1.ierrors;
+ prev_stats->rx_nombuf = stats1.rx_nombuf;
}
int CTRexExtendedDriverBase1GVm::wait_for_stable_link(){
diff --git a/src/main_dpdk.h b/src/main_dpdk.h
index bde10659..97994c47 100644
--- a/src/main_dpdk.h
+++ b/src/main_dpdk.h
@@ -18,6 +18,7 @@
#define MAIN_DPDK_H
#include <rte_ethdev.h>
+#include "pre_test.h"
#include "bp_sim.h"
enum {
@@ -25,9 +26,29 @@ enum {
MAIN_DPDK_RX_Q = 1,
};
-class CPhyEthIFStats {
+// These are statistics for packets we send, and do not expect to get back (Like ARP)
+// We reduce them from general statistics we report (and report them separately, so we can keep the assumption
+// that tx_pkts == rx_pkts and tx_bytes==rx_bytes
+class CPhyEthIgnoreStats {
+ friend class CPhyEthIF;
public:
+ uint64_t get_rx_arp() {return m_rx_arp;}
+ uint64_t get_tx_arp() {return m_tx_arp;}
+ private:
+ uint64_t ipackets; /**< Total number of successfully received packets. */
+ uint64_t ibytes; /**< Total number of successfully received bytes. */
+ uint64_t opackets; /**< Total number of successfully transmitted packets.*/
+ uint64_t obytes; /**< Total number of successfully transmitted bytes. */
+ uint64_t m_tx_arp; /**< Total number of successfully transmitted ARP packets */
+ uint64_t m_rx_arp; /**< Total number of successfully received ARP packets */
+
+ private:
+ void dump(FILE *fd);
+};
+
+class CPhyEthIFStats {
+ public:
uint64_t ipackets; /**< Total number of successfully received packets. */
uint64_t ibytes; /**< Total number of successfully received bytes. */
uint64_t f_ipackets; /**< Total number of successfully received packets - filter SCTP*/
@@ -38,6 +59,7 @@ class CPhyEthIFStats {
uint64_t oerrors; /**< Total number of failed transmitted packets. */
uint64_t imcasts; /**< Total number of multicast received packets. */
uint64_t rx_nombuf; /**< Total number of RX mbuf allocation failures. */
+ struct rte_eth_stats m_prev_stats;
uint64_t m_rx_per_flow_pkts [MAX_FLOW_STATS]; // Per flow RX pkts
uint64_t m_rx_per_flow_bytes[MAX_FLOW_STATS]; // Per flow RX bytes
// Previous fdir stats values read from driver. Since on xl710 this is 32 bit, we save old value, to handle wrap around.
@@ -71,7 +93,6 @@ class CPhyEthIF {
int reset_hw_flow_stats();
int get_flow_stats(rx_per_flow_t *rx_stats, tx_per_flow_t *tx_stats, int min, int max, bool reset);
int get_flow_stats_payload(rx_per_flow_t *rx_stats, tx_per_flow_t *tx_stats, int min, int max, bool reset);
- void get_stats_1g(CPhyEthIFStats *stats);
void rx_queue_setup(uint16_t rx_queue_id,
uint16_t nb_rx_desc,
unsigned int socket_id,
@@ -99,6 +120,7 @@ class CPhyEthIF {
void add_mac(char * mac);
bool get_promiscuous();
void dump_stats(FILE *fd);
+ void set_ignore_stats_base(CPreTestStats &pre_stats);
void update_counters();
void stats_clear();
uint8_t get_port_id(){
@@ -120,6 +142,9 @@ class CPhyEthIF {
CPhyEthIFStats & get_stats(){
return ( m_stats );
}
+ CPhyEthIgnoreStats & get_ignore_stats() {
+ return m_ignore_stats;
+ }
void flush_dp_rx_queue(void);
void flush_rx_queue(void);
int add_rx_flow_stat_rule(uint8_t port_id, uint16_t l3_type, uint8_t l4_proto
@@ -167,6 +192,7 @@ class CPhyEthIF {
CPPSMeasure m_pps_tx;
CPPSMeasure m_pps_rx;
CPhyEthIFStats m_stats;
+ CPhyEthIgnoreStats m_ignore_stats;
float m_last_tx_rate;
float m_last_rx_rate;
float m_last_tx_pps;
diff --git a/src/test_pkt_gen.cpp b/src/pkt_gen.cpp
index 502e84dc..eb9a26f9 100644
--- a/src/test_pkt_gen.cpp
+++ b/src/pkt_gen.cpp
@@ -29,7 +29,7 @@
#include <common/Network/Packet/EthernetHeader.h>
#include <common/Network/Packet/Arp.h>
#include "rx_check_header.h"
-#include "test_pkt_gen.h"
+#include "pkt_gen.h"
// For use in tests
char *CTestPktGen::create_test_pkt(uint16_t l3_type, uint16_t l4_proto, uint8_t ttl, uint32_t ip_id, uint16_t flags
diff --git a/src/test_pkt_gen.h b/src/pkt_gen.h
index 4257c9ae..309e02b9 100644
--- a/src/test_pkt_gen.h
+++ b/src/pkt_gen.h
@@ -19,14 +19,15 @@
limitations under the License.
*/
-#ifndef __TEST_PKT_GEN_H__
-#define __TEST_PKT_GEN_H__
+#ifndef __PKT_GEN_H__
+#define __PKT_GEN_H__
enum {
D_PKT_TYPE_ICMP = 1,
D_PKT_TYPE_UDP = 2,
D_PKT_TYPE_TCP = 3,
- D_PKT_TYPE_9k_UDP = 4,
+ D_PKT_TYPE_ARP = 4,
+ D_PKT_TYPE_9k_UDP = 5,
D_PKT_TYPE_IPV6 = 60,
D_PKT_TYPE_HW_VERIFY = 100,
D_PKT_TYPE_HW_VERIFY_RCV_ALL = 101,
diff --git a/src/pre_test.cpp b/src/pre_test.cpp
index 0639d9c8..278db98b 100644
--- a/src/pre_test.cpp
+++ b/src/pre_test.cpp
@@ -26,10 +26,9 @@
#include "common/basic_utils.h"
#include "bp_sim.h"
#include "main_dpdk.h"
-#include "test_pkt_gen.h"
+#include "pkt_gen.h"
#include "pre_test.h"
-
void CPretestPortInfo::set_params(CPerPortIPCfg port_cfg, const uint8_t *src_mac, bool resolve_needed) {
m_ip = port_cfg.get_ip();
m_def_gw = port_cfg.get_def_gw();
@@ -73,18 +72,24 @@ void CPretestPortInfo::dump(FILE *fd) {
put in mac relevant dest MAC for port/ip pair.
return false if no relevant info exists, true otherwise.
*/
-bool CPretest::get_mac(uint16_t port, uint32_t ip, uint8_t *mac) {
- assert(port < TREX_MAX_PORTS);
+bool CPretest::get_mac(uint16_t port_id, uint32_t ip, uint8_t *mac) {
+ assert(port_id < TREX_MAX_PORTS);
- if (m_port_info[port].m_state != CPretestPortInfo::RESOLVE_DONE) {
+ if (m_port_info[port_id].m_state != CPretestPortInfo::RESOLVE_DONE) {
return false;
}
- memcpy(mac, &m_port_info[port].m_dst_mac, sizeof(m_port_info[port].m_dst_mac));
+ memcpy(mac, &m_port_info[port_id].m_dst_mac, sizeof(m_port_info[port_id].m_dst_mac));
return true;
}
+CPreTestStats CPretest::get_stats(uint16_t port_id) {
+ assert(port_id < TREX_MAX_PORTS);
+
+ return m_port_info[port_id].m_stats;
+}
+
bool CPretest::is_loopback(uint16_t port) {
assert(port < TREX_MAX_PORTS);
@@ -104,22 +109,26 @@ int CPretest::handle_rx(int port_id, int queue_id) {
uint16_t cnt;
int i;
int verbose = CGlobalInfo::m_options.preview.getVMode();
-
- cnt = rte_eth_rx_burst(port_id, queue_id, rx_pkts, sizeof(rx_pkts)/sizeof(rx_pkts[0]));
-
- for (i = 0; i < cnt; i++) {
- rte_mbuf_t * m = rx_pkts[i];
- int pkt_size = rte_pktmbuf_pkt_len(m);
- uint8_t *p = rte_pktmbuf_mtod(m, uint8_t *);
- ArpHdr *arp;
- CPretestPortInfo *port = &m_port_info[port_id];
- if (is_arp(p, pkt_size, arp)) {
- if (arp->m_arp_op == htons(ArpHdr::ARP_HDR_OP_REQUEST)) {
- if (verbose >= 3) {
- fprintf(stdout, "RX ARP request on port %d queue %d sip:0x%08x tip:0x%08x\n", port_id, queue_id
- , ntohl(arp->m_arp_sip)
- , ntohl(arp->m_arp_tip));
- }
+ int tries = 0;
+
+ do {
+ cnt = rte_eth_rx_burst(port_id, queue_id, rx_pkts, sizeof(rx_pkts)/sizeof(rx_pkts[0]));
+ tries++;
+
+ for (i = 0; i < cnt; i++) {
+ rte_mbuf_t * m = rx_pkts[i];
+ int pkt_size = rte_pktmbuf_pkt_len(m);
+ uint8_t *p = rte_pktmbuf_mtod(m, uint8_t *);
+ ArpHdr *arp;
+ CPretestPortInfo *port = &m_port_info[port_id];
+ if (is_arp(p, pkt_size, arp)) {
+ m_port_info[port_id].m_stats.m_rx_arp++;
+ if (arp->m_arp_op == htons(ArpHdr::ARP_HDR_OP_REQUEST)) {
+ if (verbose >= 3) {
+ fprintf(stdout, "RX ARP request on port %d queue %d sip:0x%08x tip:0x%08x\n", port_id, queue_id
+ , ntohl(arp->m_arp_sip)
+ , ntohl(arp->m_arp_tip));
+ }
// is this request for our IP?
if (ntohl(arp->m_arp_tip) == port->m_ip) {
// If our request(i.e. we are connected in loopback)
@@ -137,23 +146,24 @@ int CPretest::handle_rx(int port_id, int queue_id) {
} else {
// ARP request not to our IP. At the moment, we ignore this.
}
- } else {
- if (arp->m_arp_op == htons(ArpHdr::ARP_HDR_OP_REPLY)) {
- if (verbose >= 3) {
- fprintf(stdout, "RX ARP response on port %d queue %d sip:0x%08x tip:0x%08x\n", port_id, queue_id
- , ntohl(arp->m_arp_sip)
- , ntohl(arp->m_arp_tip));
- }
- // If this is response to our request, update our tables
- if (port->m_def_gw == ntohl(arp->m_arp_sip)) {
- port->set_dst_mac((uint8_t *)&arp->m_arp_sha);
+ } else {
+ if (arp->m_arp_op == htons(ArpHdr::ARP_HDR_OP_REPLY)) {
+ if (verbose >= 3) {
+ fprintf(stdout, "RX ARP response on port %d queue %d sip:0x%08x tip:0x%08x\n", port_id, queue_id
+ , ntohl(arp->m_arp_sip)
+ , ntohl(arp->m_arp_tip));
+ }
+ // If this is response to our request, update our tables
+ if (port->m_def_gw == ntohl(arp->m_arp_sip)) {
+ port->set_dst_mac((uint8_t *)&arp->m_arp_sha);
+ }
}
}
}
+ rte_pktmbuf_free(m);
}
+ } while ((cnt != 0) && (tries < 1000));
- rte_pktmbuf_free(m);
- }
return 0;
}
@@ -242,6 +252,8 @@ void CPretest::send_arp_req(uint16_t port_id, bool is_grat) {
if (num_sent < 1) {
fprintf(stderr, "Failed sending ARP to port:%d\n", port_id);
exit(1);
+ } else {
+ m_port_info[port_id].m_stats.m_tx_arp++;
}
}
diff --git a/src/pre_test.h b/src/pre_test.h
index 7bbeb40d..ad7608a6 100644
--- a/src/pre_test.h
+++ b/src/pre_test.h
@@ -27,6 +27,18 @@
#include "bp_sim.h"
#include "trex_defs.h"
+class CPreTestStats {
+ public:
+ uint32_t m_rx_arp; // how many ARP packets we received
+ uint32_t m_tx_arp; // how many ARP packets we sent
+
+ public:
+ void clear() {
+ m_rx_arp = 0;
+ m_tx_arp = 0;
+ }
+};
+
class CPretestPortInfo {
friend class CPretest;
@@ -41,6 +53,7 @@ class CPretestPortInfo {
CPretestPortInfo() {
m_state = INIT_NEEDED;
m_is_loopback = false;
+ m_stats.clear();
}
void dump(FILE *fd);
uint8_t *create_arp_req(uint16_t &pkt_size, uint8_t port, bool is_grat);
@@ -55,6 +68,7 @@ class CPretestPortInfo {
uint8_t m_dst_mac[6];
enum CPretestPortInfoStates m_state;
bool m_is_loopback;
+ CPreTestStats m_stats;
};
@@ -64,6 +78,7 @@ class CPretest {
m_max_ports = max_ports;
}
bool get_mac(uint16_t port, uint32_t ip, uint8_t *mac);
+ CPreTestStats get_stats(uint16_t port_id);
bool is_loopback(uint16_t port);
void set_port_params(uint16_t port_id, const CPerPortIPCfg &port_cfg, const uint8_t *src_mac, bool resolve_needed);
bool resolve_all();
diff --git a/src/latency.cpp b/src/stateful_rx_core.cpp
index 76f12b46..ebc51fcb 100644
--- a/src/latency.cpp
+++ b/src/stateful_rx_core.cpp
@@ -5,7 +5,7 @@
*/
/*
-Copyright (c) 2015-2015 Cisco Systems, Inc.
+Copyright (c) 2015-2016 Cisco Systems, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -23,11 +23,11 @@ limitations under the License.
#include "flow_stat_parser.h"
#include "utl_json.h"
#include "trex_watchdog.h"
-#include "test_pkt_gen.h"
+#include "pkt_gen.h"
#include "common/basic_utils.h"
-#include "latency.h"
+#include "stateful_rx_core.h"
-const uint8_t sctp_pkt[]={
+const uint8_t sctp_pkt[]={
0x00,0x04,0x96,0x08,0xe0,0x40,
0x00,0x0e,0x2e,0x24,0x37,0x5f,
@@ -42,9 +42,9 @@ const uint8_t sctp_pkt[]={
0x80,0x44,//SPORT
0x00,0x50,//DPORT
- 0x00,0x00,0x00,0x00, //checksum
+ 0x00,0x00,0x00,0x00, //checksum
- 0x11,0x22,0x33,0x44, // magic
+ 0x11,0x22,0x33,0x44, // magic
0x00,0x00,0x00,0x00, //64 bit counter
0x00,0x00,0x00,0x00,
0x00,0x01,0xa0,0x00, //seq
@@ -63,18 +63,18 @@ const uint8_t icmp_pkt[]={
0x9b,0xe6,0x18,0x9b, //SIP
0xcb,0xff,0xfc,0xc2, //DIP
- 0x08, 0x00,
+ 0x08, 0x00,
0x01, 0x02, //checksum
0xaa, 0xbb, // id
0x00, 0x00, // Sequence number
- 0x11,0x22,0x33,0x44, // magic
+ 0x11,0x22,0x33,0x44, // magic
0x00,0x00,0x00,0x00, //64 bit counter
0x00,0x00,0x00,0x00,
0x00,0x01,0xa0,0x00, //seq
0x00,0x00,0x00,0x00,
-};
+};
void CLatencyPktInfo::Create(class CLatencyPktMode *m_l_pkt_info){
@@ -123,7 +123,7 @@ void CLatencyPktInfo::Create(class CLatencyPktMode *m_l_pkt_info){
m_dummy_node.m_src_port = 0x11;
m_dummy_node.m_flow_id =0;
m_dummy_node.m_flags =CGenNode::NODE_FLAGS_LATENCY;
-
+
}
rte_mbuf_t * CLatencyPktInfo::generate_pkt(int port_id,uint32_t extern_ip){
@@ -172,7 +172,8 @@ void CCPortLatency::reset(){
m_pad = 0;
m_tx_pkt_err=0;
m_tx_pkt_ok =0;
- m_tx_grat_arp_ok =0;
+ m_ign_stats.clear();
+ m_ign_stats_prev.clear();
m_pkt_ok=0;
m_rx_check=0;
m_no_magic=0;
@@ -231,13 +232,13 @@ void CCPortLatency::update_packet(rte_mbuf_t * m, int port_id){
m_tx_seq++;
CLatencyPktMode *c_l_pkt_mode = m_parent->c_l_pkt_mode;
- c_l_pkt_mode->update_pkt(p + m_l4_offset, is_client_to_server, m_pkt_size - m_l4_offset, &m_icmp_tx_seq);
+ c_l_pkt_mode->update_pkt(p + m_l4_offset, is_client_to_server, m_pkt_size - m_l4_offset, &m_icmp_tx_seq);
}
-void CCPortLatency::DumpShortHeader(FILE *fd){
+void CCPortLatency::DumpShortHeader(FILE *fd){
fprintf(fd," if| tx_ok , rx_ok , rx check ,error, latency (usec) , Jitter max window \n");
- fprintf(fd," | , , , , average , max , (usec) \n");
+ fprintf(fd," | , , , , average , max , (usec) \n");
fprintf(fd," ---------------------------------------------------------------------------------------------------------------- \n");
}
@@ -271,7 +272,7 @@ void CCPortLatency::dump_json(std::string & json ){
void CCPortLatency::DumpShort(FILE *fd){
// m_hist.update(); <- moved to CLatencyManager::update()
- fprintf(fd,"%8lu,%8lu,%10lu,%5lu,",
+ fprintf(fd,"%8lu,%8lu,%10lu,%5lu,",
m_tx_pkt_ok,
m_pkt_ok,
m_rx_check,
@@ -283,8 +284,8 @@ void CCPortLatency::DumpShort(FILE *fd){
m_hist.get_max_latency(),
get_jitter_usec()
);
- fprintf(fd," | ");
- m_hist.DumpWinMax(fd);
+ fprintf(fd," | ");
+ m_hist.DumpWinMax(fd);
}
@@ -295,7 +296,9 @@ void CCPortLatency::dump_counters_json(std::string & json ){
json+="\"stats\" : {";
DPL_J(m_tx_pkt_ok);
- DPL_J(m_tx_grat_arp_ok);
+ json+=add_json("tx_arp", m_ign_stats.get_tx_arp());
+ json+=add_json("ipv6_n_solic", m_ign_stats.get_tx_n_solic());
+ json+=add_json("ignore_bytes", m_ign_stats.get_tx_bytes());
DPL_J(m_tx_pkt_err);
DPL_J(m_pkt_ok);
DPL_J(m_unsup_prot);
@@ -313,14 +316,14 @@ void CCPortLatency::dump_counters_json(std::string & json ){
}
void CCPortLatency::DumpCounters(FILE *fd){
- #define DP_A1(f) if (f) fprintf(fd," %-40s : %llu \n",#f, (unsigned long long)f)
+#define DP_A1(f) if (f) fprintf(fd," %-40s : %llu \n",#f, (unsigned long long)f)
+#define DP_A2(str, f) if (f) fprintf(fd," %-40s : %llu \n", str, (unsigned long long)f)
fprintf(fd," counter \n");
fprintf(fd," -----------\n");
DP_A1(m_tx_pkt_err);
DP_A1(m_tx_pkt_ok);
- DP_A1(m_tx_grat_arp_ok);
DP_A1(m_pkt_ok);
DP_A1(m_unsup_prot);
DP_A1(m_no_magic);
@@ -329,7 +332,9 @@ void CCPortLatency::DumpCounters(FILE *fd){
DP_A1(m_length_error);
DP_A1(m_rx_check);
DP_A1(m_no_ipv4_option);
-
+ DP_A2("tx_arp", m_ign_stats.get_tx_arp());
+ DP_A2("ipv6_n_solic", m_ign_stats.get_tx_n_solic());
+ DP_A2("ignore_bytes", m_ign_stats.get_tx_bytes());
fprintf(fd," -----------\n");
m_hist.Dump(fd);
@@ -338,8 +343,8 @@ void CCPortLatency::DumpCounters(FILE *fd){
bool CCPortLatency::dump_packet(rte_mbuf_t * m){
fprintf(stdout," %f.03 dump packet ..\n",now_sec());
- uint8_t *p=rte_pktmbuf_mtod(m, uint8_t*);
- uint16_t pkt_size=rte_pktmbuf_pkt_len(m);
+ uint8_t *p=rte_pktmbuf_mtod(m, uint8_t*);
+ uint16_t pkt_size=rte_pktmbuf_pkt_len(m);
utl_DumpBuffer(stdout,p,pkt_size,0);
return (0);
#if 0
@@ -350,7 +355,7 @@ bool CCPortLatency::dump_packet(rte_mbuf_t * m){
lp->dump(stdout);
- return (0);
+ return (0);
#endif
}
@@ -372,7 +377,7 @@ bool CCPortLatency::check_packet(rte_mbuf_t * m,CRx_check_header * & rx_p) {
if ( !parser.Parse() ) {
m_unsup_prot++; // Unsupported protocol
return (false);
- }
+ }
CLatencyPktMode *c_l_pkt_mode = m_parent->c_l_pkt_mode;
uint16_t pkt_size=rte_pktmbuf_pkt_len(m);
uint16_t vlan_offset=parser.m_vlan_offset;
@@ -492,7 +497,7 @@ void CLatencyManager::Delete(){
}
/* 0->1
- 1->0
+ 1->0
2->3
3->2
*/
@@ -516,7 +521,7 @@ bool CLatencyManager::Create(CLatencyManagerCfg * cfg){
c_l_pkt_mode = (CLatencyPktModeICMP *) new CLatencyPktModeICMP(CGlobalInfo::m_options.get_l_pkt_mode());
break;
}
-
+
m_max_ports=cfg->m_max_ports;
assert (m_max_ports <= TREX_MAX_PORTS);
assert ((m_max_ports%2)==0);
@@ -537,10 +542,12 @@ bool CLatencyManager::Create(CLatencyManagerCfg * cfg){
m_pkt_gen.get_pkt_size(),lpo );
}
m_cps= cfg->m_cps;
- m_d_time =ptime_convert_dsec_hr((1.0/m_cps));
- m_delta_sec =(1.0/m_cps);
+ if (m_cps != 0) {
+ m_delta_sec =(1.0/m_cps);
+ } else {
+ m_delta_sec = 0.0;
+ }
-
if ( get_is_rx_check_mode() ) {
assert(m_rx_check_manager.Create());
m_rx_check_manager.m_cur_time= now_sec();
@@ -602,7 +609,8 @@ void CLatencyManager::send_grat_arp_all_ports() {
}
if ( lp->m_io->tx(m) == 0 ) {
- lp->m_port.m_tx_grat_arp_ok++;
+ lp->m_port.m_ign_stats.m_tx_arp++;
+ lp->m_port.m_ign_stats.m_tot_bytes += 64; // mbuf size is smaller, but 64 bytes will be sent
} else {
lp->m_port.m_tx_pkt_err++;
}
@@ -610,26 +618,26 @@ void CLatencyManager::send_grat_arp_all_ports() {
}
void CLatencyManager::wait_for_rx_dump(){
- rte_mbuf_t * rx_pkts[64];
- int i;
- while ( true ) {
- rte_pause();
- rte_pause();
- rte_pause();
- for (i=0; i<m_max_ports; i++) {
- CLatencyManagerPerPort * lp=&m_ports[i];
- rte_mbuf_t * m;
- uint16_t cnt_p = lp->m_io->rx_burst(rx_pkts, 64);
- if (cnt_p) {
- int j;
- for (j=0; j<cnt_p; j++) {
- m=rx_pkts[j] ;
- lp->m_port.dump_packet( m);
- rte_pktmbuf_free(m);
- }
- } /*cnt_p*/
- }/* for*/
- }
+ rte_mbuf_t * rx_pkts[64];
+ int i;
+ while ( true ) {
+ rte_pause();
+ rte_pause();
+ rte_pause();
+ for (i=0; i<m_max_ports; i++) {
+ CLatencyManagerPerPort * lp=&m_ports[i];
+ rte_mbuf_t * m;
+ uint16_t cnt_p = lp->m_io->rx_burst(rx_pkts, 64);
+ if (cnt_p) {
+ int j;
+ for (j=0; j<cnt_p; j++) {
+ m=rx_pkts[j] ;
+ lp->m_port.dump_packet( m);
+ rte_pktmbuf_free(m);
+ }
+ } /*cnt_p*/
+ }/* for*/
+ }
}
@@ -744,15 +752,17 @@ void CLatencyManager::start(int iter, bool activate_watchdog) {
node->m_time = now_sec()+0.007;
m_p_queue.push(node);
- node = new CGenNode();
- node->m_type = CGenNode::FLOW_PKT; /* latency */
- node->m_time = now_sec(); /* 1/cps rate */
- m_p_queue.push(node);
+ if (m_delta_sec > 0) {
+ node = new CGenNode();
+ node->m_type = CGenNode::FLOW_PKT; /* latency */
+ node->m_time = now_sec(); /* 1/cps rate */
+ m_p_queue.push(node);
+ }
if (CGlobalInfo::m_options.m_arp_ref_per > 0) {
node = new CGenNode();
node->m_type = CGenNode::GRAT_ARP; /* gratuitous ARP */
- node->m_time = now_sec() + CGlobalInfo::m_options.m_arp_ref_per;
+ node->m_time = now_sec() + (double) CGlobalInfo::m_options.m_arp_ref_per;
m_p_queue.push(node);
}
@@ -807,7 +817,7 @@ void CLatencyManager::start(int iter, bool activate_watchdog) {
m_cpu_dp_u.start_work1();
send_grat_arp_all_ports();
m_p_queue.pop();
- node->m_time += CGlobalInfo::m_options.m_arp_ref_per;
+ node->m_time += (double)CGlobalInfo::m_options.m_arp_ref_per;
m_p_queue.push(node);
m_cpu_dp_u.commit1();
break;
@@ -822,7 +832,7 @@ void CLatencyManager::start(int iter, bool activate_watchdog) {
printf("stop due iter %d\n",iter);
break;
}
- }
+ }
cnt++;
}
@@ -853,6 +863,20 @@ bool CLatencyManager::is_active(){
return (m_is_active);
}
+// return the statistics we want to ignore for port port_id
+// stat - hold values we return.
+// if get_diff is true, return diff from last read. Else return total.
+void CLatencyManager::get_ignore_stats(int port_id, CRXCoreIgnoreStat &stat, bool get_diff) {
+ CLatencyManagerPerPort * lp = &m_ports[port_id];
+ CRXCoreIgnoreStat temp;
+ temp = lp->m_port.m_ign_stats;
+ if (get_diff) {
+ stat = temp - lp->m_port.m_ign_stats_prev;
+ lp->m_port.m_ign_stats_prev = temp;
+ } else {
+ stat = lp->m_port.m_ign_stats;
+ }
+}
double CLatencyManager::get_max_latency(){
double l=0.0;
diff --git a/src/latency.h b/src/stateful_rx_core.h
index 2f8a1134..3fa5892f 100644
--- a/src/latency.h
+++ b/src/stateful_rx_core.h
@@ -1,5 +1,3 @@
-#ifndef LATENCY_H
-#define LATENCY_H
/*
Hanoh Haim
Ido Barnea
@@ -7,7 +5,7 @@
*/
/*
-Copyright (c) 2015-2015 Cisco Systems, Inc.
+Copyright (c) 2015-2016 Cisco Systems, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -21,6 +19,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
+#ifndef __STATEFUL_RX_CORE_H__
+#define __STATEFUL_RX_CORE_H__
+
#include "bp_sim.h"
#include "flow_stat.h"
@@ -30,6 +31,33 @@ limitations under the License.
class TrexWatchDog;
+class CRXCoreIgnoreStat {
+ friend class CCPortLatency;
+ friend class CLatencyManager;
+ public:
+ inline CRXCoreIgnoreStat operator- (const CRXCoreIgnoreStat &t_in) {
+ CRXCoreIgnoreStat t_out;
+ t_out.m_tx_arp = this->m_tx_arp - t_in.m_tx_arp;
+ t_out.m_tx_ipv6_n_solic = this->m_tx_ipv6_n_solic - t_in.m_tx_ipv6_n_solic;
+ t_out.m_tot_bytes = this->m_tot_bytes - t_in.m_tot_bytes;
+ return t_out;
+ }
+ uint64_t get_tx_bytes() {return m_tot_bytes;}
+ uint64_t get_tx_pkts() {return m_tx_arp + m_tx_ipv6_n_solic;}
+ uint64_t get_tx_arp() {return m_tx_arp;}
+ uint64_t get_tx_n_solic() {return m_tx_ipv6_n_solic;}
+ void clear() {
+ m_tx_arp = 0;
+ m_tx_ipv6_n_solic = 0;
+ m_tot_bytes = 0;
+ }
+
+ private:
+ uint64_t m_tx_arp;
+ uint64_t m_tx_ipv6_n_solic;
+ uint64_t m_tot_bytes;
+};
+
class CLatencyPktInfo {
public:
void Create(class CLatencyPktMode *m_l_pkt_info);
@@ -180,7 +208,6 @@ private:
public:
uint64_t m_tx_pkt_ok;
- uint64_t m_tx_grat_arp_ok;
uint64_t m_tx_pkt_err;
uint64_t m_pkt_ok;
uint64_t m_unsup_prot;
@@ -190,6 +217,8 @@ public:
uint64_t m_rx_check;
uint64_t m_no_ipv4_option;
uint64_t m_length_error;
+ CRXCoreIgnoreStat m_ign_stats;
+ CRXCoreIgnoreStat m_ign_stats_prev;
CTimeHistogram m_hist; /* all window */
CJitter m_jitter;
};
@@ -307,6 +336,7 @@ public:
void set_mask(uint32_t mask){
m_port_mask=mask;
}
+ void get_ignore_stats(int port_id, CRXCoreIgnoreStat &stat, bool get_diff);
double get_max_latency(void);
double get_avr_latency(void);
bool is_any_error();
@@ -334,7 +364,6 @@ private:
bool m_is_active;
CLatencyPktInfo m_pkt_gen;
CLatencyManagerPerPort m_ports[TREX_MAX_PORTS];
- uint64_t m_d_time; // calc tick betwen sending
double m_cps;
double m_delta_sec;
uint64_t m_start_time; // calc tick betwen sending
diff --git a/src/stateless/rx/trex_stateless_rx_core.cpp b/src/stateless/rx/trex_stateless_rx_core.cpp
index e61fb448..d162c5b3 100644
--- a/src/stateless/rx/trex_stateless_rx_core.cpp
+++ b/src/stateless/rx/trex_stateless_rx_core.cpp
@@ -22,7 +22,7 @@
#include <stdio.h>
#include "bp_sim.h"
#include "flow_stat_parser.h"
-#include "latency.h"
+#include "stateful_rx_core.h"
#include "pal/linux/sanb_atomic.h"
#include "trex_stateless_messaging.h"
#include "trex_stateless_rx_core.h"
diff --git a/src/stateless/rx/trex_stateless_rx_core.h b/src/stateless/rx/trex_stateless_rx_core.h
index 39af8199..3f9fb6cc 100644
--- a/src/stateless/rx/trex_stateless_rx_core.h
+++ b/src/stateless/rx/trex_stateless_rx_core.h
@@ -21,7 +21,7 @@
#ifndef __TREX_STATELESS_RX_CORE_H__
#define __TREX_STATELESS_RX_CORE_H__
#include <stdint.h>
-#include "latency.h"
+#include "stateful_rx_core.h"
#include "os_time.h"
#include "pal/linux/sanb_atomic.h"
#include "utl_cpuu.h"