diff options
Diffstat (limited to 'src/stateless')
-rw-r--r-- | src/stateless/cp/trex_stateless_port.cpp | 7 | ||||
-rw-r--r-- | src/stateless/cp/trex_stateless_port.h | 100 | ||||
-rw-r--r-- | src/stateless/dp/trex_stateless_dp_core.cpp | 16 | ||||
-rw-r--r-- | src/stateless/messaging/trex_stateless_messaging.cpp | 42 | ||||
-rw-r--r-- | src/stateless/messaging/trex_stateless_messaging.h | 76 | ||||
-rw-r--r-- | src/stateless/rx/trex_stateless_rx_core.cpp | 112 | ||||
-rw-r--r-- | src/stateless/rx/trex_stateless_rx_core.h | 18 |
7 files changed, 252 insertions, 119 deletions
diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp index 5947aaf7..90589d7a 100644 --- a/src/stateless/cp/trex_stateless_port.cpp +++ b/src/stateless/cp/trex_stateless_port.cpp @@ -473,6 +473,13 @@ TrexStatelessPort::send_message_to_dp(uint8_t core_id, TrexStatelessCpToDpMsgBas ring->Enqueue((CGenNode *)msg); } +void +TrexStatelessPort::send_message_to_rx(TrexStatelessCpToRxMsgBase *msg) { + + /* send the message to the core */ + CNodeRing *ring = CMsgIns::Ins()->getCpRx()->getRingCpToDp(0); + ring->Enqueue((CGenNode *)msg); +} uint64_t TrexStatelessPort::get_port_speed_bps() const { diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h index d3c4dcb9..7e1838d4 100644 --- a/src/stateless/cp/trex_stateless_port.h +++ b/src/stateless/cp/trex_stateless_port.h @@ -4,7 +4,7 @@ */ /* -Copyright (c) 2015-2015 Cisco Systems, Inc. +Copyright (c) 2015-2016 Cisco Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -21,20 +21,21 @@ limitations under the License. #ifndef __TREX_STATELESS_PORT_H__ #define __TREX_STATELESS_PORT_H__ -#include <trex_stream.h> -#include <trex_dp_port_events.h> -#include <internal_api/trex_platform_api.h> +#include "internal_api/trex_platform_api.h" +#include "trex_dp_port_events.h" +#include "trex_stream.h" class TrexStatelessCpToDpMsgBase; +class TrexStatelessCpToRxMsgBase; class TrexStreamsGraphObj; class TrexPortMultiplier; -/** +/** * TRex port owner can perform * write commands * while port is owned - others can * do read only commands - * + * */ class TrexPortOwner { public: @@ -92,7 +93,7 @@ private: /* handler genereated internally */ std::string m_handler; - + /* seed for generating random values */ unsigned int m_seed; @@ -106,7 +107,7 @@ class AsyncStopEvent; /** * describes a stateless port - * + * * @author imarom (31-Aug-15) */ class TrexStatelessPort { @@ -137,9 +138,9 @@ public: RC_ERR_FAILED_TO_COMPILE_STREAMS }; - + TrexStatelessPort(uint8_t port_id, const TrexPlatformApi *api); - + ~TrexStatelessPort(); /** @@ -155,11 +156,11 @@ public: void release(void); /** - * validate the state of the port before start - * it will return a stream graph - * containing information about the streams - * configured on this port - * + * validate the state of the port before start + * it will return a stream graph + * containing information about the streams + * configured on this port + * * on error it throws TrexException */ const TrexStreamsGraphObj *validate(void); @@ -190,13 +191,13 @@ public: /** * update current traffic on port - * + * */ void update_traffic(const TrexPortMultiplier &mul, bool force); /** * get the port state - * + * */ port_state_e get_state() const { return m_port_state; @@ -204,23 +205,23 @@ public: /** * port state as string - * + * */ std::string get_state_as_string() const; /** * the the max stream id currently assigned - * + * */ int get_max_stream_id() const; /** * fill up properties of the port - * + * * @author imarom (16-Sep-15) - * - * @param driver - * @param speed + * + * @param driver + * @param speed */ void get_properties(std::string &driver, TrexPlatformApi::driver_speed_e &speed); @@ -237,7 +238,7 @@ public: /** * delegators - * + * */ void add_stream(TrexStream *stream); @@ -267,7 +268,7 @@ public: /** * returns the number of DP cores linked to this port - * + * */ uint8_t get_dp_core_count() { return m_cores_id_list.size(); @@ -275,7 +276,7 @@ public: /** * returns the traffic multiplier currently being used by the DP - * + * */ double get_multiplier() { return (m_factor); @@ -283,13 +284,13 @@ public: /** * get port speed in bits per second - * + * */ uint64_t get_port_speed_bps() const; /** * return RX caps - * + * */ int get_rx_caps() const { return m_rx_caps; @@ -300,12 +301,12 @@ public: } /** - * return true if port adds CRC to a packet (not occurs for - * VNICs) - * + * return true if port adds CRC to a packet (not occurs for + * VNICs) + * * @author imarom (24-Feb-16) - * - * @return bool + * + * @return bool */ bool has_crc_added() const { return m_api_info.has_crc; @@ -318,9 +319,9 @@ public: /** * get the port effective rate (on a started / paused port) - * + * * @author imarom (07-Jan-16) - * + * */ void get_port_effective_rate(double &pps, double &bps_L1, @@ -330,8 +331,8 @@ public: /** * set port promiscuous on/off - * - * @param enabled + * + * @param enabled */ void set_promiscuous(bool enabled); bool get_promiscuous(); @@ -357,40 +358,45 @@ private: /** * send message to all cores using duplicate - * + * */ void send_message_to_all_dp(TrexStatelessCpToDpMsgBase *msg); /** * send message to specific DP core - * + * */ void send_message_to_dp(uint8_t core_id, TrexStatelessCpToDpMsgBase *msg); + /** + * send message to specific RX core + * + */ + void send_message_to_rx(TrexStatelessCpToRxMsgBase *msg); /** * when a port stops, perform various actions - * + * */ void common_port_stop_actions(bool async); /** * calculate effective M per core - * + * */ double calculate_effective_factor(const TrexPortMultiplier &mul, bool force = false); double calculate_effective_factor_internal(const TrexPortMultiplier &mul); - + /** * generates a graph of streams graph - * + * */ void generate_streams_graph(); /** * dispose of it - * + * * @author imarom (26-Nov-15) */ void delete_streams_graph(); @@ -426,7 +432,7 @@ private: /** * port multiplier object - * + * */ class TrexPortMultiplier { public: @@ -443,8 +449,8 @@ public: }; /** - * multiplier can be absolute value - * increment value or subtract value + * multiplier can be absolute value + * increment value or subtract value */ enum mul_op_e { OP_ABS, diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp index f8d6d828..ba25f61d 100644 --- a/src/stateless/dp/trex_stateless_dp_core.cpp +++ b/src/stateless/dp/trex_stateless_dp_core.cpp @@ -5,7 +5,7 @@ */ /* -Copyright (c) 2015-2015 Cisco Systems, Inc. +Copyright (c) 2015-2016 Cisco Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,14 +19,12 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include <trex_stateless_dp_core.h> -#include <trex_stateless_messaging.h> -#include <trex_streams_compiler.h> -#include <trex_stream_node.h> -#include <trex_stream.h> - -#include <bp_sim.h> - +#include "bp_sim.h" +#include "trex_stateless_dp_core.h" +#include "trex_stateless_messaging.h" +#include "trex_stream.h" +#include "trex_stream_node.h" +#include "trex_streams_compiler.h" void CDpOneStream::Delete(CFlowGenListPerThread * core){ assert(m_node->get_state() == CGenNodeStateless::ss_INACTIVE); diff --git a/src/stateless/messaging/trex_stateless_messaging.cpp b/src/stateless/messaging/trex_stateless_messaging.cpp index 333aec88..3468d622 100644 --- a/src/stateless/messaging/trex_stateless_messaging.cpp +++ b/src/stateless/messaging/trex_stateless_messaging.cpp @@ -5,7 +5,7 @@ */ /* -Copyright (c) 2015-2015 Cisco Systems, Inc. +Copyright (c) 2015-2016 Cisco Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,17 +19,18 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include <trex_stateless_messaging.h> -#include <trex_stateless_dp_core.h> -#include <trex_streams_compiler.h> -#include <trex_stateless.h> -#include <bp_sim.h> - #include <string.h> +#include "trex_stateless_messaging.h" +#include "trex_stateless_dp_core.h" +#include "trex_stateless_rx_core.h" +#include "trex_streams_compiler.h" +#include "trex_stateless.h" +#include "bp_sim.h" + /************************* start traffic message - ************************/ + ************************/ TrexStatelessDpStart::TrexStatelessDpStart(uint8_t port_id, int event_id, TrexStreamsCompiledObj *obj, double duration) { m_port_id = port_id; m_event_id = event_id; @@ -40,7 +41,7 @@ TrexStatelessDpStart::TrexStatelessDpStart(uint8_t port_id, int event_id, TrexSt /** * clone for DP start message - * + * */ TrexStatelessCpToDpMsgBase * TrexStatelessDpStart::clone() { @@ -69,7 +70,7 @@ TrexStatelessDpStart::handle(TrexStatelessDpCore *dp_core) { /************************* stop traffic message - ************************/ + ************************/ bool TrexStatelessDpStop::handle(TrexStatelessDpCore *dp_core) { @@ -114,7 +115,7 @@ bool TrexStatelessDpResume::handle(TrexStatelessDpCore *dp_core){ /** * clone for DP stop message - * + * */ TrexStatelessCpToDpMsgBase * TrexStatelessDpStop::clone() { @@ -130,7 +131,7 @@ TrexStatelessDpStop::clone() { -TrexStatelessCpToDpMsgBase * +TrexStatelessCpToDpMsgBase * TrexStatelessDpQuit::clone(){ TrexStatelessCpToDpMsgBase *new_msg = new TrexStatelessDpQuit(); @@ -140,7 +141,7 @@ TrexStatelessDpQuit::clone(){ bool TrexStatelessDpQuit::handle(TrexStatelessDpCore *dp_core){ - + /* quit */ dp_core->quit_main_loop(); return (true); @@ -155,7 +156,7 @@ bool TrexStatelessDpCanQuit::handle(TrexStatelessDpCore *dp_core){ return (true); } -TrexStatelessCpToDpMsgBase * +TrexStatelessCpToDpMsgBase * TrexStatelessDpCanQuit::clone(){ TrexStatelessCpToDpMsgBase *new_msg = new TrexStatelessDpCanQuit(); @@ -165,7 +166,7 @@ TrexStatelessDpCanQuit::clone(){ /************************* update traffic message - ************************/ + ************************/ bool TrexStatelessDpUpdate::handle(TrexStatelessDpCore *dp_core) { dp_core->update_traffic(m_port_id, m_factor); @@ -207,3 +208,14 @@ TrexDpPortEventMsg::handle() { return (true); } +/************************* messages from CP to RX **********************/ +bool TrexRxStartMsg::handle (CRxCoreStateless *rx_core) { + rx_core->work(); + return true; +} + +/************************* messages from CP to RX **********************/ +bool TrexRxStopMsg::handle (CRxCoreStateless *rx_core) { + rx_core->idle(); + return true; +} diff --git a/src/stateless/messaging/trex_stateless_messaging.h b/src/stateless/messaging/trex_stateless_messaging.h index dda086b7..b7e8fd3f 100644 --- a/src/stateless/messaging/trex_stateless_messaging.h +++ b/src/stateless/messaging/trex_stateless_messaging.h @@ -5,7 +5,7 @@ */ /* -Copyright (c) 2015-2015 Cisco Systems, Inc. +Copyright (c) 2015-2016 Cisco Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -22,16 +22,17 @@ limitations under the License. #ifndef __TREX_STATELESS_MESSAGING_H__ #define __TREX_STATELESS_MESSAGING_H__ -#include <msg_manager.h> -#include <trex_dp_port_events.h> +#include "msg_manager.h" +#include "trex_dp_port_events.h" class TrexStatelessDpCore; +class CRxCoreStateless; class TrexStreamsCompiledObj; class CFlowGenListPerThread; /** * defines the base class for CP to DP messages - * + * * @author imarom (27-Oct-15) */ class TrexStatelessCpToDpMsgBase { @@ -49,7 +50,7 @@ public: /** * clone the current message - * + * */ virtual TrexStatelessCpToDpMsgBase * clone() = 0; @@ -76,7 +77,7 @@ protected: /** * a message to start traffic - * + * * @author imarom (27-Oct-15) */ class TrexStatelessDpStart : public TrexStatelessCpToDpMsgBase { @@ -137,7 +138,7 @@ private: /** * a message to stop traffic - * + * * @author imarom (27-Oct-15) */ class TrexStatelessDpStop : public TrexStatelessCpToDpMsgBase { @@ -191,9 +192,9 @@ private: }; /** - * a message to Quit the datapath traffic. support only stateless for now - * - * @author hhaim + * a message to Quit the datapath traffic. support only stateless for now + * + * @author hhaim */ class TrexStatelessDpQuit : public TrexStatelessCpToDpMsgBase { public: @@ -209,9 +210,9 @@ public: }; /** - * a message to check if both port are idel and exit - * - * @author hhaim + * a message to check if both port are idel and exit + * + * @author hhaim */ class TrexStatelessDpCanQuit : public TrexStatelessCpToDpMsgBase { public: @@ -247,7 +248,7 @@ private: /** * barrier message for DP core - * + * */ class TrexStatelessDpBarrier : public TrexStatelessCpToDpMsgBase { public: @@ -270,7 +271,7 @@ private: /** * defines the base class for CP to DP messages - * + * * @author imarom (27-Oct-15) */ class TrexStatelessDpToCpMsgBase { @@ -284,7 +285,7 @@ public: /** * virtual function to handle a message - * + * */ virtual bool handle() = 0; @@ -295,9 +296,9 @@ public: /** - * a message indicating an event has happened on a port at the - * DP - * + * a message indicating an event has happened on a port at the + * DP + * */ class TrexDpPortEventMsg : public TrexStatelessDpToCpMsgBase { public: @@ -326,8 +327,41 @@ private: int m_thread_id; uint8_t m_port_id; int m_event_id; - + }; -#endif /* __TREX_STATELESS_MESSAGING_H__ */ +/************************* messages from CP to RX **********************/ + +/** + * defines the base class for CP to RX messages + * + */ +class TrexStatelessCpToRxMsgBase { +public: + TrexStatelessCpToRxMsgBase() { + } + + virtual ~TrexStatelessCpToRxMsgBase() { + } + + /** + * virtual function to handle a message + * + */ + virtual bool handle (CRxCoreStateless *rx_core) = 0; + + /* no copy constructor */ + TrexStatelessCpToRxMsgBase(TrexStatelessCpToRxMsgBase &) = delete; + +}; + +class TrexRxStartMsg : public TrexStatelessCpToRxMsgBase { + bool handle (CRxCoreStateless *rx_core); +}; + +class TrexRxStopMsg : public TrexStatelessCpToRxMsgBase { + bool handle (CRxCoreStateless *rx_core); +}; + +#endif /* __TREX_STATELESS_MESSAGING_H__ */ diff --git a/src/stateless/rx/trex_stateless_rx_core.cpp b/src/stateless/rx/trex_stateless_rx_core.cpp index a108bef3..86711189 100644 --- a/src/stateless/rx/trex_stateless_rx_core.cpp +++ b/src/stateless/rx/trex_stateless_rx_core.cpp @@ -1,48 +1,110 @@ #include <stdio.h> -#include "latency.h" +#include "bp_sim.h" #include "flow_stat_parser.h" -#include "stateless/rx/trex_stateless_rx_core.h" - +#include "latency.h" +#include "trex_stateless_messaging.h" +#include "trex_stateless_rx_core.h" void CRxCoreStateless::create(const CRxSlCfg &cfg) { m_max_ports = cfg.m_max_ports; + CMessagingManager * cp_rx = CMsgIns::Ins()->getCpRx(); + + m_ring_from_cp = cp_rx->getRingCpToDp(0); + m_ring_to_cp = cp_rx->getRingDpToCp(0); + m_state = STATE_IDLE; + for (int i = 0; i < m_max_ports; i++) { CLatencyManagerPerPort * lp = &m_ports[i]; - // CCPortLatency * lpo = &m_ports[swap_port(i)].m_port; - lp->m_io = cfg.m_ports[i]; - /* lp->m_port.Create(this, - i, - m_pkt_gen.get_payload_offset(), - m_pkt_gen.get_l4_offset(), - m_pkt_gen.get_pkt_size(),lpo );???*/ } +} +void CRxCoreStateless::handle_cp_msg(TrexStatelessCpToRxMsgBase *msg) { + msg->handle(this); + delete msg; } -void CRxCoreStateless::start() { - static int count = 0; - static int i = 0; - while (1) { - count += try_rx(); - i++; - if (i == 100000000) { - i = 0; - //??? remove - printf("counter:%d port0:[%u], port1:[%u]\n", count, m_ports[0].m_port.m_rx_pg_pkts[0], m_ports[1].m_port.m_rx_pg_pkts[1]); +bool CRxCoreStateless::periodic_check_for_cp_messages() { + /* fast path */ + if ( likely ( m_ring_from_cp->isEmpty() ) ) { + return false; + } + + while ( true ) { + CGenNode * node = NULL; + + if (m_ring_from_cp->Dequeue(node) != 0) { + break; + } + assert(node); + TrexStatelessCpToRxMsgBase * msg = (TrexStatelessCpToRxMsgBase *)node; + handle_cp_msg(msg); + } + + return true; + +} + +void CRxCoreStateless::idle_state_loop() { + const int SHORT_DELAY_MS = 2; + const int LONG_DELAY_MS = 50; + const int DEEP_SLEEP_LIMIT = 2000; + + int counter = 0; + + while (m_state == STATE_IDLE) { + bool had_msg = periodic_check_for_cp_messages(); + if (had_msg) { + counter = 0; + continue; + } + + /* enter deep sleep only if enough time had passed */ + if (counter < DEEP_SLEEP_LIMIT) { + delay(SHORT_DELAY_MS); + counter++; + } else { + delay(LONG_DELAY_MS); } } } -// ??? temp try +void CRxCoreStateless::start() { + static int count = 0; + static int i = 0; + + while (true) { + if (m_state == STATE_WORKING) { + count += try_rx(); + i++; + if (i == 100) { + i = 0; + // if no packets in 100 cycles, sleep for a while to spare the cpu + if (count == 0) { + delay(1); + } + count = 0; + periodic_check_for_cp_messages(); + } + } else { + idle_state_loop(); + } +#if 0 + ??? do we need this? + if ( m_core->is_terminated_by_master() ) { + break; + } +#endif + } +} + int CRxCoreStateless::try_rx() { rte_mbuf_t * rx_pkts[64]; int i, total_pkts = 0; for (i = 0; i < m_max_ports; i++) { CLatencyManagerPerPort * lp = &m_ports[i]; rte_mbuf_t * m; - //m_cpu_dp_u.start_work(); /* try to read 64 packets clean up the queue */ uint16_t cnt_p = lp->m_io->rx_burst(rx_pkts, 64); total_pkts += cnt_p; @@ -63,10 +125,8 @@ int CRxCoreStateless::try_rx() { } rte_pktmbuf_free(m); } - /* commit only if there was work to do ! */ - //m_cpu_dp_u.commit(); //??? what's this? - }/* if work */ - }// all ports + }/* if work */ + }// all ports return total_pkts; } diff --git a/src/stateless/rx/trex_stateless_rx_core.h b/src/stateless/rx/trex_stateless_rx_core.h index 942ddbd6..eecc8033 100644 --- a/src/stateless/rx/trex_stateless_rx_core.h +++ b/src/stateless/rx/trex_stateless_rx_core.h @@ -23,6 +23,8 @@ limitations under the License. #include <stdint.h> #include "latency.h" +class TrexStatelessCpToRxMsgBase; + class CRxSlCfg { public: CRxSlCfg (){ @@ -37,19 +39,33 @@ class CRxSlCfg { }; class CRxCoreStateless { + enum state_e { + STATE_IDLE, + STATE_WORKING, + }; + public: void start(); void create(const CRxSlCfg &cfg); void reset_rx_stats(uint8_t port_id); int get_rx_stats(uint8_t port_id, uint32_t *pkts, uint32_t *prev_pkts , uint32_t *bytes, uint32_t *prev_bytes, int min, int max); + void work() {m_state = STATE_WORKING;} + void idle() {m_state = STATE_IDLE;} private: + void handle_cp_msg(TrexStatelessCpToRxMsgBase *msg); + bool periodic_check_for_cp_messages(); + void idle_state_loop(); int try_rx(); bool is_flow_stat_id(uint16_t id); uint16_t get_hw_id(uint16_t id); - + private: uint32_t m_max_ports; + bool m_has_streams; CLatencyManagerPerPort m_ports[TREX_MAX_PORTS]; + state_e m_state; /* state of all ports */ + CNodeRing *m_ring_from_cp; + CNodeRing *m_ring_to_cp; }; #endif |