From c4e6748cedf1f9f3a3c1916c96c4f044561b075b Mon Sep 17 00:00:00 2001 From: imarom Date: Mon, 9 May 2016 14:25:21 +0300 Subject: PCAP remote code review fixes --- src/bp_sim.cpp | 191 +++++++++++++++------------- src/bp_sim.h | 4 + src/main_dpdk.cpp | 24 ++-- src/stateless/dp/trex_stateless_dp_core.cpp | 10 -- src/stateless/dp/trex_stream_node.h | 2 +- 5 files changed, 126 insertions(+), 105 deletions(-) (limited to 'src') diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp index 18b1053e..c658248e 100755 --- a/src/bp_sim.cpp +++ b/src/bp_sim.cpp @@ -3709,19 +3709,6 @@ int CNodeGenerator::flush_file(dsec_t max_time, thread->free_node(node); } - } else if (type == CGenNode::PCAP_PKT) { - m_p_queue.pop(); - - CGenNodePCAP *node_pcap = (CGenNodePCAP *)node; - - /* might have been marked for free */ - if ( unlikely( node_pcap->is_marked_for_free() ) ) { - thread->free_node(node); - } else { - node_pcap->handle(thread); - } - - } else { bool exit_sccheduler = handle_slow_messages(type,node,thread,always); if (exit_sccheduler) { @@ -3743,6 +3730,87 @@ int CNodeGenerator::flush_file(dsec_t max_time, return (0); } + +void CNodeGenerator::handle_flow_pkt(CGenNode *node, CFlowGenListPerThread *thread) { + + /*repeat and NAT is not supported */ + if ( node->is_nat_first_state() ) { + node->set_nat_wait_state(); + flush_one_node_to_file(node); + #ifdef _DEBUG + update_stats(node); + #endif + } else { + if ( node->is_nat_wait_state() ) { + if (node->is_responder_pkt()) { + m_p_queue.pop(); + /* time out, need to free the flow and remove the association , we didn't get convertion yet*/ + thread->terminate_nat_flows(node); + return; + + } else { + flush_one_node_to_file(node); + #ifdef _DEBUG + update_stats(node); + #endif + } + } else { + assert(0); + } + } + m_p_queue.pop(); + if ( node->is_last_in_flow() ) { + thread->free_last_flow_node( node); + } else { + node->update_next_pkt_in_flow(); + m_p_queue.push(node); + } +} + +void CNodeGenerator::handle_flow_sync(CGenNode *node, CFlowGenListPerThread *thread, bool &exit_scheduler) { + /* flow sync message is a sync point for time */ + thread->m_cur_time_sec = node->m_time; + + /* first pop the node */ + m_p_queue.pop(); + + thread->check_msgs(); /* check messages */ + m_v_if->flush_tx_queue(); /* flush pkt each timeout */ + + /* exit in case this is the last node*/ + if ( m_p_queue.size() == m_parent->m_non_active_nodes ) { + thread->free_node(node); + exit_scheduler = true; + } else { + /* schedule for next maintenace */ + node->m_time += SYNC_TIME_OUT; + m_p_queue.push(node); + } + +} + +void CNodeGenerator::handle_command(CGenNode *node, CFlowGenListPerThread *thread, bool &exit_scheduler) { + m_p_queue.pop(); + CGenNodeCommand *node_cmd = (CGenNodeCommand *)node; + TrexStatelessCpToDpMsgBase * cmd=node_cmd->m_cmd; + cmd->handle(&thread->m_stateless_dp_info); + exit_scheduler = cmd->is_quit(); + thread->free_node((CGenNode *)node_cmd);/* free the node */ +} + +void CNodeGenerator::handle_pcap_pkt(CGenNode *node, CFlowGenListPerThread *thread) { + m_p_queue.pop(); + + CGenNodePCAP *node_pcap = (CGenNodePCAP *)node; + + /* might have been marked for free */ + if ( unlikely( node_pcap->is_marked_for_free() ) ) { + thread->free_node(node); + } else { + node_pcap->handle(thread); + } +} + bool CNodeGenerator::handle_slow_messages(uint8_t type, CGenNode * node, @@ -3752,89 +3820,42 @@ CNodeGenerator::handle_slow_messages(uint8_t type, /* should we continue after */ bool exit_scheduler = false; - if (unlikely (type == CGenNode::FLOW_DEFER_PORT_RELEASE) ) { + switch (type) { + case CGenNode::PCAP_PKT: + handle_pcap_pkt(node, thread); + break; + + case CGenNode::FLOW_DEFER_PORT_RELEASE: m_p_queue.pop(); thread->handler_defer_job(node); thread->free_node(node); + break; - } else if (type == CGenNode::FLOW_PKT_NAT) { - /*repeat and NAT is not supported */ - if ( node->is_nat_first_state() ){ - node->set_nat_wait_state(); - flush_one_node_to_file(node); - #ifdef _DEBUG - update_stats(node); - #endif - }else{ - if ( node->is_nat_wait_state() ) { - if (node->is_responder_pkt()) { - m_p_queue.pop(); - /* time out, need to free the flow and remove the association , we didn't get convertion yet*/ - thread->terminate_nat_flows(node); - return (exit_scheduler); - - }else{ - flush_one_node_to_file(node); - #ifdef _DEBUG - update_stats(node); - #endif - } - }else{ - assert(0); - } - } - m_p_queue.pop(); - if ( node->is_last_in_flow() ) { - thread->free_last_flow_node( node); - }else{ - node->update_next_pkt_in_flow(); - m_p_queue.push(node); - } - - } else if ( type == CGenNode::FLOW_SYNC ) { + case CGenNode::FLOW_PKT_NAT: + handle_flow_pkt(node, thread); + break; - /* flow sync message is a sync point for time */ - thread->m_cur_time_sec = node->m_time; + case CGenNode::FLOW_SYNC: + handle_flow_sync(node, thread, exit_scheduler); + break; - /* first pop the node */ - m_p_queue.pop(); + case CGenNode::EXIT_SCHED: + m_p_queue.pop(); + thread->free_node(node); + exit_scheduler = true; + break; - thread->check_msgs(); /* check messages */ - m_v_if->flush_tx_queue(); /* flush pkt each timeout */ - /* exit in case this is the last node*/ - if ( m_p_queue.size() == m_parent->m_non_active_nodes ) { - thread->free_node(node); - exit_scheduler = true; - } else { - /* schedule for next maintenace */ - node->m_time += SYNC_TIME_OUT; - m_p_queue.push(node); - } + case CGenNode::COMMAND: + handle_command(node, thread, exit_scheduler); + break; + default: + assert(0); + } - } else if ( type == CGenNode::EXIT_SCHED ) { - m_p_queue.pop(); - thread->free_node(node); - exit_scheduler = true; - - } else { - if ( type == CGenNode::COMMAND) { - m_p_queue.pop(); - CGenNodeCommand *node_cmd = (CGenNodeCommand *)node; - { - TrexStatelessCpToDpMsgBase * cmd=node_cmd->m_cmd; - cmd->handle(&thread->m_stateless_dp_info); - exit_scheduler = cmd->is_quit(); - thread->free_node((CGenNode *)node_cmd);/* free the node */ - } - }else{ - printf(" ERROR type is not valid %d \n",type); - assert(0); - } - } + return (exit_scheduler); - return exit_scheduler; } diff --git a/src/bp_sim.h b/src/bp_sim.h index 77101508..8f003eee 100755 --- a/src/bp_sim.h +++ b/src/bp_sim.h @@ -2036,6 +2036,10 @@ private: CFlowGenListPerThread * thread, bool always); + void handle_command(CGenNode *node, CFlowGenListPerThread *thread, bool &exit_scheduler); + void handle_flow_pkt(CGenNode *node, CFlowGenListPerThread *thread); + void handle_flow_sync(CGenNode *node, CFlowGenListPerThread *thread, bool &exit_scheduler); + void handle_pcap_pkt(CGenNode *node, CFlowGenListPerThread *thread); public: pqueue_t m_p_queue; diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index c8921ba7..05d89f9d 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -3859,24 +3859,30 @@ int CGlobalTRex::run_in_master() { /* exception and scope safe */ std::unique_lock cp_lock(m_cp_lock); - uint32_t slow_path_ms = 0; + uint32_t slow_path_counter = 0; + + const int FASTPATH_DELAY_MS = 20; + const int SLOWPATH_DELAY_MS = 500; while ( true ) { - if (slow_path_ms >= 500) { + /* fast path */ + if (!handle_fast_path()) { + break; + } + + /* slow path */ + if (slow_path_counter >= SLOWPATH_DELAY_MS) { if (!handle_slow_path(was_stopped)) { break; } - slow_path_ms = 0; + slow_path_counter = 0; } - if (!handle_fast_path()) { - break; - } - + cp_lock.unlock(); - delay(20); - slow_path_ms += 20; + delay(FASTPATH_DELAY_MS); + slow_path_counter += FASTPATH_DELAY_MS; cp_lock.lock(); } diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp index dff5285d..1a730e66 100644 --- a/src/stateless/dp/trex_stateless_dp_core.cpp +++ b/src/stateless/dp/trex_stateless_dp_core.cpp @@ -946,19 +946,9 @@ TrexStatelessDpCore::stop_traffic(uint8_t port_id, TrexStatelessDpPerPort * lp_port = get_port_db(port_id); if ( lp_port->stop_traffic(port_id,stop_on_id,event_id) == false){ - /* nothing to do ! already stopped */ - //printf(" skip .. %f\n",m_core->m_cur_time_sec); return; } - /* inform the control plane we stopped - this might be a async stop - (streams ended) - */ - #if 0 - if ( are_all_ports_idle() ) { - /* just a place holder if we will need to do somthing in that case */ - } - #endif CNodeRing *ring = CMsgIns::Ins()->getCpDp()->getRingDpToCp(m_core->m_thread_id); TrexStatelessDpToCpMsgBase *event_msg = new TrexDpPortEventMsg(m_core->m_thread_id, diff --git a/src/stateless/dp/trex_stream_node.h b/src/stateless/dp/trex_stream_node.h index bdbc5084..de4c21de 100644 --- a/src/stateless/dp/trex_stream_node.h +++ b/src/stateless/dp/trex_stream_node.h @@ -552,7 +552,7 @@ private: uint8_t m_port_id; /* pad to match the size of CGenNode */ - uint8_t m_pad_end[25]; + uint8_t m_pad_end[33]; } __rte_cache_aligned; -- cgit 1.2.3-korg