diff options
-rw-r--r-- | scripts/automation/regression/stateless_tests/stl_client_test.py | 27 | ||||
-rw-r--r-- | src/stateless/cp/trex_dp_port_events.cpp | 20 | ||||
-rw-r--r-- | src/stateless/cp/trex_dp_port_events.h | 8 | ||||
-rw-r--r-- | src/stateless/cp/trex_stateless_port.cpp | 26 | ||||
-rw-r--r-- | src/stateless/cp/trex_stateless_port.h | 3 |
5 files changed, 78 insertions, 6 deletions
diff --git a/scripts/automation/regression/stateless_tests/stl_client_test.py b/scripts/automation/regression/stateless_tests/stl_client_test.py index ed125cde..f3bb3188 100644 --- a/scripts/automation/regression/stateless_tests/stl_client_test.py +++ b/scripts/automation/regression/stateless_tests/stl_client_test.py @@ -297,3 +297,30 @@ class STLClient_Test(CStlGeneral_Test): finally: self.c.set_port_attr(ports = [self.tx_port, self.rx_port], promiscuous = False) + + + # see https://trex-tgn.cisco.com/youtrack/issue/trex-226 + def test_latency_pause_resume (self): + + try: + + s1 = STLStream(name = 'latency', + packet = self.pkt, + mode = STLTXCont(percentage = self.percentage), + flow_stats = STLFlowLatencyStats(pg_id = 1)) + + self.c.add_streams([s1], ports = self.tx_port) + + self.c.clear_stats() + + # mult has no meaning on latency - just messing around with the test + self.c.start(ports = self.tx_port, mult = "10mpps") + + for i in range(100): + self.c.pause() + self.c.resume() + + self.c.stop() + + except STLError as e: + assert False , '{0}'.format(e) diff --git a/src/stateless/cp/trex_dp_port_events.cpp b/src/stateless/cp/trex_dp_port_events.cpp index fc96e00a..f06390ce 100644 --- a/src/stateless/cp/trex_dp_port_events.cpp +++ b/src/stateless/cp/trex_dp_port_events.cpp @@ -123,6 +123,20 @@ TrexDpPortEvents::on_core_reporting_in(int event_id, int thread_id, bool status) } +/** + * return true if a core is still pending on an event + */ +bool +TrexDpPortEvents::is_core_pending_on_event(int event_id, int thread_id) { + TrexDpPortEvent *event = lookup(event_id); + /* event might have been deleted */ + if (!event) { + return false; + } + + return event->is_core_pending_on_event(thread_id); +} + /*************************** * event * @@ -180,4 +194,8 @@ TrexDpPortEvent::on_core_reporting_in(int thread_id, bool status) { } } - +bool +TrexDpPortEvent::is_core_pending_on_event(int thread_id) { + /* if the core has yet to mark its 'done' bit - it is still pending */ + return !m_signal.at(thread_id); +} diff --git a/src/stateless/cp/trex_dp_port_events.h b/src/stateless/cp/trex_dp_port_events.h index 681e47ab..be549a55 100644 --- a/src/stateless/cp/trex_dp_port_events.h +++ b/src/stateless/cp/trex_dp_port_events.h @@ -64,6 +64,7 @@ protected: private: void init(TrexStatelessPort *port, int event_id, int timeout_ms); bool on_core_reporting_in(int thread_id, bool status = true); + bool is_core_pending_on_event(int thread_id); std::unordered_map<int, bool> m_signal; int m_pending_cnt; @@ -109,6 +110,13 @@ public: */ void on_core_reporting_in(int event_id, int thread_id, bool status = true); + /** + * return true if core has yet to respond + * to the event + * + */ + bool is_core_pending_on_event(int event_id, int thread_id); + private: TrexDpPortEvent *lookup(int event_id); diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp index 0fe4b410..376453b9 100644 --- a/src/stateless/cp/trex_stateless_port.cpp +++ b/src/stateless/cp/trex_stateless_port.cpp @@ -394,6 +394,17 @@ TrexStatelessPort::common_port_stop_actions(bool async) { } +/** + * core is considered active if it has a pending for async stop + * + */ +bool +TrexStatelessPort::is_core_active(int core_id) { + return ( (m_pending_async_stop_event != TrexDpPortEvents::INVALID_ID) && + (m_dp_events.is_core_pending_on_event(m_pending_async_stop_event, core_id)) + ); +} + void TrexStatelessPort::pause_traffic(void) { @@ -409,7 +420,9 @@ TrexStatelessPort::pause_traffic(void) { /* send a pause message */ TrexStatelessCpToDpMsgBase *pause_msg = new TrexStatelessDpPause(m_port_id); - send_message_to_all_dp(pause_msg); + + /* send message to all cores */ + send_message_to_all_dp(pause_msg, true); /* make sure all DP cores paused */ m_dp_events.barrier(); @@ -431,10 +444,9 @@ TrexStatelessPort::resume_traffic(void) { /* generate a message to all the relevant DP cores to start transmitting */ TrexStatelessCpToDpMsgBase *resume_msg = new TrexStatelessDpResume(m_port_id); - send_message_to_all_dp(resume_msg); + send_message_to_all_dp(resume_msg, true); change_state(PORT_STATE_TX); - Json::Value data; data["port_id"] = m_port_id; get_stateless_obj()->get_publisher()->publish_event(TrexPublisher::EVENT_PORT_RESUMED, data); @@ -609,9 +621,15 @@ TrexStatelessPort::encode_stats(Json::Value &port) { } void -TrexStatelessPort::send_message_to_all_dp(TrexStatelessCpToDpMsgBase *msg) { +TrexStatelessPort::send_message_to_all_dp(TrexStatelessCpToDpMsgBase *msg, bool send_to_active_only) { for (auto core_id : m_cores_id_list) { + + /* skip non active cores if requested */ + if ( (send_to_active_only) && (!is_core_active(core_id)) ) { + continue; + } + send_message_to_dp(core_id, msg->clone()); } diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h index 915c5325..b1f6ddfe 100644 --- a/src/stateless/cp/trex_stateless_port.h +++ b/src/stateless/cp/trex_stateless_port.h @@ -378,6 +378,7 @@ public: private: + bool is_core_active(int core_id); const std::vector<int> get_core_id_list () { return m_cores_id_list; @@ -393,7 +394,7 @@ private: * send message to all cores using duplicate * */ - void send_message_to_all_dp(TrexStatelessCpToDpMsgBase *msg); + void send_message_to_all_dp(TrexStatelessCpToDpMsgBase *msg, bool send_to_active_only = false); /** * send message to specific DP core |