summaryrefslogtreecommitdiffstats
path: root/src/stateless
diff options
context:
space:
mode:
Diffstat (limited to 'src/stateless')
-rw-r--r--src/stateless/cp/trex_stateless_port.cpp7
-rw-r--r--src/stateless/cp/trex_stateless_port.h100
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.cpp16
-rw-r--r--src/stateless/messaging/trex_stateless_messaging.cpp42
-rw-r--r--src/stateless/messaging/trex_stateless_messaging.h76
-rw-r--r--src/stateless/rx/trex_stateless_rx_core.cpp112
-rw-r--r--src/stateless/rx/trex_stateless_rx_core.h18
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