From 84fc182fd1021b0ad564478f284afff660a5b924 Mon Sep 17 00:00:00 2001 From: Yaroslav Brustinov Date: Tue, 31 May 2016 13:57:12 +0300 Subject: add rpc command get_cpu_util_full to cpp --- src/main_dpdk.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index ca5664d7..ff4b2b6a 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -2417,6 +2417,7 @@ public: float m_active_flows; float m_open_flows; float m_cpu_util; + float m_cpu_util_raw; float m_rx_cpu_util; float m_bw_per_core; uint8_t m_threads; @@ -2484,6 +2485,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_cpu_util_raw); json+=GET_FIELD(m_bw_per_core); json+=GET_FIELD(m_rx_cpu_util); json+=GET_FIELD(m_platform_factor); @@ -3542,6 +3544,7 @@ void CGlobalTRex::get_stats(CGlobalStats & stats){ stats.m_num_of_ports = m_max_ports; stats.m_cpu_util = m_fl.GetCpuUtil(); + stats.m_cpu_util_raw = m_fl.GetCpuUtilRaw(); if (get_is_stateless()) { stats.m_rx_cpu_util = m_rx_sl.get_cpu_util(); } @@ -5703,6 +5706,14 @@ int TrexDpdkPlatformApi::get_active_pgids(flow_stat_active_t &result) const { return g_trex.m_trex_stateless->m_rx_flow_stat.get_active_pgids(result); } +int TrexDpdkPlatformApi::get_cpu_util_full(cpu_util_full_t &cpu_util_full) const { + for (int i=0; i<(int)g_trex.m_fl.m_threads_info.size(); i++) { + CFlowGenListPerThread * lp=g_trex.m_fl.m_threads_info[i]; + cpu_util_full.push_back(lp->m_cpu_cp_u.GetHistory()); + } + return 0; +} + CFlowStatParser *TrexDpdkPlatformApi::get_flow_stat_parser() const { return CTRexExtendedDriverDb::Ins()->get_drv()->get_flow_stat_parser(); } -- cgit From 300ec24108211721d99ac9faf67fd1f91057b95b Mon Sep 17 00:00:00 2001 From: Yaroslav Brustinov Date: Thu, 2 Jun 2016 16:24:49 +0300 Subject: cpu utilization per thread + mbufs per socket + add in tui --- src/main_dpdk.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index ff4b2b6a..94679d72 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -2427,7 +2427,7 @@ public: public: void Dump(FILE *fd,DumpFormat mode); void DumpAllPorts(FILE *fd); - void dump_json(std::string & json, bool baseline,uint32_t stats_tick); + void dump_json(std::string & json, bool baseline); private: std::string get_field(std::string name,float &f); std::string get_field(std::string name,uint64_t &f); @@ -2467,7 +2467,7 @@ std::string CGlobalStats::get_field_port(int port,std::string name,uint64_t &f){ } -void CGlobalStats::dump_json(std::string & json, bool baseline,uint32_t stats_tick){ +void CGlobalStats::dump_json(std::string & json, bool baseline){ /* refactor this to JSON */ json="{\"name\":\"trex-global\",\"type\":0,"; @@ -2535,10 +2535,6 @@ void CGlobalStats::dump_json(std::string & json, bool baseline,uint32_t stats_ti json+=GET_FIELD_PORT(i,m_total_rx_pps); } json+=m_template.dump_as_json("template"); - if ( stats_tick %4==0){ - json+=CGlobalInfo::dump_pool_as_json(); /* no need a feq update beacuse it trash the cores D cache, once in 2 sec */ - } - json+="\"unknown\":0}}" ; } @@ -3776,7 +3772,7 @@ CGlobalTRex::publish_async_data(bool sync_now, bool baseline) { get_stats(m_stats); } - m_stats.dump_json(json, baseline,m_stats_cnt); + m_stats.dump_json(json, baseline); m_zmq_publisher.publish_json(json); /* generator json , all cores are the same just sample the first one */ @@ -3869,7 +3865,7 @@ CGlobalTRex::handle_slow_path(bool &was_stopped) { if (m_io_modes.m_g_mode == CTrexGlobalIoMode::gMem) { if ( m_stats_cnt%4==0) { - fprintf (stdout," %s \n",CGlobalInfo::dump_pool_as_json().c_str()); + fprintf (stdout," %s \n",CGlobalInfo::dump_pool_as_json_str().c_str()); } } @@ -5707,13 +5703,18 @@ int TrexDpdkPlatformApi::get_active_pgids(flow_stat_active_t &result) const { } int TrexDpdkPlatformApi::get_cpu_util_full(cpu_util_full_t &cpu_util_full) const { - for (int i=0; i<(int)g_trex.m_fl.m_threads_info.size(); i++) { - CFlowGenListPerThread * lp=g_trex.m_fl.m_threads_info[i]; + for (int thread_id=0; thread_id<(int)g_trex.m_fl.m_threads_info.size(); thread_id++) { + CFlowGenListPerThread * lp=g_trex.m_fl.m_threads_info[thread_id]; cpu_util_full.push_back(lp->m_cpu_cp_u.GetHistory()); } return 0; } +int TrexDpdkPlatformApi::get_mbuf_util(Json::Value &mbuf_pool) const { + mbuf_pool = CGlobalInfo::dump_pool_as_json(); + return 0; +} + CFlowStatParser *TrexDpdkPlatformApi::get_flow_stat_parser() const { return CTRexExtendedDriverDb::Ins()->get_drv()->get_flow_stat_parser(); } -- cgit From e0ca7a226fd37023ff8a9d80e46403a34492c1d7 Mon Sep 17 00:00:00 2001 From: Yaroslav Brustinov Date: Sun, 5 Jun 2016 01:16:11 +0300 Subject: cpu utilization: don't return vectors, only change passed arguments. --- src/main_dpdk.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 94679d72..75da27ca 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -5703,15 +5703,17 @@ int TrexDpdkPlatformApi::get_active_pgids(flow_stat_active_t &result) const { } int TrexDpdkPlatformApi::get_cpu_util_full(cpu_util_full_t &cpu_util_full) const { + static cpu_vct_t cpu_vct; for (int thread_id=0; thread_id<(int)g_trex.m_fl.m_threads_info.size(); thread_id++) { CFlowGenListPerThread * lp=g_trex.m_fl.m_threads_info[thread_id]; - cpu_util_full.push_back(lp->m_cpu_cp_u.GetHistory()); + cpu_util_full.push_back(cpu_vct); + lp->m_cpu_cp_u.GetHistory(cpu_util_full.back()); } return 0; } int TrexDpdkPlatformApi::get_mbuf_util(Json::Value &mbuf_pool) const { - mbuf_pool = CGlobalInfo::dump_pool_as_json(); + CGlobalInfo::dump_pool_as_json(mbuf_pool); return 0; } -- cgit From 56b55266e24255facdd9e4d604e628399debabb1 Mon Sep 17 00:00:00 2001 From: Yaroslav Brustinov Date: Sun, 5 Jun 2016 11:15:48 +0300 Subject: cpu utilization: replace using static with resize vector. --- src/main_dpdk.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index f0c9c7e1..ffae5caa 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -5769,11 +5769,10 @@ int TrexDpdkPlatformApi::get_active_pgids(flow_stat_active_t &result) const { } int TrexDpdkPlatformApi::get_cpu_util_full(cpu_util_full_t &cpu_util_full) const { - static cpu_vct_t cpu_vct; + cpu_util_full.resize((int)g_trex.m_fl.m_threads_info.size()); for (int thread_id=0; thread_id<(int)g_trex.m_fl.m_threads_info.size(); thread_id++) { CFlowGenListPerThread * lp=g_trex.m_fl.m_threads_info[thread_id]; - cpu_util_full.push_back(cpu_vct); - lp->m_cpu_cp_u.GetHistory(cpu_util_full.back()); + lp->m_cpu_cp_u.GetHistory(cpu_util_full[thread_id]); } return 0; } -- cgit From e56edd675d810d65e4e565561d83d39daa8354fb Mon Sep 17 00:00:00 2001 From: Hanoh Haim Date: Tue, 14 Jun 2016 12:32:32 +0300 Subject: disable WD due to crash trex-210 --- src/main_dpdk.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 90d08ab0..7c66cf05 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -4781,7 +4781,8 @@ int main_test(int argc , char * argv[]){ } /* disable WD if needed */ - g_trex.m_watchdog.init(CGlobalInfo::m_options.preview.getWDDisable()?false:true); + //CGlobalInfo::m_options.preview.getWDDisable()?false:true + g_trex.m_watchdog.init(false); /* always disable - due to trex-211 /* this will give us all cores - master + tx + latency */ g_trex.m_watchdog.mark_pending_monitor(g_trex.m_max_cores); -- cgit From 73fdde4e6b2d67ae3587a7133975e41deb46e2fd Mon Sep 17 00:00:00 2001 From: Hanoh Haim Date: Tue, 14 Jun 2016 13:06:21 +0300 Subject: fix typo --- src/main_dpdk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 7c66cf05..1c0f8c80 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -4782,7 +4782,7 @@ int main_test(int argc , char * argv[]){ /* disable WD if needed */ //CGlobalInfo::m_options.preview.getWDDisable()?false:true - g_trex.m_watchdog.init(false); /* always disable - due to trex-211 + g_trex.m_watchdog.init(false); /* always disable - due to trex-211 */ /* this will give us all cores - master + tx + latency */ g_trex.m_watchdog.mark_pending_monitor(g_trex.m_max_cores); -- cgit From 9b4c1354cb97988983da217c85223e8d0479b4d5 Mon Sep 17 00:00:00 2001 From: Hanoh Haim Date: Fri, 17 Jun 2016 12:33:22 +0300 Subject: XL710/X710 include 4 byte CRC for port stats --- src/main_dpdk.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 1c0f8c80..b41d4f91 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -5494,10 +5494,10 @@ void CTRexExtendedDriverBase40G::get_extended_stats(CPhyEthIF * _if,CPhyEthIFSta stats->ipackets = stats1.ipackets; - stats->ibytes = stats1.ibytes; + stats->ibytes = stats1.ibytes + (stats1.ipackets<<2); stats->opackets = stats1.opackets; - stats->obytes = stats1.obytes; + stats->obytes = stats1.obytes + (stats1.opackets<<2); stats->f_ipackets = 0; stats->f_ibytes = 0; -- cgit From d49f3784270f142825fa4bd4ae96730401a2b871 Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Mon, 20 Jun 2016 10:58:10 +0300 Subject: better support for latency with field engine + some order with mbuf functions --- src/main_dpdk.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index b41d4f91..b959895d 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -2115,8 +2115,12 @@ int CCoreEthIFStateless::send_node(CGenNode * no) { } if (unlikely(node_sl->is_stat_needed())) { - return send_node_flow_stat(m, node_sl, lp_port, lp_stats, - (node_sl->get_cache_mbuf() || node_sl->is_cache_mbuf_array())? true:false); + if ( unlikely(node_sl->is_cache_mbuf_array()) ) { + // No support for latency + cache. If user asks for cache on latency stream, we change cache to 0. + // assert here just to make sure. + assert(1); + } + return send_node_flow_stat(m, node_sl, lp_port, lp_stats, (node_sl->get_cache_mbuf()) ? true : false); } else { send_pkt(lp_port,m,lp_stats); } -- cgit From 3ca8be805c26eddfe40c254bdca4e5ae71eee792 Mon Sep 17 00:00:00 2001 From: imarom Date: Sun, 19 Jun 2016 18:05:54 +0300 Subject: WATCHDOG - refactor due to trex-211 --- src/main_dpdk.cpp | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index b959895d..ef1668ab 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -2857,8 +2857,9 @@ private: uint32_t m_stats_cnt; std::mutex m_cp_lock; + TrexMonitor m_monitor; + public: - TrexWatchDog m_watchdog; TrexStateless *m_trex_stateless; }; @@ -3288,8 +3289,7 @@ bool CGlobalTRex::Create(){ TrexRpcServerConfig rpc_req_resp_cfg(TrexRpcServerConfig::RPC_PROT_TCP, global_platform_cfg_info.m_zmq_rpc_port, - &m_cp_lock, - &m_watchdog); + &m_cp_lock); cfg.m_port_count = CGlobalInfo::m_options.m_expected_portd; cfg.m_rpc_req_resp_cfg = &rpc_req_resp_cfg; @@ -3992,8 +3992,10 @@ int CGlobalTRex::run_in_master() { const int FASTPATH_DELAY_MS = 10; const int SLOWPATH_DELAY_MS = 500; - int handle = m_watchdog.register_monitor("master", 2); - m_watchdog.start(); + m_monitor.create("master", 2); + TrexWatchDog::getInstance().register_monitor(&m_monitor); + + TrexWatchDog::getInstance().start(); while ( true ) { @@ -4016,14 +4018,14 @@ int CGlobalTRex::run_in_master() { slow_path_counter += FASTPATH_DELAY_MS; cp_lock.lock(); - m_watchdog.tickle(handle); + m_monitor.tickle(); } /* on exit release the lock */ cp_lock.unlock(); /* first stop the WD */ - m_watchdog.stop(); + TrexWatchDog::getInstance().stop(); if (!is_all_cores_finished()) { /* probably CLTR-C */ @@ -4047,12 +4049,12 @@ int CGlobalTRex::run_in_rx_core(void){ if (get_is_stateless()) { m_sl_rx_running = true; - m_rx_sl.start(m_watchdog); + m_rx_sl.start(); m_sl_rx_running = false; } else { if ( CGlobalInfo::m_options.is_rx_enabled() ){ m_sl_rx_running = false; - m_mg.start(0, &m_watchdog); + m_mg.start(0, true); } } @@ -4079,9 +4081,8 @@ int CGlobalTRex::run_in_core(virtual_thread_id_t virt_core_id){ lpt = m_fl.m_threads_info[virt_core_id-1]; /* register a watchdog handle on current core */ - lpt->m_watchdog = &m_watchdog; - lpt->m_watchdog_handle = m_watchdog.register_monitor(ss.str(), 1); - + lpt->m_monitor.create(ss.str(), 1); + TrexWatchDog::getInstance().register_monitor(&lpt->m_monitor); if (get_is_stateless()) { lpt->start_stateless_daemon(*lp); @@ -4090,7 +4091,7 @@ int CGlobalTRex::run_in_core(virtual_thread_id_t virt_core_id){ } /* done - remove this from the watchdog (we might wait on join for a long time) */ - lpt->m_watchdog->disable_monitor(lpt->m_watchdog_handle); + lpt->m_monitor.disable(); m_signal[virt_core_id]=1; return (0); @@ -4786,11 +4787,7 @@ int main_test(int argc , char * argv[]){ /* disable WD if needed */ //CGlobalInfo::m_options.preview.getWDDisable()?false:true - g_trex.m_watchdog.init(false); /* always disable - due to trex-211 */ - - /* this will give us all cores - master + tx + latency */ - g_trex.m_watchdog.mark_pending_monitor(g_trex.m_max_cores); - + TrexWatchDog::getInstance().init(true); /* always disable - due to trex-211 */ g_trex.m_sl_rx_running = false; if ( get_is_stateless() ) { -- cgit From 35efdda889977a7b0bf5d1cda213d0e7ffcd4367 Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Mon, 20 Jun 2016 12:56:17 +0300 Subject: Add 4 bytes for each packet rx/tx bytes in flow stats, to artificially count ethernet CRC --- src/main_dpdk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index ef1668ab..3dd020ae 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -2074,7 +2074,7 @@ int CCoreEthIFStateless::send_node_flow_stat(rte_mbuf *m, CGenNodeStateless * no } tx_per_flow_t *lp_s = &lp_stats->m_tx_per_flow[hw_id]; lp_s->add_pkts(1); - lp_s->add_bytes(mi->pkt_len); + lp_s->add_bytes(mi->pkt_len + 4); // We add 4 because of ethernet CRC if (hw_id >= MAX_FLOW_STATS) { fsp_head->time_stamp = os_get_hr_tick_64(); -- cgit From 88486da4a095bd7fa7094d4bd9ab54eeafd24a26 Mon Sep 17 00:00:00 2001 From: imarom Date: Mon, 20 Jun 2016 13:48:27 +0300 Subject: fix: --no-watchdog did not work --- src/main_dpdk.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 3dd020ae..29966932 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -4786,8 +4786,8 @@ int main_test(int argc , char * argv[]){ } /* disable WD if needed */ - //CGlobalInfo::m_options.preview.getWDDisable()?false:true - TrexWatchDog::getInstance().init(true); /* always disable - due to trex-211 */ + bool wd_enable = (CGlobalInfo::m_options.preview.getWDDisable() ? false : true); + TrexWatchDog::getInstance().init(wd_enable); g_trex.m_sl_rx_running = false; if ( get_is_stateless() ) { -- cgit From 7b13e5e5a6ec2dd71f551e61b846b481d5c58205 Mon Sep 17 00:00:00 2001 From: Hanoh Haim Date: Mon, 20 Jun 2016 13:50:10 +0300 Subject: minor remove sim help --- src/main_dpdk.cpp | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 3dd020ae..8ae44b02 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -714,20 +714,11 @@ static int usage(){ printf(" --prefix : for multi trex, each instance should have a different name \n"); printf(" --mac-spread : Spread the destination mac-order by this factor. e.g 2 will generate the traffic to 2 devices DEST-MAC ,DEST-MAC+1 \n"); printf(" maximum is up to 128 devices \n"); - printf(" --mbuf-factor : factor for packet memory \n"); - + printf(" \n"); printf(" --no-watchdog : disable watchdog \n"); - - printf("\n simulation mode : \n"); - printf(" Using this mode you can generate the traffic into a pcap file and learn how trex works \n"); - printf(" With this version you must be SUDO to use this mode ( I know this is not normal ) \n"); - printf(" you can use the Linux CEL version of TRex to do it without super user \n"); - printf(" \n"); - printf(" -o [capfile_name] simulate trex into pcap file \n"); - printf(" --pcap export the file in pcap mode \n"); - printf(" bp-sim-64 -d 10 -f cfg.yaml -o my.pcap --pcap # export 10 sec of what Trex will do on real-time to a file my.pcap \n"); - printf(" --vm-sim : simulate vm with driver of one input queue and one output queue \n"); + printf(" \n"); + printf(" --vm-sim : simulate vm with driver of one input queue and one output queue \n"); printf(" \n"); printf(" Examples: "); printf(" basic trex run for 10 sec and multiplier of x10 \n"); -- cgit From 5f84648529772a4b0b52eedfbf3669c6e45d653f Mon Sep 17 00:00:00 2001 From: imarom Date: Thu, 23 Jun 2016 11:27:05 +0300 Subject: allow coredump for TRex with --alow-coredump by default, huge pages will not be mapped to the core --- src/main_dpdk.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index dcef2f38..4f8d8937 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -50,6 +50,7 @@ #include #include #include + #include "bp_sim.h" #include "os_time.h" #include "common/arg/SimpleGlob.h" @@ -553,7 +554,9 @@ enum { OPT_HELP, OPT_PREFIX, OPT_MAC_SPLIT, OPT_SEND_DEBUG_PKT, - OPT_NO_WATCHDOG + OPT_NO_WATCHDOG, + OPT_ALLOW_COREDUMP + }; @@ -615,7 +618,8 @@ static CSimpleOpt::SOption parser_options[] = { OPT_MAC_SPLIT, "--mac-spread", SO_REQ_SEP }, { OPT_SEND_DEBUG_PKT, "--send-debug-pkt", SO_REQ_SEP }, { OPT_MBUF_FACTOR , "--mbuf-factor", SO_REQ_SEP }, - { OPT_NO_WATCHDOG , "--no-watchdog", SO_NONE }, + { OPT_NO_WATCHDOG , "--no-watchdog", SO_NONE }, + { OPT_ALLOW_COREDUMP , "--allow-coredump", SO_NONE }, SO_END_OF_OPTIONS @@ -718,6 +722,8 @@ static int usage(){ printf(" \n"); printf(" --no-watchdog : disable watchdog \n"); printf(" \n"); + printf(" --allow-coredump : allow a creation of core dump \n"); + printf(" \n"); printf(" --vm-sim : simulate vm with driver of one input queue and one output queue \n"); printf(" \n"); printf(" Examples: "); @@ -935,6 +941,10 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t po->preview.setWDDisable(true); break; + case OPT_ALLOW_COREDUMP : + po->preview.setCoreDumpEnable(true); + break; + case OPT_LATENCY_PREVIEW : sscanf(args.OptionArg(),"%d", &po->m_latency_prev); break; @@ -4703,6 +4713,15 @@ int main_test(int argc , char * argv[]){ exit(-1); } + /* enable core dump if requested */ + if (CGlobalInfo::m_options.preview.getCoreDumpEnable()) { + utl_set_coredump_size(-1); + } + else { + utl_set_coredump_size(0); + } + + update_global_info_from_platform_file(); /* It is not a mistake. Give the user higher priorty over the configuration file */ @@ -5779,3 +5798,4 @@ int TrexDpdkPlatformApi::get_active_pgids(flow_stat_active_t &result) const { CFlowStatParser *TrexDpdkPlatformApi::get_flow_stat_parser() const { return CTRexExtendedDriverDb::Ins()->get_drv()->get_flow_stat_parser(); } + -- cgit From 83170bb32b9bdbbe63a9f2b301b19bcd1d7eaa60 Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Thu, 23 Jun 2016 18:06:39 +0300 Subject: Fix latency stats issues of fast stop/start, and starting from different cores --- src/main_dpdk.cpp | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 4f8d8937..906aa2b7 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -2053,17 +2053,17 @@ int CCoreEthIFStateless::send_node_flow_stat(rte_mbuf *m, CGenNodeStateless * no } mi = node_sl->alloc_flow_stat_mbuf(m, fsp_head, is_const); - fsp_head->seq = lp_stats->m_seq_num[hw_id_payload]; + fsp_head->seq = lp_stats->m_lat_data[hw_id_payload].get_seq_num(); fsp_head->hw_id = hw_id_payload; - fsp_head->magic = FLOW_STAT_PAYLOAD_MAGIC; + fsp_head->magic = lp_stats->m_lat_data[hw_id_payload].get_magic(); - lp_stats->m_seq_num[hw_id_payload]++; + lp_stats->m_lat_data[hw_id_payload].inc_seq_num(); #ifdef ERR_CNTRS_TEST if (temp % 10 == 0) { - fsp_head->seq = lp_stats->m_seq_num[hw_id_payload]++; + fsp_head->seq = lp_stats->m_lat_data[hw_id_payload].inc_seq_num(); } if ((temp - 1) % 100 == 0) { - fsp_head->seq = lp_stats->m_seq_num[hw_id_payload] - 4; + fsp_head->seq = lp_stats->m_lat_data[hw_id_payload].get_seq_num() - 4; } #endif } else { @@ -2815,7 +2815,7 @@ public: bool sanity_check(); void update_stats(void); tx_per_flow_t get_flow_tx_stats(uint8_t port, uint16_t hw_id); - tx_per_flow_t clear_flow_tx_stats(uint8_t port, uint16_t index); + tx_per_flow_t clear_flow_tx_stats(uint8_t port, uint16_t index, bool is_lat); void get_stats(CGlobalStats & stats); void dump_post_test_stats(FILE *fd); void dump_config(FILE *fd); @@ -2859,7 +2859,7 @@ private: std::mutex m_cp_lock; TrexMonitor m_monitor; - + public: TrexStateless *m_trex_stateless; @@ -3536,7 +3536,7 @@ tx_per_flow_t CGlobalTRex::get_flow_tx_stats(uint8_t port, uint16_t index) { } // read stats. Return read value, and clear. -tx_per_flow_t CGlobalTRex::clear_flow_tx_stats(uint8_t port, uint16_t index) { +tx_per_flow_t CGlobalTRex::clear_flow_tx_stats(uint8_t port, uint16_t index, bool is_lat) { uint8_t port0; CFlowGenListPerThread * lpt; tx_per_flow_t ret; @@ -3546,12 +3546,11 @@ tx_per_flow_t CGlobalTRex::clear_flow_tx_stats(uint8_t port, uint16_t index) { for (int i=0; i < get_cores_tx(); i++) { lpt = m_fl.m_threads_info[i]; port0 = lpt->getDualPortId() * 2; - if (port == port0) { - m_stats.m_port[port0].m_tx_per_flow[index] += - lpt->m_node_gen.m_v_if->m_stats[0].m_tx_per_flow[index]; - } else if (port == port0 + 1) { - m_stats.m_port[port0 + 1].m_tx_per_flow[index] += - lpt->m_node_gen.m_v_if->m_stats[1].m_tx_per_flow[index]; + if ((port == port0) || (port == port0 + 1)) { + m_stats.m_port[port].m_tx_per_flow[index] += + lpt->m_node_gen.m_v_if->m_stats[port - port0].m_tx_per_flow[index]; + if (is_lat) + lpt->m_node_gen.m_v_if->m_stats[port - port0].m_lat_data[index - MAX_FLOW_STATS].reset(); } } @@ -4293,7 +4292,7 @@ int CPhyEthIF::get_flow_stats(rx_per_flow_t *rx_stats, tx_per_flow_t *tx_stats, } if (tx_stats != NULL) { - tx_stats[i - min] = g_trex.clear_flow_tx_stats(m_port_id, i); + tx_stats[i - min] = g_trex.clear_flow_tx_stats(m_port_id, i, false); } } else { if (hw_rx_stat_supported) { @@ -4318,7 +4317,7 @@ int CPhyEthIF::get_flow_stats_payload(rx_per_flow_t *rx_stats, tx_per_flow_t *tx for (int i = min; i <= max; i++) { if ( reset ) { if (tx_stats != NULL) { - tx_stats[i - min] = g_trex.clear_flow_tx_stats(m_port_id, i + MAX_FLOW_STATS); + tx_stats[i - min] = g_trex.clear_flow_tx_stats(m_port_id, i + MAX_FLOW_STATS, true); } } else { if (tx_stats != NULL) { @@ -5798,4 +5797,3 @@ int TrexDpdkPlatformApi::get_active_pgids(flow_stat_active_t &result) const { CFlowStatParser *TrexDpdkPlatformApi::get_flow_stat_parser() const { return CTRexExtendedDriverDb::Ins()->get_drv()->get_flow_stat_parser(); } - -- cgit From 8635fce7827e0ee75a2fe032e8dce139a746e1c4 Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Sun, 26 Jun 2016 17:41:29 +0300 Subject: Fx trex-216 - Crash on VM setups when running latency flows --- src/main_dpdk.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 906aa2b7..d132df51 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -2055,7 +2055,8 @@ int CCoreEthIFStateless::send_node_flow_stat(rte_mbuf *m, CGenNodeStateless * no mi = node_sl->alloc_flow_stat_mbuf(m, fsp_head, is_const); fsp_head->seq = lp_stats->m_lat_data[hw_id_payload].get_seq_num(); fsp_head->hw_id = hw_id_payload; - fsp_head->magic = lp_stats->m_lat_data[hw_id_payload].get_magic(); + fsp_head->flow_seq = lp_stats->m_lat_data[hw_id_payload].get_flow_seq(); + fsp_head->magic = FLOW_STAT_PAYLOAD_MAGIC; lp_stats->m_lat_data[hw_id_payload].inc_seq_num(); #ifdef ERR_CNTRS_TEST -- cgit From 3c693c4d3a57c8567c5e2a8327deb70a08be9a14 Mon Sep 17 00:00:00 2001 From: Hanoh Haim Date: Mon, 27 Jun 2016 13:43:01 +0300 Subject: fix trex-218 & trex-219 --- src/main_dpdk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index d132df51..2ef06157 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -5505,7 +5505,7 @@ void CTRexExtendedDriverBase40G::get_extended_stats(CPhyEthIF * _if,CPhyEthIFSta stats->ipackets = stats1.ipackets; - stats->ibytes = stats1.ibytes + (stats1.ipackets<<2); + stats->ibytes = stats1.ibytes ; stats->opackets = stats1.opackets; stats->obytes = stats1.obytes + (stats1.opackets<<2); -- cgit From 7bf6055dc8f8ae50ef0f6b612f68eaa77e1b4014 Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Mon, 27 Jun 2016 14:25:19 +0300 Subject: Make all latency tests work on Virtual machines --- src/main_dpdk.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 2ef06157..45e46810 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -4341,20 +4341,15 @@ bool CCoreEthIF::process_rx_pkt(pkt_dir_t dir, } bool send=false; + // e1000 on ESXI hands us the packet with the ethernet FCS + if (parser.getPktSize() < m->pkt_len) { + rte_pktmbuf_trim(m, m->pkt_len - parser.getPktSize()); + } + if ( get_is_stateless() ) { // In stateless RX, we only care about flow stat packets if ((parser.getIpId() & 0xff00) == IP_ID_RESERVE_BASE) { send = true; - if (parser.getIpId() == FLOW_STAT_PAYLOAD_IP_ID) { - // e1000 on ESXI appends 4 bytes to the packet. - // This is a best effort hack to get our latency info which we put at the end of the packet - uint8_t *p = rte_pktmbuf_mtod(m, uint8_t*); - struct flow_stat_payload_header *fsp_head = (struct flow_stat_payload_header *) - (p + m->pkt_len - sizeof(struct flow_stat_payload_header)); - if (fsp_head->magic != FLOW_STAT_PAYLOAD_MAGIC) { - rte_pktmbuf_trim(m, 4); - } - } } } else { CLatencyPktMode *c_l_pkt_mode = g_trex.m_mg.c_l_pkt_mode; -- cgit From 7772d0893579d0627c10515aeb6d9c9c8204316d Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Wed, 29 Jun 2016 16:18:13 +0300 Subject: flow stat/latency error counters code + documentation --- src/main_dpdk.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 45e46810..941612b1 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -5760,6 +5760,10 @@ int TrexDpdkPlatformApi::get_rfc2544_info(void *rfc2544_info, int min, int max, return g_trex.m_rx_sl.get_rfc2544_info((rfc2544_info_t *)rfc2544_info, min, max, reset); } +int TrexDpdkPlatformApi::get_rx_err_cntrs(void *rx_err_cntrs) const { + return g_trex.m_rx_sl.get_rx_err_cntrs((CRxCoreErrCntrs *)rx_err_cntrs); +} + int TrexDpdkPlatformApi::reset_hw_flow_stats(uint8_t port_id) const { return g_trex.m_ports[port_id].reset_hw_flow_stats(); } -- cgit From f03fa158116cfd65659d14698c91446dc9bdb4c4 Mon Sep 17 00:00:00 2001 From: imarom Date: Mon, 27 Jun 2016 17:15:05 +0300 Subject: draft #3 of client config --- src/main_dpdk.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 941612b1..ad9858a2 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -2022,9 +2022,12 @@ void CCoreEthIF::update_mac_addr(CGenNode * node,uint8_t *p){ if ( unlikely( CGlobalInfo::m_options.preview.get_mac_ip_mapping_enable() ) ) { /* mac mapping file is configured */ + #if 0 if ( node->is_initiator_pkt() && (node->m_src_mac.inused==INUSED)) { memcpy(p+6, &node->m_src_mac.mac, 6); } + #endif + } else if ( unlikely( CGlobalInfo::m_options.preview.get_mac_ip_overide_enable() ) ){ /* client side */ if ( node->is_initiator_pkt() ){ -- cgit From 1dfd42ceb79677e171d5dedcac34900776574000 Mon Sep 17 00:00:00 2001 From: imarom Date: Wed, 29 Jun 2016 10:35:54 +0300 Subject: added enhanced parsing for the YAML wrapper module --- src/main_dpdk.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index ad9858a2..0200df92 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -547,7 +547,7 @@ enum { OPT_HELP, OPT_L_PKT_MODE, OPT_NO_FLOW_CONTROL, OPT_RX_CHECK_HOPS, - OPT_MAC_FILE, + OPT_CLIENT_CFG_FILE, OPT_NO_KEYBOARD_INPUT, OPT_VLAN, OPT_VIRT_ONE_TX_RX_QUEUE, @@ -611,7 +611,7 @@ static CSimpleOpt::SOption parser_options[] = { OPT_L_PKT_MODE, "--l-pkt-mode", SO_REQ_SEP }, { OPT_NO_FLOW_CONTROL, "--no-flow-control-change", SO_NONE }, { OPT_VLAN, "--vlan", SO_NONE }, - { OPT_MAC_FILE, "--mac", SO_REQ_SEP }, + { OPT_CLIENT_CFG_FILE, "--client_cfg", SO_REQ_SEP }, { OPT_NO_KEYBOARD_INPUT ,"--no-key", SO_NONE }, { OPT_VIRT_ONE_TX_RX_QUEUE, "--vm-sim", SO_NONE }, { OPT_PREFIX, "--prefix", SO_REQ_SEP }, @@ -641,7 +641,7 @@ static int usage(){ printf(" options \n\n"); - printf(" --mac [file] : YAML file with configuration \n"); + printf(" --client_cfg [file] : YAML file which describes clients configuration\n"); printf(" \n\n"); printf(" -c [number of threads] : default is 1. number of threads to allocate for each dual ports. \n"); printf(" \n"); @@ -825,8 +825,8 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t po->preview.set_no_keyboard(true); break; - case OPT_MAC_FILE : - po->mac_file = args.OptionArg(); + case OPT_CLIENT_CFG_FILE : + po->client_cfg_file = args.OptionArg(); break; case OPT_PLAT_CFG_FILE : @@ -1011,11 +1011,13 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t parse_err(ss.str()); } - if ( CGlobalInfo::is_learn_mode() ){ - if ( po->preview.get_ipv6_mode_enable() ){ - parse_err("--learn mode is not supported with --ipv6, beacuse there is not such thing NAT66 ( ipv6-ipv6) \n" \ - "if you think it is important,open a defect \n"); - } + if (CGlobalInfo::is_learn_mode() && po->preview.get_ipv6_mode_enable()) { + parse_err("--learn mode is not supported with --ipv6, beacuse there is not such thing NAT66 ( ipv6-ipv6) \n" \ + "if you think it is important,open a defect \n"); + } + + if (CGlobalInfo::get_vlan_mode_enable() && (po->client_cfg_file != "") ) { + parse_err("--vlan and --client_cfg cannot be combined"); } if (po->preview.get_is_rx_check_enable() || po->is_latency_enabled() || CGlobalInfo::is_learn_mode()) { -- cgit From 4242bc5ec3aa8816db9bdd57bd1f732da4305555 Mon Sep 17 00:00:00 2001 From: imarom Date: Wed, 29 Jun 2016 15:39:46 +0300 Subject: client configuration: refactoring --- src/main_dpdk.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 0200df92..21612901 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -1016,7 +1016,7 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t "if you think it is important,open a defect \n"); } - if (CGlobalInfo::get_vlan_mode_enable() && (po->client_cfg_file != "") ) { + if (po->preview.get_vlan_mode_enable() && (po->client_cfg_file != "") ) { parse_err("--vlan and --client_cfg cannot be combined"); } @@ -4204,12 +4204,10 @@ int CGlobalTRex::start_master_statefull() { m_fl.Create(); m_fl.load_from_yaml(CGlobalInfo::m_options.cfg_file,get_cores_tx()); - if (CGlobalInfo::m_options.mac_file != "") { + + if (CGlobalInfo::m_options.client_cfg_file != "") { + m_fl.load_client_config_file(CGlobalInfo::m_options.client_cfg_file); CGlobalInfo::m_options.preview.set_mac_ip_mapping_enable(true); - m_fl.load_from_mac_file(CGlobalInfo::m_options.mac_file); - m_fl.m_mac_info.set_configured(true); - } else { - m_fl.m_mac_info.set_configured(false); } m_expected_pps = m_fl.get_total_pps(); -- cgit From d7c33685c85593e5b604f240272c000bdba3bc08 Mon Sep 17 00:00:00 2001 From: imarom Date: Thu, 30 Jun 2016 15:23:54 +0300 Subject: client config - refactor #2 --- src/main_dpdk.cpp | 141 +++++++++++++++++++++++++----------------------------- 1 file changed, 66 insertions(+), 75 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 21612901..3827579b 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -549,10 +549,8 @@ enum { OPT_HELP, OPT_RX_CHECK_HOPS, OPT_CLIENT_CFG_FILE, OPT_NO_KEYBOARD_INPUT, - OPT_VLAN, OPT_VIRT_ONE_TX_RX_QUEUE, OPT_PREFIX, - OPT_MAC_SPLIT, OPT_SEND_DEBUG_PKT, OPT_NO_WATCHDOG, OPT_ALLOW_COREDUMP @@ -610,12 +608,10 @@ static CSimpleOpt::SOption parser_options[] = { OPT_LEARN_VERIFY, "--learn-verify", SO_NONE }, { OPT_L_PKT_MODE, "--l-pkt-mode", SO_REQ_SEP }, { OPT_NO_FLOW_CONTROL, "--no-flow-control-change", SO_NONE }, - { OPT_VLAN, "--vlan", SO_NONE }, { OPT_CLIENT_CFG_FILE, "--client_cfg", SO_REQ_SEP }, { OPT_NO_KEYBOARD_INPUT ,"--no-key", SO_NONE }, { OPT_VIRT_ONE_TX_RX_QUEUE, "--vm-sim", SO_NONE }, { OPT_PREFIX, "--prefix", SO_REQ_SEP }, - { OPT_MAC_SPLIT, "--mac-spread", SO_REQ_SEP }, { OPT_SEND_DEBUG_PKT, "--send-debug-pkt", SO_REQ_SEP }, { OPT_MBUF_FACTOR , "--mbuf-factor", SO_REQ_SEP }, { OPT_NO_WATCHDOG , "--no-watchdog", SO_NONE }, @@ -716,8 +712,6 @@ static int usage(){ printf(" --no-key : daemon mode, don't get input from keyboard \n"); printf(" --no-flow-control-change : By default TRex disables flow-control. If this option is given, it does not touch it\n"); printf(" --prefix : for multi trex, each instance should have a different name \n"); - printf(" --mac-spread : Spread the destination mac-order by this factor. e.g 2 will generate the traffic to 2 devices DEST-MAC ,DEST-MAC+1 \n"); - printf(" maximum is up to 128 devices \n"); printf(" --mbuf-factor : factor for packet memory \n"); printf(" \n"); printf(" --no-watchdog : disable watchdog \n"); @@ -725,6 +719,7 @@ static int usage(){ printf(" --allow-coredump : allow a creation of core dump \n"); printf(" \n"); printf(" --vm-sim : simulate vm with driver of one input queue and one output queue \n"); + printf(" \n"); printf(" Examples: "); printf(" basic trex run for 10 sec and multiplier of x10 \n"); @@ -740,7 +735,7 @@ static int usage(){ printf("\n"); printf("\n"); - printf(" Copyright (c) 2015-2015 Cisco Systems, Inc. \n"); + printf(" Copyright (c) 2015-2016 Cisco Systems, Inc. \n"); printf(" \n"); printf(" Licensed under the Apache License, Version 2.0 (the 'License') \n"); printf(" you may not use this file except in compliance with the License. \n"); @@ -841,9 +836,6 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t po->preview.set_ipv6_mode_enable(true); break; - case OPT_VLAN: - po->preview.set_vlan_mode_enable(true); - break; case OPT_LEARN : po->m_learn_mode = CParserOption::LEARN_MODE_IP_OPTION; @@ -975,13 +967,6 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t po->prefix = args.OptionArg(); break; - case OPT_MAC_SPLIT: - sscanf(args.OptionArg(),"%d", &tmp_data); - po->m_mac_splitter = (uint8_t)tmp_data; - po->preview.set_mac_ip_features_enable(true); - po->preview.setDestMacSplit(true); - break; - case OPT_SEND_DEBUG_PKT: sscanf(args.OptionArg(),"%d", &tmp_data); po->m_debug_pkt_proto = (uint8_t)tmp_data; @@ -1005,21 +990,11 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t parse_err("Please provide single run mode (e.g. batch or interactive)"); } - if ( po->m_mac_splitter > 128 ){ - std::stringstream ss; - ss << "maximum mac spreading is 128 you set it to: " << po->m_mac_splitter; - parse_err(ss.str()); - } - if (CGlobalInfo::is_learn_mode() && po->preview.get_ipv6_mode_enable()) { parse_err("--learn mode is not supported with --ipv6, beacuse there is not such thing NAT66 ( ipv6-ipv6) \n" \ "if you think it is important,open a defect \n"); } - if (po->preview.get_vlan_mode_enable() && (po->client_cfg_file != "") ) { - parse_err("--vlan and --client_cfg cannot be combined"); - } - if (po->preview.get_is_rx_check_enable() || po->is_latency_enabled() || CGlobalInfo::is_learn_mode()) { po->set_rx_enabled(); } @@ -1757,7 +1732,7 @@ public: virtual void flush_dp_rx_queue(void); virtual int flush_tx_queue(void); __attribute__ ((noinline)) void flush_rx_queue(); - __attribute__ ((noinline)) void update_mac_addr(CGenNode * node,uint8_t *p); + __attribute__ ((noinline)) void apply_client_cfg(const ClientCfg *cfg, rte_mbuf_t *m, pkt_dir_t dir, uint8_t *p); bool process_rx_pkt(pkt_dir_t dir,rte_mbuf_t * m); @@ -1790,6 +1765,8 @@ protected: rte_mbuf_t *m, CVirtualIFPerSideStats * lp_stats); + void add_vlan(rte_mbuf_t *m, uint16_t vlan_id); + protected: uint8_t m_core_id; uint16_t m_mbuf_cache; @@ -2014,30 +1991,6 @@ void CCoreEthIF::send_one_pkt(pkt_dir_t dir, lp_port->m_len = 0; } - -void CCoreEthIF::update_mac_addr(CGenNode * node,uint8_t *p){ - - if ( CGlobalInfo::m_options.preview.getDestMacSplit() ) { - p[5]+= (node->m_src_ip % CGlobalInfo::m_options.m_mac_splitter); - } - - if ( unlikely( CGlobalInfo::m_options.preview.get_mac_ip_mapping_enable() ) ) { - /* mac mapping file is configured - */ - #if 0 - if ( node->is_initiator_pkt() && (node->m_src_mac.inused==INUSED)) { - memcpy(p+6, &node->m_src_mac.mac, 6); - } - #endif - - } else if ( unlikely( CGlobalInfo::m_options.preview.get_mac_ip_overide_enable() ) ){ - /* client side */ - if ( node->is_initiator_pkt() ){ - *((uint32_t*)(p+6))=PKT_NTOHL(node->m_src_ip); - } - } -} - int CCoreEthIFStateless::send_node_flow_stat(rte_mbuf *m, CGenNodeStateless * node_sl, CCorePerPort * lp_port , CVirtualIFPerSideStats * lp_stats, bool is_const) { // Defining this makes 10% percent packet loss. 1% packet reorder. @@ -2163,8 +2116,38 @@ int CCoreEthIFStateless::handle_slow_path_node(CGenNode * no) { return (-1); } +void CCoreEthIF::apply_client_cfg(const ClientCfg *cfg, rte_mbuf_t *m, pkt_dir_t dir, uint8_t *p) { + + assert(cfg); -int CCoreEthIF::send_node(CGenNode * node){ + /* take the right direction config */ + const ClientCfgDir &cfg_dir = ( (dir == CLIENT_SIDE) ? cfg->m_initiator : cfg->m_responder); + + /* dst mac */ + if (cfg_dir.has_dst_mac_addr()) { + memcpy(p, cfg_dir.get_dst_mac_addr(), 6); + } + + /* src mac */ + if (cfg_dir.has_src_mac_addr()) { + memcpy(p + 6, cfg_dir.get_src_mac_addr(), 6); + } + + /* VLAN */ + if (cfg_dir.has_vlan()) { + add_vlan(m, cfg_dir.get_vlan()); + } +} + + +void CCoreEthIF::add_vlan(rte_mbuf_t *m, uint16_t vlan_id) { + m->ol_flags = PKT_TX_VLAN_PKT; + m->l2_len = 14; + m->vlan_tci = vlan_id; +} + +int CCoreEthIF::send_node(CGenNode * node) { + if ( unlikely( node->get_cache_mbuf() !=NULL ) ) { pkt_dir_t dir; @@ -2182,33 +2165,29 @@ int CCoreEthIF::send_node(CGenNode * node){ rte_mbuf_t * m=lp->generate_new_mbuf(node); pkt_dir_t dir; - bool single_port; + bool single_port; - dir = node->cur_interface_dir(); + dir = node->cur_interface_dir(); single_port = node->get_is_all_flow_from_same_dir() ; if ( unlikely( CGlobalInfo::m_options.preview.get_vlan_mode_enable() ) ){ /* which vlan to choose 0 or 1*/ uint8_t vlan_port = (node->m_src_ip &1); - - /* set the vlan */ - m->ol_flags = PKT_TX_VLAN_PKT; - m->l2_len =14; - uint16_t vlan_id = CGlobalInfo::m_options.m_vlan_port[vlan_port]; - + uint16_t vlan_id = CGlobalInfo::m_options.m_vlan_port[vlan_port]; if (likely( vlan_id >0 ) ) { - m->vlan_tci = vlan_id; dir = dir ^ vlan_port; }else{ /* both from the same dir but with VLAN0 */ - m->vlan_tci = CGlobalInfo::m_options.m_vlan_port[0]; + vlan_id = CGlobalInfo::m_options.m_vlan_port[0]; dir = dir ^ 0; } + + add_vlan(m, vlan_id); } - CCorePerPort * lp_port=&m_ports[dir]; - CVirtualIFPerSideStats * lp_stats = &m_stats[dir]; + CCorePerPort *lp_port = &m_ports[dir]; + CVirtualIFPerSideStats *lp_stats = &m_stats[dir]; if (unlikely(m==0)) { lp_stats->m_tx_alloc_error++; @@ -2216,17 +2195,21 @@ int CCoreEthIF::send_node(CGenNode * node){ } /* update mac addr dest/src 12 bytes */ - uint8_t *p=rte_pktmbuf_mtod(m, uint8_t*); - uint8_t p_id=lp_port->m_port->get_port_id(); - - + uint8_t *p = rte_pktmbuf_mtod(m, uint8_t*); + uint8_t p_id = lp_port->m_port->get_port_id(); + memcpy(p,CGlobalInfo::m_options.get_dst_src_mac_addr(p_id),12); - /* if customer enables both mac_file and get_mac_ip_overide, - * we will apply mac_file. - */ - if ( unlikely(CGlobalInfo::m_options.preview.get_mac_ip_features_enable() ) ) { - update_mac_addr(node,p); + if ( unlikely( CGlobalInfo::m_options.preview.get_mac_ip_overide_enable() ) ) { + /* client side */ + if ( node->is_initiator_pkt() ) { + *((uint32_t*)(p+6)) = PKT_NTOHL(node->m_src_ip); + } + } + + /* flag is faster than checking the node pointer (another cacheline) */ + if ( unlikely(CGlobalInfo::m_options.preview.get_is_client_cfg_enable() ) ) { + apply_client_cfg(node->m_client_cfg, m, dir, p); } if ( unlikely( node->is_rx_check_enabled() ) ) { @@ -4207,7 +4190,15 @@ int CGlobalTRex::start_master_statefull() { if (CGlobalInfo::m_options.client_cfg_file != "") { m_fl.load_client_config_file(CGlobalInfo::m_options.client_cfg_file); - CGlobalInfo::m_options.preview.set_mac_ip_mapping_enable(true); + CGlobalInfo::m_options.preview.set_client_cfg_enable(true); + } + + /* verify options */ + try { + CGlobalInfo::m_options.verify(); + } catch (const std::runtime_error &e) { + std::cout << "\n*** " << e.what() << "\n\n"; + exit(-1); } m_expected_pps = m_fl.get_total_pps(); -- cgit From c6c4a4307a8a0ae17d3e26c9dc98b874dd5ee60b Mon Sep 17 00:00:00 2001 From: imarom Date: Sun, 3 Jul 2016 10:55:49 +0300 Subject: client config - cosmetics and gtest back on --- src/main_dpdk.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 3827579b..4b086597 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -4188,8 +4188,14 @@ int CGlobalTRex::start_master_statefull() { m_fl.Create(); m_fl.load_from_yaml(CGlobalInfo::m_options.cfg_file,get_cores_tx()); + /* client config */ if (CGlobalInfo::m_options.client_cfg_file != "") { - m_fl.load_client_config_file(CGlobalInfo::m_options.client_cfg_file); + try { + m_fl.load_client_config_file(CGlobalInfo::m_options.client_cfg_file); + } catch (const std::runtime_error &e) { + std::cout << "\n*** " << e.what() << "\n\n"; + exit(-1); + } CGlobalInfo::m_options.preview.set_client_cfg_enable(true); } -- cgit From 483dfb7c5021d7dc9e2c7f10c9b76101441c7203 Mon Sep 17 00:00:00 2001 From: imarom Date: Sun, 3 Jul 2016 15:38:59 +0300 Subject: slowpath features bit to avoid multiple IFs --- src/main_dpdk.cpp | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 4b086597..c4ba7fa5 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -1732,7 +1732,9 @@ public: virtual void flush_dp_rx_queue(void); virtual int flush_tx_queue(void); __attribute__ ((noinline)) void flush_rx_queue(); - __attribute__ ((noinline)) void apply_client_cfg(const ClientCfg *cfg, rte_mbuf_t *m, pkt_dir_t dir, uint8_t *p); + __attribute__ ((noinline)) void handle_slowpath_features(CGenNode *node, rte_mbuf_t *m, uint8_t *p, pkt_dir_t dir); + + void apply_client_cfg(const ClientCfg *cfg, rte_mbuf_t *m, pkt_dir_t dir, uint8_t *p); bool process_rx_pkt(pkt_dir_t dir,rte_mbuf_t * m); @@ -2146,8 +2148,29 @@ void CCoreEthIF::add_vlan(rte_mbuf_t *m, uint16_t vlan_id) { m->vlan_tci = vlan_id; } +/** + * slow path features goes here (avoid multiple IFs) + * + */ +void CCoreEthIF::handle_slowpath_features(CGenNode *node, rte_mbuf_t *m, uint8_t *p, pkt_dir_t dir) { + + + /* MAC ovverride */ + if ( unlikely( CGlobalInfo::m_options.preview.get_mac_ip_overide_enable() ) ) { + /* client side */ + if ( node->is_initiator_pkt() ) { + *((uint32_t*)(p+6)) = PKT_NTOHL(node->m_src_ip); + } + } + + /* flag is faster than checking the node pointer (another cacheline) */ + if ( unlikely(CGlobalInfo::m_options.preview.get_is_client_cfg_enable() ) ) { + apply_client_cfg(node->m_client_cfg, m, dir, p); + } + +} + int CCoreEthIF::send_node(CGenNode * node) { - if ( unlikely( node->get_cache_mbuf() !=NULL ) ) { pkt_dir_t dir; @@ -2170,6 +2193,7 @@ int CCoreEthIF::send_node(CGenNode * node) { dir = node->cur_interface_dir(); single_port = node->get_is_all_flow_from_same_dir() ; + if ( unlikely( CGlobalInfo::m_options.preview.get_vlan_mode_enable() ) ){ /* which vlan to choose 0 or 1*/ uint8_t vlan_port = (node->m_src_ip &1); @@ -2200,18 +2224,12 @@ int CCoreEthIF::send_node(CGenNode * node) { memcpy(p,CGlobalInfo::m_options.get_dst_src_mac_addr(p_id),12); - if ( unlikely( CGlobalInfo::m_options.preview.get_mac_ip_overide_enable() ) ) { - /* client side */ - if ( node->is_initiator_pkt() ) { - *((uint32_t*)(p+6)) = PKT_NTOHL(node->m_src_ip); - } - } - - /* flag is faster than checking the node pointer (another cacheline) */ - if ( unlikely(CGlobalInfo::m_options.preview.get_is_client_cfg_enable() ) ) { - apply_client_cfg(node->m_client_cfg, m, dir, p); + /* when slowpath features are on */ + if ( unlikely( CGlobalInfo::m_options.preview.get_is_slowpath_features_on() ) ) { + handle_slowpath_features(node, m, p, dir); } + if ( unlikely( node->is_rx_check_enabled() ) ) { lp_stats->m_tx_rx_check_pkt++; lp->do_generate_new_mbuf_rxcheck(m, node, single_port); -- cgit From c9a62eba0b701bec78e672f15ff0fc587b8c0792 Mon Sep 17 00:00:00 2001 From: Yaroslav Brustinov Date: Tue, 5 Jul 2016 15:58:05 +0300 Subject: add TRex -w argument (wait between nics init and sending traffic) --- src/main_dpdk.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index c36c3eae..eeacdbff 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -140,8 +140,8 @@ public: virtual int configure_drop_queue(CPhyEthIF * _if); virtual void get_extended_stats(CPhyEthIF * _if,CPhyEthIFStats *stats)=0; virtual void clear_extended_stats(CPhyEthIF * _if)=0; - virtual int wait_for_stable_link()=0; - virtual void wait_after_link_up(){}; + virtual int wait_for_stable_link(); + virtual void wait_after_link_up(); virtual bool flow_control_disable_supported(){return true;} 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 @@ -537,6 +537,7 @@ enum { OPT_HELP, OPT_ONLY_LATENCY, OPT_1G_MODE, OPT_LATENCY_PREVIEW , + OPT_WAIT_BEFORE_TRAFFIC, OPT_PCAP, OPT_RX_CHECK, OPT_IO_MODE, @@ -598,6 +599,7 @@ static CSimpleOpt::SOption parser_options[] = { OPT_1G_MODE, "-1g", SO_NONE }, { OPT_LATENCY_PREVIEW , "-k", SO_REQ_SEP }, + { OPT_WAIT_BEFORE_TRAFFIC , "-w", SO_REQ_SEP }, { OPT_PCAP, "--pcap", SO_NONE }, { OPT_RX_CHECK, "--rx-check", SO_REQ_SEP }, { OPT_IO_MODE, "--iom", SO_REQ_SEP }, @@ -675,6 +677,8 @@ static int usage(){ 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"); + printf(" -w [sec] : wait between init of interfaces and sending traffic,\n"); + printf(" \n"); printf(" --cfg [platform_yaml] : load and configure platform using this file see example in cfg/cfg_examplexx.yaml file \n"); printf(" this file is used to configure/mask interfaces cores affinity and mac addr \n"); @@ -941,6 +945,10 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t sscanf(args.OptionArg(),"%d", &po->m_latency_prev); break; + case OPT_WAIT_BEFORE_TRAFFIC : + sscanf(args.OptionArg(),"%d", &po->m_wait_before_traffic); + break; + case OPT_PCAP: po->preview.set_pcap_mode_enable(true); break; @@ -4865,6 +4873,15 @@ int CTRexExtendedDriverBase::configure_drop_queue(CPhyEthIF * _if) { return (rte_eth_dev_rx_queue_stop(port_id, 0)); } +int CTRexExtendedDriverBase::wait_for_stable_link() { + wait_x_sec(CGlobalInfo::m_options.m_wait_before_traffic); + return 0; +} + +void CTRexExtendedDriverBase::wait_after_link_up() { + wait_x_sec(CGlobalInfo::m_options.m_wait_before_traffic); +} + CFlowStatParser *CTRexExtendedDriverBase::get_flow_stat_parser() { CFlowStatParser *parser = new CFlowStatParser(); assert (parser); @@ -4886,11 +4903,11 @@ void wait_x_sec(int sec) { // in 1G we need to wait if links became ready to soon void CTRexExtendedDriverBase1G::wait_after_link_up(){ - wait_x_sec(7); + wait_x_sec(6 + CGlobalInfo::m_options.m_wait_before_traffic); } int CTRexExtendedDriverBase1G::wait_for_stable_link(){ - wait_x_sec(10); + wait_x_sec(9 + CGlobalInfo::m_options.m_wait_before_traffic); return(0); } -- cgit From c9ae2ba88f6831d7a78c0fe05581303dcbb8a231 Mon Sep 17 00:00:00 2001 From: Yaroslav Brustinov Date: Tue, 5 Jul 2016 18:07:17 +0300 Subject: few more places to add wait_before_traffic argument --- src/main_dpdk.cpp | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index eeacdbff..905899d4 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -4863,6 +4863,18 @@ int main_test(int argc , char * argv[]){ return (0); } +void wait_x_sec(int sec) { + int i; + printf(" wait %d sec ", sec); + fflush(stdout); + for (i=0; i Date: Tue, 5 Jul 2016 19:55:59 +0300 Subject: original delay was 10 miliseconds not 10 seconds, new default will cover it. --- src/main_dpdk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 905899d4..adf460d7 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -5635,7 +5635,7 @@ void CTRexExtendedDriverBase1GVm::get_extended_stats(CPhyEthIF * _if,CPhyEthIFSt } int CTRexExtendedDriverBase1GVm::wait_for_stable_link(){ - wait_x_sec(9 + CGlobalInfo::m_options.m_wait_before_traffic); + wait_x_sec(CGlobalInfo::m_options.m_wait_before_traffic); return (0); } -- cgit From f374d4fda8db1862311355c1b189f2d1e94f15de Mon Sep 17 00:00:00 2001 From: Yaroslav Brustinov Date: Wed, 6 Jul 2016 17:25:50 +0300 Subject: increase server<->client API version from 1.2 to 1.3 various fixes --- src/main_dpdk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index adf460d7..1e206f27 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -677,7 +677,7 @@ static int usage(){ 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"); - printf(" -w [sec] : wait between init of interfaces and sending traffic,\n"); + printf(" -w [sec] : wait between init of interfaces and sending traffic, default is 1\n"); printf(" \n"); printf(" --cfg [platform_yaml] : load and configure platform using this file see example in cfg/cfg_examplexx.yaml file \n"); -- cgit From c19193cff9413a03dd85cc9facda0c28b28d37c2 Mon Sep 17 00:00:00 2001 From: Yaroslav Brustinov Date: Fri, 8 Jul 2016 15:45:22 +0300 Subject: fix multicast being counted as ierror --- src/main_dpdk.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 1e206f27..a2bfefe3 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -5542,11 +5542,10 @@ void CTRexExtendedDriverBase40G::get_extended_stats(CPhyEthIF * _if,CPhyEthIFSta stats->f_ibytes = 0; - stats->ierrors = stats1.ierrors + stats1.imissed + stats1.ibadcrc + + stats->ierrors = stats1.imissed + stats1.ibadcrc + stats1.ibadlen + stats1.ierrors + stats1.oerrors + - stats1.imcasts + stats1.rx_nombuf + stats1.tx_pause_xon + stats1.rx_pause_xon + @@ -5616,11 +5615,10 @@ void CTRexExtendedDriverBase1GVm::get_extended_stats(CPhyEthIF * _if,CPhyEthIFSt stats->f_ibytes = 0; - stats->ierrors = stats1.ierrors + stats1.imissed + stats1.ibadcrc + + stats->ierrors = stats1.imissed + stats1.ibadcrc + stats1.ibadlen + stats1.ierrors + stats1.oerrors + - stats1.imcasts + stats1.rx_nombuf + stats1.tx_pause_xon + stats1.rx_pause_xon + -- cgit From cc5cc5631e9df4ef0eee9c26705208dfcf035e8c Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Wed, 6 Jul 2016 11:04:52 +0300 Subject: NAT seq num randomization working version - Missing some functionality --- src/main_dpdk.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index a2bfefe3..d5e7c9b5 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -687,9 +687,10 @@ static int usage(){ printf(" --ipv6 : work in ipv6 mode\n"); printf(" --learn (deprecated). Replaced by --learn-mode. To get older behaviour, use --learn-mode 2\n"); - printf(" --learn-mode [1-2] : Work in NAT environments, learn the dynamic NAT translation and ALG \n"); - printf(" 1 Use TCP ACK in first SYN to pass NAT translation information. Will work only for TCP streams. Initial SYN packet must be present in stream.\n"); + printf(" --learn-mode [1-3] : Work in NAT environments, learn the dynamic NAT translation and ALG \n"); + printf(" 1 Use TCP ACK in first SYN to pass NAT translation information. Will work only for TCP streams. Initial SYN packet must be first packet in stream.\n"); printf(" 2 Add special IP option to pass NAT translation information. Will not work on certain firewalls if they drop packets with IP options\n"); + printf(" 3 Like 1, but without support for sequence number randomization in server->clien direction. Performance (flow/second) better than 1\n"); printf(" --learn-verify : Learn the translation, but intended for verification of the mechanism in cases that NAT does not exist \n"); printf(" \n"); printf(" --l-pkt-mode [0-3] : Set mode for sending latency packets.\n"); -- cgit From 7b9d10888594ca9fe1114309e53c0dea9089085b Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Mon, 11 Jul 2016 16:58:21 +0300 Subject: NAT seq num randomization fully working --- src/main_dpdk.cpp | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index d5e7c9b5..099ebb3b 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -2439,8 +2439,10 @@ public: uint64_t m_active_sockets; uint64_t m_total_nat_time_out; + uint64_t m_total_nat_time_out_wait_ack; uint64_t m_total_nat_no_fid ; uint64_t m_total_nat_active ; + uint64_t m_total_nat_syn_wait; uint64_t m_total_nat_open ; uint64_t m_total_nat_learn_error ; @@ -2559,8 +2561,10 @@ void CGlobalStats::dump_json(std::string & json, bool baseline){ json+=GET_FIELD(m_socket_util); json+=GET_FIELD(m_total_nat_time_out); + json+=GET_FIELD(m_total_nat_time_out_wait_ack); json+=GET_FIELD(m_total_nat_no_fid ); json+=GET_FIELD(m_total_nat_active ); + json+=GET_FIELD(m_total_nat_syn_wait); json+=GET_FIELD(m_total_nat_open ); json+=GET_FIELD(m_total_nat_learn_error); @@ -2596,7 +2600,12 @@ void CGlobalStats::DumpAllPorts(FILE *fd){ fprintf (fd," Platform_factor : %2.1f \n",m_platform_factor); fprintf (fd," Total-Tx : %s ",double_to_human_str(m_tx_bps,"bps",KBYE_1000).c_str()); if ( CGlobalInfo::is_learn_mode() ) { - fprintf (fd," Nat_time_out : %8llu \n", (unsigned long long)m_total_nat_time_out); + fprintf (fd," NAT time out : %8llu", (unsigned long long)m_total_nat_time_out); + if (CGlobalInfo::is_learn_mode(CParserOption::LEARN_MODE_TCP_ACK)) { + fprintf (fd," (%llu in wait for syn+ack)\n", (unsigned long long)m_total_nat_time_out_wait_ack); + } else { + fprintf (fd, "\n"); + } }else{ fprintf (fd,"\n"); } @@ -2604,28 +2613,33 @@ void CGlobalStats::DumpAllPorts(FILE *fd){ fprintf (fd," Total-Rx : %s ",double_to_human_str(m_rx_bps,"bps",KBYE_1000).c_str()); if ( CGlobalInfo::is_learn_mode() ) { - fprintf (fd," Nat_no_fid : %8llu \n", (unsigned long long)m_total_nat_no_fid); + fprintf (fd," NAT aged flow id: %8llu \n", (unsigned long long)m_total_nat_no_fid); }else{ fprintf (fd,"\n"); } fprintf (fd," Total-PPS : %s ",double_to_human_str(m_tx_pps,"pps",KBYE_1000).c_str()); if ( CGlobalInfo::is_learn_mode() ) { - fprintf (fd," Total_nat_active: %8llu \n", (unsigned long long)m_total_nat_active); + fprintf (fd," Total NAT active: %8llu", (unsigned long long)m_total_nat_active); + if (CGlobalInfo::is_learn_mode(CParserOption::LEARN_MODE_TCP_ACK)) { + fprintf (fd," (%llu waiting for syn)\n", (unsigned long long)m_total_nat_syn_wait); + } else { + fprintf (fd, "\n"); + } }else{ fprintf (fd,"\n"); } fprintf (fd," Total-CPS : %s ",double_to_human_str(m_tx_cps,"cps",KBYE_1000).c_str()); if ( CGlobalInfo::is_learn_mode() ) { - fprintf (fd," Total_nat_open : %8llu \n", (unsigned long long)m_total_nat_open); + fprintf (fd," Total NAT opened: %8llu \n", (unsigned long long)m_total_nat_open); }else{ fprintf (fd,"\n"); } fprintf (fd,"\n"); fprintf (fd," Expected-PPS : %s ",double_to_human_str(m_tx_expected_pps,"pps",KBYE_1000).c_str()); if ( CGlobalInfo::is_learn_verify_mode() ) { - fprintf (fd," Nat_learn_errors: %8llu \n", (unsigned long long)m_total_nat_learn_error); + fprintf (fd," NAT learn errors: %8llu \n", (unsigned long long)m_total_nat_learn_error); }else{ fprintf (fd,"\n"); } @@ -3647,8 +3661,10 @@ void CGlobalTRex::get_stats(CGlobalStats & stats){ uint64_t total_nat_time_out =0; + uint64_t total_nat_time_out_wait_ack =0; uint64_t total_nat_no_fid =0; uint64_t total_nat_active =0; + uint64_t total_nat_syn_wait = 0; uint64_t total_nat_open =0; uint64_t total_nat_learn_error=0; @@ -3677,8 +3693,10 @@ void CGlobalTRex::get_stats(CGlobalStats & stats){ total_sockets += lpt->m_smart_gen.MaxSockets(); total_nat_time_out +=lpt->m_stats.m_nat_flow_timeout; + total_nat_time_out_wait_ack += lpt->m_stats.m_nat_flow_timeout_wait_ack; total_nat_no_fid +=lpt->m_stats.m_nat_lookup_no_flow_id ; total_nat_active +=lpt->m_stats.m_nat_lookup_add_flow_id - lpt->m_stats.m_nat_lookup_remove_flow_id; + total_nat_syn_wait += lpt->m_stats.m_nat_lookup_add_flow_id - lpt->m_stats.m_nat_lookup_wait_ack_state; total_nat_open +=lpt->m_stats.m_nat_lookup_add_flow_id; total_nat_learn_error +=lpt->m_stats.m_nat_flow_learn_error; uint8_t port0 = lpt->getDualPortId() *2; @@ -3700,8 +3718,10 @@ void CGlobalTRex::get_stats(CGlobalStats & stats){ } stats.m_total_nat_time_out = total_nat_time_out; + stats.m_total_nat_time_out_wait_ack = total_nat_time_out_wait_ack; stats.m_total_nat_no_fid = total_nat_no_fid; stats.m_total_nat_active = total_nat_active; + stats.m_total_nat_syn_wait = total_nat_syn_wait; stats.m_total_nat_open = total_nat_open; stats.m_total_nat_learn_error = total_nat_learn_error; @@ -3959,9 +3979,17 @@ CGlobalTRex::handle_slow_path(bool &was_stopped) { m_mg.DumpRxCheck(stdout); break; } - } - + } + } + if ( m_io_modes.m_g_mode == CTrexGlobalIoMode::gNAT ) { + if ( m_io_modes.m_nat_mode == CTrexGlobalIoMode::natENABLE ) { + if (CGlobalInfo::is_learn_mode(CParserOption::LEARN_MODE_TCP_ACK)) { + fprintf(stdout, "NAT flow table info\n"); + m_mg.dump_nat_flow_table(stdout); + } else { + fprintf(stdout, "\nThis is only relevant in --learn-mode %d\n", CParserOption::LEARN_MODE_TCP_ACK); + } } } -- cgit From 1b6c970a70c0fcf8b7599877ecb9ceb31e261fed Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Wed, 13 Jul 2016 15:42:52 +0300 Subject: Better error handling in case of unsupported driver --- src/main_dpdk.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 099ebb3b..17b9f25f 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -3386,7 +3386,9 @@ int CGlobalTRex::ixgbe_prob_init(void){ if ( !CTRexExtendedDriverDb::Ins()->is_driver_exists(dev_info.driver_name) ){ - printf(" ERROR driver name %s is not supported \n",dev_info.driver_name); + printf(" Error: driver %s is not supported. Please consult the documentation for a list of supported drivers\n" + ,dev_info.driver_name); + exit(1); } int i; -- cgit From 659ba2606be997631d736070d2efd92472496a11 Mon Sep 17 00:00:00 2001 From: Martin Weiser Date: Fri, 15 Jul 2016 15:59:54 +0200 Subject: add option to use DPDK tx checksum offloading to generate packets with correct IP, TCP and UDP checksums --- src/main_dpdk.cpp | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 45e46810..820371ab 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include "bp_sim.h" #include "os_time.h" @@ -555,7 +556,8 @@ enum { OPT_HELP, OPT_MAC_SPLIT, OPT_SEND_DEBUG_PKT, OPT_NO_WATCHDOG, - OPT_ALLOW_COREDUMP + OPT_ALLOW_COREDUMP, + OPT_CHECKSUM_OFFLOAD, }; @@ -620,6 +622,7 @@ static CSimpleOpt::SOption parser_options[] = { OPT_MBUF_FACTOR , "--mbuf-factor", SO_REQ_SEP }, { OPT_NO_WATCHDOG , "--no-watchdog", SO_NONE }, { OPT_ALLOW_COREDUMP , "--allow-coredump", SO_NONE }, + { OPT_CHECKSUM_OFFLOAD, "--checksum-offload", SO_NONE }, SO_END_OF_OPTIONS @@ -725,6 +728,8 @@ static int usage(){ printf(" --allow-coredump : allow a creation of core dump \n"); printf(" \n"); printf(" --vm-sim : simulate vm with driver of one input queue and one output queue \n"); + printf(" \n"); + printf(" --checksum-offload : enable IP, TCP and UDP tx checksum offloading with DPDK. This requires all used interfaces to support this \n"); printf(" \n"); printf(" Examples: "); printf(" basic trex run for 10 sec and multiplier of x10 \n"); @@ -987,6 +992,10 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t po->m_debug_pkt_proto = (uint8_t)tmp_data; break; + case OPT_CHECKSUM_OFFLOAD: + po->preview.setChecksumOffloadEnable(true); + break; + default: usage(); @@ -1341,6 +1350,19 @@ void CPhyEthIF::configure(uint16_t nb_rx_queue, /* get device info */ rte_eth_dev_info_get(m_port_id, &m_dev_info); + if (CGlobalInfo::m_options.preview.getChecksumOffloadEnable()) { + /* check if the device supports TCP and UDP checksum offloading */ + if ((m_dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM) == 0) { + rte_exit(EXIT_FAILURE, "Device does not support UDP checksum offload: " + "port=%u\n", + m_port_id); + } + if ((m_dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) { + rte_exit(EXIT_FAILURE, "Device does not support TCP checksum offload: " + "port=%u\n", + m_port_id); + } + } } -- cgit From 3c106ce73a4a54863ed1c3df47c09eb1e63fadaf Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Sun, 17 Jul 2016 12:48:05 +0300 Subject: dpdk0716 move: changes to our files --- src/main_dpdk.cpp | 63 ++++++++++++++++++------------------------------------- 1 file changed, 20 insertions(+), 43 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 7bff8253..7a6f972a 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -64,9 +64,9 @@ #include "publisher/trex_publisher.h" #include "../linux_dpdk/version.h" extern "C" { -#include "dpdk22/drivers/net/ixgbe/base/ixgbe_type.h" +#include "dpdk/drivers/net/ixgbe/base/ixgbe_type.h" } -#include "dpdk22/drivers/net/e1000/base/e1000_regs.h" +#include "dpdk/drivers/net/e1000/base/e1000_regs.h" #include "global_io_mode.h" #include "utl_term_io.h" #include "msg_manager.h" @@ -306,17 +306,7 @@ public: m_if_per_card = 4; } - TrexPlatformApi::driver_speed_e get_driver_speed(uint8_t port_id) { - int speed; - - rte_eth_get_speed(port_id, &speed); - if (speed == 10) { - return TrexPlatformApi::SPEED_10G; - } else { - return TrexPlatformApi::SPEED_40G; - } - } - + TrexPlatformApi::driver_speed_e get_driver_speed(uint8_t port_id); static CTRexExtendedDriverBase * create(){ return ( new CTRexExtendedDriverBase40G() ); } @@ -3282,7 +3272,6 @@ int CGlobalTRex::ixgbe_start(void){ return (0); } - bool CGlobalTRex::Create(){ CFlowsYamlInfo pre_yaml_info; @@ -5351,6 +5340,16 @@ CFlowStatParser *CTRexExtendedDriverBase10G::get_flow_stat_parser() { } //////////////////////////////////////////////////////////////////////////////// +TrexPlatformApi::driver_speed_e CTRexExtendedDriverBase40G::get_driver_speed(uint8_t port_id) { + CPhyEthIF *phy_if = &g_trex.m_ports[port_id]; + + if (phy_if->m_dev_info.speed_capa & ETH_LINK_SPEED_40G) { + return TrexPlatformApi::SPEED_40G; + } else { + return TrexPlatformApi::SPEED_10G; + } + } + void CTRexExtendedDriverBase40G::clear_extended_stats(CPhyEthIF * _if){ rte_eth_stats_reset(_if->get_port_id()); } @@ -5409,7 +5408,7 @@ void CTRexExtendedDriverBase40G::add_del_rules(enum rte_filter_op op, uint8_t po case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER: filter.input.flow.ip4_flow.ttl=ttl; filter.input.flow.ip4_flow.ip_id = ip_id; - filter.input.flow.ip4_flow.l4_protocol = IPPROTO_ICMP; // In this case we want filter for icmp packets + filter.input.flow.ip4_flow.proto = IPPROTO_ICMP; // In this case we want filter for icmp packets break; case RTE_ETH_FLOW_NONFRAG_IPV4_UDP: case RTE_ETH_FLOW_NONFRAG_IPV4_TCP: @@ -5419,11 +5418,11 @@ void CTRexExtendedDriverBase40G::add_del_rules(enum rte_filter_op op, uint8_t po break; case RTE_ETH_FLOW_NONFRAG_IPV6_UDP: case RTE_ETH_FLOW_NONFRAG_IPV6_TCP: - filter.input.flow.ipv6_flow.hop_limit=ttl; + filter.input.flow.ipv6_flow.hop_limits=ttl; break; case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER: - filter.input.flow.ipv6_flow.hop_limit=ttl; - filter.input.flow.ipv6_flow.l4_protocol = IPPROTO_ICMP; // In the future we want to support this + filter.input.flow.ipv6_flow.hop_limits=ttl; + filter.input.flow.ipv6_flow.proto = IPPROTO_ICMP; // In the future we want to support this break; } @@ -5579,36 +5578,19 @@ int CTRexExtendedDriverBase40G::dump_fdir_global_stats(CPhyEthIF * _if, FILE *fd } void CTRexExtendedDriverBase40G::get_extended_stats(CPhyEthIF * _if,CPhyEthIFStats *stats){ - struct rte_eth_stats stats1; 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.ibadcrc + - stats1.ibadlen + - stats1.ierrors + - stats1.oerrors + - stats1.rx_nombuf + - stats1.tx_pause_xon + - stats1.rx_pause_xon + - stats1.tx_pause_xoff+ - stats1.rx_pause_xoff ; - - + stats->ierrors = stats1.imissed + stats1.ierrors + stats1.rx_nombuf; stats->oerrors = stats1.oerrors;; stats->imcasts = 0; stats->rx_nombuf = stats1.rx_nombuf; - } int CTRexExtendedDriverBase40G::wait_for_stable_link(){ @@ -5667,15 +5649,10 @@ void CTRexExtendedDriverBase1GVm::get_extended_stats(CPhyEthIF * _if,CPhyEthIFSt stats->f_ibytes = 0; - stats->ierrors = stats1.imissed + stats1.ibadcrc + - stats1.ibadlen + + stats->ierrors = stats1.imissed + stats1.ierrors + stats1.oerrors + - stats1.rx_nombuf + - stats1.tx_pause_xon + - stats1.rx_pause_xon + - stats1.tx_pause_xoff+ - stats1.rx_pause_xoff ; + stats1.rx_nombuf; stats->oerrors = stats1.oerrors;; -- cgit From 344e3045d8346b4b204692e591e1556fc2333f97 Mon Sep 17 00:00:00 2001 From: imarom Date: Wed, 27 Jul 2016 11:08:09 +0300 Subject: support for graceful shutdown --- src/main_dpdk.cpp | 183 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 146 insertions(+), 37 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 7a6f972a..b6205f33 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -20,6 +20,7 @@ */ #include #include +#include #include #include #include @@ -2486,40 +2487,40 @@ public: void DumpAllPorts(FILE *fd); void dump_json(std::string & json, bool baseline); private: - std::string get_field(std::string name,float &f); - std::string get_field(std::string name,uint64_t &f); - std::string get_field_port(int port,std::string name,float &f); - std::string get_field_port(int port,std::string name,uint64_t &f); + std::string get_field(const char *name, float &f); + std::string get_field(const char *name, uint64_t &f); + std::string get_field_port(int port, const char *name, float &f); + std::string get_field_port(int port, const char *name, uint64_t &f); }; -std::string CGlobalStats::get_field(std::string name,float &f){ +std::string CGlobalStats::get_field(const char *name, float &f){ char buff[200]; if(f <= -10.0 or f >= 10.0) - snprintf(buff, sizeof(buff), "\"%s\":%.1f,",name.c_str(),f); + snprintf(buff, sizeof(buff), "\"%s\":%.1f,",name,f); else - snprintf(buff, sizeof(buff), "\"%s\":%.3e,",name.c_str(),f); + snprintf(buff, sizeof(buff), "\"%s\":%.3e,",name,f); return (std::string(buff)); } -std::string CGlobalStats::get_field(std::string name,uint64_t &f){ +std::string CGlobalStats::get_field(const char *name, uint64_t &f){ char buff[200]; - snprintf(buff, sizeof(buff), "\"%s\":%llu,",name.c_str(), (unsigned long long)f); + snprintf(buff, sizeof(buff), "\"%s\":%llu,", name, (unsigned long long)f); return (std::string(buff)); } -std::string CGlobalStats::get_field_port(int port,std::string name,float &f){ +std::string CGlobalStats::get_field_port(int port, const char *name, float &f){ char buff[200]; if(f <= -10.0 or f >= 10.0) - snprintf(buff, sizeof(buff), "\"%s-%d\":%.1f,",name.c_str(),port,f); + snprintf(buff, sizeof(buff), "\"%s-%d\":%.1f,", name, port, f); else - snprintf(buff, sizeof(buff), "\"%s-%d\":%.3e,",name.c_str(),port,f); + snprintf(buff, sizeof(buff), "\"%s-%d\":%.3e,", name, port, f); return (std::string(buff)); } -std::string CGlobalStats::get_field_port(int port,std::string name,uint64_t &f){ +std::string CGlobalStats::get_field_port(int port, const char *name, uint64_t &f){ char buff[200]; - snprintf(buff, sizeof(buff), "\"%s-%d\":%llu,",name.c_str(),port, (unsigned long long)f); + snprintf(buff, sizeof(buff), "\"%s-%d\":%llu,",name, port, (unsigned long long)f); return (std::string(buff)); } @@ -2538,8 +2539,8 @@ void CGlobalStats::dump_json(std::string & json, bool baseline){ snprintf(ts_buff , sizeof(ts_buff), "\"ts\":{\"value\":%lu, \"freq\":%lu},", os_get_hr_tick_64(), os_get_hr_freq()); json+= std::string(ts_buff); -#define GET_FIELD(f) get_field(std::string(#f),f) -#define GET_FIELD_PORT(p,f) get_field_port(p,std::string(#f),lp->f) +#define GET_FIELD(f) get_field(#f, f) +#define GET_FIELD_PORT(p,f) get_field_port(p, #f, lp->f) json+=GET_FIELD(m_cpu_util); json+=GET_FIELD(m_cpu_util_raw); @@ -2781,6 +2782,7 @@ public: m_expected_cps=0.0; m_expected_bps=0.0; m_trex_stateless = NULL; + m_mark_for_shutdown = false; } bool Create(); @@ -2795,7 +2797,19 @@ public: bool is_all_links_are_up(bool dump=false); int reset_counters(); + /** + * mark for shutdown + * on the next check - the control plane will + * call shutdown() + */ + void mark_for_shutdown(const char *cause) { + printf("\n *** TRex shutting down - cause: '%s'\n", cause); + m_mark_for_shutdown = true; + } + private: + void register_signals(); + /* try to stop all datapath cores and RX core */ void try_stop_all_cores(); /* send message to all dp cores */ @@ -2803,6 +2817,16 @@ private: int send_message_to_rx(TrexStatelessCpToRxMsgBase *msg); void check_for_dp_message_from_core(int thread_id); + bool is_marked_for_shutdown() const { + return m_mark_for_shutdown; + } + + /** + * shutdown sequence + * + */ + void shutdown(); + public: void check_for_dp_messages(); int start_master_statefull(); @@ -2898,6 +2922,7 @@ private: std::mutex m_cp_lock; TrexMonitor m_monitor; + bool m_mark_for_shutdown; public: TrexStateless *m_trex_stateless; @@ -3272,9 +3297,32 @@ int CGlobalTRex::ixgbe_start(void){ return (0); } +static void trex_termination_handler(int signum); + +void CGlobalTRex::register_signals() { + struct sigaction action; + + /* handler */ + action.sa_handler = trex_termination_handler; + + /* blocked signals during handling */ + sigemptyset(&action.sa_mask); + sigaddset(&action.sa_mask, SIGINT); + sigaddset(&action.sa_mask, SIGTERM); + + /* no flags */ + action.sa_flags = 0; + + /* register */ + sigaction(SIGINT, &action, NULL); + sigaction(SIGTERM, &action, NULL); +} + bool CGlobalTRex::Create(){ CFlowsYamlInfo pre_yaml_info; + register_signals(); + m_stats_cnt =0; if (!get_is_stateless()) { pre_yaml_info.load_from_yaml_file(CGlobalInfo::m_options.cfg_file); @@ -3908,17 +3956,16 @@ CGlobalTRex::handle_slow_path(bool &was_stopped) { if ( CGlobalInfo::m_options.preview.get_no_keyboard() ==false ) { if ( m_io_modes.handle_io_modes() ) { - printf(" CTRL -C ... \n"); - was_stopped=true; + mark_for_shutdown("CTRL + C detected"); return false; } } if ( sanity_check() ) { - printf(" Test was stopped \n"); - was_stopped=true; + mark_for_shutdown("Test was stopped"); return false; } + if (m_io_modes.m_g_mode != CTrexGlobalIoMode::gDISABLE ) { fprintf(stdout,"\033[2J"); fprintf(stdout,"\033[2H"); @@ -4032,6 +4079,41 @@ CGlobalTRex::handle_fast_path() { return true; } + +/** + * shutdown sequence + * + */ +void CGlobalTRex::shutdown() { + + /* first stop the WD */ + TrexWatchDog::getInstance().stop(); + + /* stateless shutdown */ + if (get_is_stateless()) { + m_trex_stateless->shutdown(); + } + + if (!is_all_cores_finished()) { + try_stop_all_cores(); + } + + m_mg.stop(); + + delay(1000); + + /* shutdown drivers */ + for (int i = 0; i < m_max_ports; i++) { + rte_eth_dev_stop(i); + } + + if (is_marked_for_shutdown()) { + /* we should stop latency and exit to stop agents */ + exit(-1); + } +} + + int CGlobalTRex::run_in_master() { bool was_stopped=false; @@ -4052,7 +4134,7 @@ int CGlobalTRex::run_in_master() { TrexWatchDog::getInstance().start(); - while ( true ) { + while (!is_marked_for_shutdown()) { /* fast path */ if (!handle_fast_path()) { @@ -4079,22 +4161,9 @@ int CGlobalTRex::run_in_master() { /* on exit release the lock */ cp_lock.unlock(); - /* first stop the WD */ - TrexWatchDog::getInstance().stop(); - - if (!is_all_cores_finished()) { - /* probably CLTR-C */ - try_stop_all_cores(); - } - - m_mg.stop(); - - - delay(1000); - if ( was_stopped ){ - /* we should stop latency and exit to stop agents */ - exit(-1); - } + /* shutdown everything gracefully */ + shutdown(); + return (0); } @@ -5702,6 +5771,37 @@ struct rte_mbuf * rte_mbuf_convert_to_one_seg(struct rte_mbuf *m){ return(r); } +/** + * handle a signal for termination + * + * @author imarom (7/27/2016) + * + * @param signum + */ +static void trex_termination_handler(int signum) { + std::stringstream ss; + + /* be sure that this was given on the main process */ + assert(rte_eal_process_type() == RTE_PROC_PRIMARY); + + const char *signame = ""; + switch (signum) { + case SIGINT: + signame = "SIGINT"; + break; + + case SIGTERM: + signame = "SIGTERM"; + break; + + default: + assert(0); + } + + ss << "receieved signal '" << signame << "'"; + g_trex.mark_for_shutdown(ss.str().c_str()); +} + /*********************************************************** * platfrom API object * TODO: REMOVE THIS TO A SEPERATE FILE @@ -5871,3 +5971,12 @@ int TrexDpdkPlatformApi::get_mbuf_util(Json::Value &mbuf_pool) const { CFlowStatParser *TrexDpdkPlatformApi::get_flow_stat_parser() const { return CTRexExtendedDriverDb::Ins()->get_drv()->get_flow_stat_parser(); } + +/** + * marks the control plane for a total server shutdown + * + * @author imarom (7/27/2016) + */ +void TrexDpdkPlatformApi::mark_for_shutdown(const char *cause) const { + g_trex.mark_for_shutdown(cause); +} -- cgit From 72ff70e2b51f293092bd3c148eea0a4439c1b29e Mon Sep 17 00:00:00 2001 From: imarom Date: Wed, 27 Jul 2016 16:27:33 +0300 Subject: removed was_stopped --- src/main_dpdk.cpp | 110 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 74 insertions(+), 36 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index b6205f33..bcb7f3db 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -2772,6 +2772,20 @@ void CGlobalStats::Dump(FILE *fd,DumpFormat mode){ class CGlobalTRex { public: + + /** + * different types of shutdown causes + */ + typedef enum { + SHUTDOWN_NONE, + SHUTDOWN_TEST_ENDED, + SHUTDOWN_CTRL_C, + SHUTDOWN_SIGINT, + SHUTDOWN_SIGTERM, + SHUTDOWN_RPC_REQ + } shutdown_rc_e; + + CGlobalTRex (){ m_max_ports=4; m_max_cores=1; @@ -2782,7 +2796,7 @@ public: m_expected_cps=0.0; m_expected_bps=0.0; m_trex_stateless = NULL; - m_mark_for_shutdown = false; + m_mark_for_shutdown = SHUTDOWN_NONE; } bool Create(); @@ -2802,9 +2816,13 @@ public: * on the next check - the control plane will * call shutdown() */ - void mark_for_shutdown(const char *cause) { - printf("\n *** TRex shutting down - cause: '%s'\n", cause); - m_mark_for_shutdown = true; + void mark_for_shutdown(shutdown_rc_e rc) { + + if (is_marked_for_shutdown()) { + return; + } + + m_mark_for_shutdown = rc; } private: @@ -2818,7 +2836,7 @@ private: void check_for_dp_message_from_core(int thread_id); bool is_marked_for_shutdown() const { - return m_mark_for_shutdown; + return (m_mark_for_shutdown != SHUTDOWN_NONE); } /** @@ -2842,8 +2860,8 @@ public: int run_in_rx_core(); int run_in_master(); - bool handle_fast_path(); - bool handle_slow_path(bool &was_stopped); + void handle_fast_path(); + void handle_slow_path(); int stop_master(); /* return the minimum number of dp cores needed to support the active ports @@ -2922,7 +2940,8 @@ private: std::mutex m_cp_lock; TrexMonitor m_monitor; - bool m_mark_for_shutdown; + + shutdown_rc_e m_mark_for_shutdown; public: TrexStateless *m_trex_stateless; @@ -3949,21 +3968,21 @@ CGlobalTRex::publish_async_barrier(uint32_t key) { } -bool -CGlobalTRex::handle_slow_path(bool &was_stopped) { +void +CGlobalTRex::handle_slow_path() { m_stats_cnt+=1; if ( CGlobalInfo::m_options.preview.get_no_keyboard() ==false ) { if ( m_io_modes.handle_io_modes() ) { - mark_for_shutdown("CTRL + C detected"); - return false; + mark_for_shutdown(SHUTDOWN_CTRL_C); + return; } } if ( sanity_check() ) { - mark_for_shutdown("Test was stopped"); - return false; + mark_for_shutdown(SHUTDOWN_TEST_ENDED); + return; } if (m_io_modes.m_g_mode != CTrexGlobalIoMode::gDISABLE ) { @@ -4054,12 +4073,10 @@ CGlobalTRex::handle_slow_path(bool &was_stopped) { /* publish data */ publish_async_data(false); - - return true; } -bool +void CGlobalTRex::handle_fast_path() { /* check from messages from DP */ check_for_dp_messages(); @@ -4073,10 +4090,8 @@ CGlobalTRex::handle_fast_path() { } if ( is_all_cores_finished() ) { - return false; + mark_for_shutdown(SHUTDOWN_TEST_ENDED); } - - return true; } @@ -4085,6 +4100,37 @@ CGlobalTRex::handle_fast_path() { * */ void CGlobalTRex::shutdown() { + std::stringstream ss; + ss << " *** TRex is shutting down - cause: '"; + + switch (m_mark_for_shutdown) { + + case SHUTDOWN_TEST_ENDED: + ss << "test has ended'"; + break; + + case SHUTDOWN_CTRL_C: + ss << "CTRL + C detected'"; + break; + + case SHUTDOWN_SIGINT: + ss << "received signal SIGINT'"; + break; + + case SHUTDOWN_SIGTERM: + ss << "received signal SIGTERM'"; + break; + + case SHUTDOWN_RPC_REQ: + ss << "server received RPC 'shutdown' request'"; + break; + + default: + assert(0); + } + + /* report */ + std::cout << ss.str() << "\n"; /* first stop the WD */ TrexWatchDog::getInstance().stop(); @@ -4104,10 +4150,10 @@ void CGlobalTRex::shutdown() { /* shutdown drivers */ for (int i = 0; i < m_max_ports; i++) { - rte_eth_dev_stop(i); + m_ports[i].stop(); } - if (is_marked_for_shutdown()) { + if (m_mark_for_shutdown != SHUTDOWN_TEST_ENDED) { /* we should stop latency and exit to stop agents */ exit(-1); } @@ -4115,7 +4161,6 @@ void CGlobalTRex::shutdown() { int CGlobalTRex::run_in_master() { - bool was_stopped=false; if ( get_is_stateless() ) { m_trex_stateless->launch_control_plane(); @@ -4137,15 +4182,11 @@ int CGlobalTRex::run_in_master() { while (!is_marked_for_shutdown()) { /* fast path */ - if (!handle_fast_path()) { - break; - } + handle_fast_path(); /* slow path */ if (slow_path_counter >= SLOWPATH_DELAY_MS) { - if (!handle_slow_path(was_stopped)) { - break; - } + handle_slow_path(); slow_path_counter = 0; } @@ -5784,22 +5825,19 @@ static void trex_termination_handler(int signum) { /* be sure that this was given on the main process */ assert(rte_eal_process_type() == RTE_PROC_PRIMARY); - const char *signame = ""; switch (signum) { case SIGINT: - signame = "SIGINT"; + g_trex.mark_for_shutdown(CGlobalTRex::SHUTDOWN_SIGINT); break; case SIGTERM: - signame = "SIGTERM"; + g_trex.mark_for_shutdown(CGlobalTRex::SHUTDOWN_SIGTERM); break; default: assert(0); } - ss << "receieved signal '" << signame << "'"; - g_trex.mark_for_shutdown(ss.str().c_str()); } /*********************************************************** @@ -5977,6 +6015,6 @@ CFlowStatParser *TrexDpdkPlatformApi::get_flow_stat_parser() const { * * @author imarom (7/27/2016) */ -void TrexDpdkPlatformApi::mark_for_shutdown(const char *cause) const { - g_trex.mark_for_shutdown(cause); +void TrexDpdkPlatformApi::mark_for_shutdown() const { + g_trex.mark_for_shutdown(CGlobalTRex::SHUTDOWN_RPC_REQ); } -- cgit