summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/bp_sim.h39
-rw-r--r--src/main_dpdk.cpp92
-rw-r--r--src/main_dpdk.h15
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_general.cpp13
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_stream.cpp13
-rw-r--r--src/rpc-server/commands/trex_rpc_cmds.h2
-rw-r--r--src/sim/trex_sim.h3
-rw-r--r--src/sim/trex_sim_stateless.cpp45
-rw-r--r--src/stateless/cp/trex_stateless_port.cpp16
-rw-r--r--src/stateless/cp/trex_stateless_port.h7
-rw-r--r--src/stateless/cp/trex_streams_compiler.cpp50
-rw-r--r--src/stateless/cp/trex_streams_compiler.h62
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.h11
-rw-r--r--src/trex_defs.h13
-rwxr-xr-xsrc/utl_cpuu.cpp6
-rwxr-xr-xsrc/utl_cpuu.h2
16 files changed, 317 insertions, 72 deletions
diff --git a/src/bp_sim.h b/src/bp_sim.h
index bfdd90f6..e1852da4 100755
--- a/src/bp_sim.h
+++ b/src/bp_sim.h
@@ -3835,6 +3835,45 @@ public:
m_stateless_dp_info.stop_traffic(port_id, false, 0);
}
+ /**
+ * return true if a core currently has some pending CP
+ * messages
+ */
+ bool are_any_pending_cp_messages() {
+ if (get_is_stateless()) {
+ return m_stateless_dp_info.are_any_pending_cp_messages();
+ } else {
+ /* for stateful this is always false */
+ return false;
+ }
+ }
+
+ /**
+ * a core provides services for two interfaces
+ * it can either be idle, active for one port
+ * or active for both
+ */
+ bool is_port_active(uint8_t port_id) {
+ /* for stateful (batch) core is always active,
+ for stateless relay the query to the next level
+ */
+ if (get_is_stateless()) {
+ return m_stateless_dp_info.is_port_active(port_id);
+ } else {
+ return true;
+ }
+ }
+
+
+ /**
+ * returns the two ports associated with this core
+ *
+ */
+ void get_port_ids(uint8_t &p1, uint8_t &p2) {
+ p1 = 2 * getDualPortId();
+ p2 = p1 + 1;
+ }
+
void Dump(FILE *fd);
void DumpCsv(FILE *fd);
void DumpStats(FILE *fd);
diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp
index caec511b..349db11e 100644
--- a/src/main_dpdk.cpp
+++ b/src/main_dpdk.cpp
@@ -1316,6 +1316,8 @@ int CPhyEthIF::get_rx_stat_capabilities() {
return get_ex_drv()->get_rx_stat_capabilities();
}
+
+
void CPhyEthIF::configure(uint16_t nb_rx_queue,
uint16_t nb_tx_queue,
const struct rte_eth_conf *eth_conf){
@@ -2436,6 +2438,8 @@ public:
float m_total_rx_bps;
float m_total_rx_pps;
+
+ float m_cpu_util;
};
class CGlobalStats {
@@ -2601,6 +2605,7 @@ void CGlobalStats::dump_json(std::string & json, bool baseline){
json+=GET_FIELD_PORT(i,m_total_tx_pps);
json+=GET_FIELD_PORT(i,m_total_rx_bps);
json+=GET_FIELD_PORT(i,m_total_rx_pps);
+ json+=GET_FIELD_PORT(i,m_cpu_util);
}
json+=m_template.dump_as_json("template");
json+="\"unknown\":0}}" ;
@@ -2906,6 +2911,7 @@ public:
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, bool is_lat);
void get_stats(CGlobalStats & stats);
+ float get_cpu_util_per_interface(uint8_t port_id);
void dump_post_test_stats(FILE *fd);
void dump_config(FILE *fd);
void dump_links_status(FILE *fd);
@@ -3744,6 +3750,9 @@ void CGlobalTRex::get_stats(CGlobalStats & stats){
for (uint16_t flow = MAX_FLOW_STATS; flow <= MAX_FLOW_STATS + max_stat_hw_id_seen_payload; flow++) {
stats.m_port[i].m_tx_per_flow[flow].clear();
}
+
+ stp->m_cpu_util = get_cpu_util_per_interface(i);
+
}
uint64_t total_open_flows=0;
@@ -3858,6 +3867,25 @@ void CGlobalTRex::get_stats(CGlobalStats & stats){
stats.m_tx_expected_bps = m_expected_bps*pf;
}
+float
+CGlobalTRex::get_cpu_util_per_interface(uint8_t port_id) {
+ CPhyEthIF * _if = &m_ports[port_id];
+
+ float tmp = 0;
+ uint8_t cnt = 0;
+ for (const auto &p : _if->get_core_list()) {
+ uint8_t core_id = p.first;
+ CFlowGenListPerThread *lp = m_fl.m_threads_info[core_id];
+ if (lp->is_port_active(port_id)) {
+ tmp += lp->m_cpu_cp_u.GetVal();
+ cnt++;
+ }
+ }
+
+ return ( (cnt > 0) ? (tmp / cnt) : 0);
+
+}
+
bool CGlobalTRex::sanity_check(){
CFlowGenListPerThread * lpt;
@@ -4442,6 +4470,36 @@ int CGlobalTRex::start_master_statefull() {
////////////////////////////////////////////
static CGlobalTRex g_trex;
+bool CPhyEthIF::Create(uint8_t portid) {
+ m_port_id = portid;
+ m_last_rx_rate = 0.0;
+ m_last_tx_rate = 0.0;
+ m_last_tx_pps = 0.0;
+
+ return true;
+}
+
+const std::vector<std::pair<uint8_t, uint8_t>> &
+CPhyEthIF::get_core_list() {
+
+ /* lazy find */
+ if (m_core_id_list.size() == 0) {
+
+ for (uint8_t core_id = 0; core_id < g_trex.get_cores_tx(); core_id++) {
+
+ /* iterate over all the directions*/
+ for (uint8_t dir = 0 ; dir < CS_NUM; dir++) {
+ if (g_trex.m_cores_vif[core_id + 1]->get_ports()[dir].m_port->get_port_id() == m_port_id) {
+ m_core_id_list.push_back(std::make_pair(core_id, dir));
+ }
+ }
+ }
+ }
+
+ return m_core_id_list;
+
+}
+
int CPhyEthIF::reset_hw_flow_stats() {
if (get_ex_drv()->hw_rx_stat_supported()) {
get_ex_drv()->reset_rx_stats(this, m_stats.m_fdir_prev_pkts, 0, MAX_FLOW_STATS);
@@ -6015,25 +6073,17 @@ TrexDpdkPlatformApi::get_interface_stats(uint8_t interface_id, TrexPlatformInter
uint8_t
TrexDpdkPlatformApi::get_dp_core_count() const {
- return CGlobalInfo::m_options.preview.getCores();
+ return CGlobalInfo::m_options.get_number_of_dp_cores_needed();
}
void
TrexDpdkPlatformApi::port_id_to_cores(uint8_t port_id, std::vector<std::pair<uint8_t, uint8_t>> &cores_id_list) const {
- cores_id_list.clear();
-
- /* iterate over all DP cores */
- for (uint8_t core_id = 0; core_id < g_trex.get_cores_tx(); core_id++) {
+ CPhyEthIF *lpt = &g_trex.m_ports[port_id];
- /* iterate over all the directions*/
- for (uint8_t dir = 0 ; dir < CS_NUM; dir++) {
- if (g_trex.m_cores_vif[core_id + 1]->get_ports()[dir].m_port->get_port_id() == port_id) {
- cores_id_list.push_back(std::make_pair(core_id, dir));
- }
- }
- }
+ /* copy data from the interface */
+ cores_id_list = lpt->get_core_list();
}
void
@@ -6133,10 +6183,23 @@ 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 {
+ uint8_t p1;
+ uint8_t p2;
+
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];
- lp->m_cpu_cp_u.GetHistory(cpu_util_full[thread_id]);
+
+ /* history */
+ CFlowGenListPerThread *lp = g_trex.m_fl.m_threads_info[thread_id];
+ cpu_vct_st &per_cpu = cpu_util_full[thread_id];
+ lp->m_cpu_cp_u.GetHistory(per_cpu);
+
+
+ /* active ports */
+ lp->get_port_ids(p1, p2);
+ per_cpu.m_port1 = (lp->is_port_active(p1) ? p1 : -1);
+ per_cpu.m_port2 = (lp->is_port_active(p2) ? p2 : -1);
+
}
return 0;
}
@@ -6158,3 +6221,4 @@ CFlowStatParser *TrexDpdkPlatformApi::get_flow_stat_parser() const {
void TrexDpdkPlatformApi::mark_for_shutdown() const {
g_trex.mark_for_shutdown(CGlobalTRex::SHUTDOWN_RPC_REQ);
}
+
diff --git a/src/main_dpdk.h b/src/main_dpdk.h
index f8c35732..91618071 100644
--- a/src/main_dpdk.h
+++ b/src/main_dpdk.h
@@ -55,13 +55,7 @@ class CPhyEthIF {
m_port_id=0;
m_rx_queue=0;
}
- bool Create(uint8_t portid){
- m_port_id = portid;
- m_last_rx_rate = 0.0;
- m_last_tx_rate = 0.0;
- m_last_tx_pps = 0.0;
- return (true);
- }
+ bool Create(uint8_t portid);
void Delete();
void set_rx_queue(uint8_t rx_queue){
@@ -156,6 +150,9 @@ class CPhyEthIF {
return m_port_id;
}
int get_rx_stat_capabilities();
+
+ const std::vector<std::pair<uint8_t, uint8_t>> & get_core_list();
+
private:
uint8_t m_port_id;
uint8_t m_rx_queue;
@@ -171,6 +168,10 @@ class CPhyEthIF {
float m_last_rx_rate;
float m_last_tx_pps;
float m_last_rx_pps;
+
+ /* holds the core ID list for this port - (core, dir) list*/
+ std::vector<std::pair<uint8_t, uint8_t>> m_core_id_list;
+
public:
struct rte_eth_dev_info m_dev_info;
};
diff --git a/src/rpc-server/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/commands/trex_rpc_cmd_general.cpp
index 080856c2..21f64e2e 100644
--- a/src/rpc-server/commands/trex_rpc_cmd_general.cpp
+++ b/src/rpc-server/commands/trex_rpc_cmd_general.cpp
@@ -199,10 +199,18 @@ TrexRpcCmdGetUtilization::_run(const Json::Value &params, Json::Value &result) {
}
for (int thread_id = 0; thread_id < cpu_util_full.size(); thread_id++) {
- for (int history_id = 0; history_id < cpu_util_full[thread_id].size(); history_id++) {
- section["cpu"][thread_id].append(cpu_util_full[thread_id][history_id]);
+
+ /* history */
+ for (int history_id = 0; history_id < cpu_util_full[thread_id].m_history.size(); history_id++) {
+ section["cpu"][thread_id]["history"].append(cpu_util_full[thread_id].m_history[history_id]);
}
+
+ /* ports */
+ section["cpu"][thread_id]["ports"] = Json::arrayValue;
+ section["cpu"][thread_id]["ports"].append(cpu_util_full[thread_id].m_port1);
+ section["cpu"][thread_id]["ports"].append(cpu_util_full[thread_id].m_port2);
}
+
return (TREX_RPC_CMD_OK);
}
@@ -270,6 +278,7 @@ TrexRpcCmdGetSysInfo::_run(const Json::Value &params, Json::Value &result) {
/* FIXME: core count */
section["dp_core_count"] = main->get_dp_core_count();
+ section["dp_core_count_per_port"] = main->get_dp_core_count() / (main->get_port_count() / 2);
section["core_type"] = get_cpu_model();
/* ports */
diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
index 736f3d02..7e973e60 100644
--- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
+++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
@@ -542,8 +542,13 @@ TrexRpcCmdStartTraffic::_run(const Json::Value &params, Json::Value &result) {
uint8_t port_id = parse_port(params, result);
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
- double duration = parse_double(params, "duration", result);
- bool force = parse_bool(params, "force", result);
+ double duration = parse_double(params, "duration", result);
+ bool force = parse_bool(params, "force", result);
+ uint64_t core_mask = parse_uint64(params, "core_mask", result);
+
+ if (!TrexDPCoreMask::is_valid_mask(port->get_dp_core_count(), core_mask)) {
+ generate_parse_err(result, "invalid core mask provided");
+ }
/* multiplier */
const Json::Value &mul_obj = parse_object(params, "mul", result);
@@ -551,7 +556,7 @@ TrexRpcCmdStartTraffic::_run(const Json::Value &params, Json::Value &result) {
std::string type = parse_choice(mul_obj, "type", TrexPortMultiplier::g_types, result);
std::string op = parse_string(mul_obj, "op", result);
double value = parse_double(mul_obj, "value", result);
-
+
if ( value <=0 ){
generate_parse_err(result, "multiplier can't be zero");
}
@@ -563,7 +568,7 @@ TrexRpcCmdStartTraffic::_run(const Json::Value &params, Json::Value &result) {
TrexPortMultiplier mul(type, op, value);
try {
- port->start_traffic(mul, duration, force);
+ port->start_traffic(mul, duration, force, core_mask);
} catch (const TrexException &ex) {
generate_execute_err(result, ex.what());
diff --git a/src/rpc-server/commands/trex_rpc_cmds.h b/src/rpc-server/commands/trex_rpc_cmds.h
index 24b95227..9dde61d4 100644
--- a/src/rpc-server/commands/trex_rpc_cmds.h
+++ b/src/rpc-server/commands/trex_rpc_cmds.h
@@ -121,7 +121,7 @@ TREX_RPC_CMD_DEFINE(TrexRpcCmdGetStream, "get_stream", 3, false, APIClass::API_C
-TREX_RPC_CMD_DEFINE(TrexRpcCmdStartTraffic, "start_traffic", 4, true, APIClass::API_CLASS_TYPE_CORE);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdStartTraffic, "start_traffic", 5, true, APIClass::API_CLASS_TYPE_CORE);
TREX_RPC_CMD_DEFINE(TrexRpcCmdStopTraffic, "stop_traffic", 1, true, APIClass::API_CLASS_TYPE_CORE);
TREX_RPC_CMD_DEFINE(TrexRpcCmdRemoveRXFilters, "remove_rx_filters", 1, true, APIClass::API_CLASS_TYPE_CORE);
TREX_RPC_CMD_DEFINE(TrexRpcCmdPauseTraffic, "pause_traffic", 1, true, APIClass::API_CLASS_TYPE_CORE);
diff --git a/src/sim/trex_sim.h b/src/sim/trex_sim.h
index 0c343261..f52ad9b4 100644
--- a/src/sim/trex_sim.h
+++ b/src/sim/trex_sim.h
@@ -143,6 +143,7 @@ private:
void prepare_control_plane();
void prepare_dataplane();
void execute_json(const std::string &json_filename);
+ void find_active_dp_cores();
void run_dp(const std::string &out_filename);
@@ -179,6 +180,8 @@ private:
int m_dp_core_index;
uint64_t m_limit;
bool m_is_dry_run;
+
+ std::vector<uint8_t> m_active_dp_cores;
};
#endif /* __TREX_SIM_H__ */
diff --git a/src/sim/trex_sim_stateless.cpp b/src/sim/trex_sim_stateless.cpp
index 77bd4d70..20041c2b 100644
--- a/src/sim/trex_sim_stateless.cpp
+++ b/src/sim/trex_sim_stateless.cpp
@@ -123,14 +123,14 @@ public:
************************/
SimStateless::SimStateless() {
- m_publisher = NULL;
- m_dp_to_cp_handler = NULL;
- m_verbose = false;
- m_dp_core_count = -1;
- m_dp_core_index = -1;
- m_port_count = -1;
- m_limit = 0;
- m_is_dry_run = false;
+ m_publisher = NULL;
+ m_dp_to_cp_handler = NULL;
+ m_verbose = false;
+ m_dp_core_count = -1;
+ m_dp_core_index = -1;
+ m_port_count = -1;
+ m_limit = 0;
+ m_is_dry_run = false;
/* override ownership checks */
TrexRpcCommand::test_set_override_ownership(true);
@@ -138,6 +138,23 @@ SimStateless::SimStateless() {
}
+/**
+ * on the simulation we first construct CP and then DP
+ * the only way to "assume" which DP will be active during
+ * the run is by checking for pending CP messages on the cores
+ *
+ * @author imarom (8/10/2016)
+ */
+void
+SimStateless::find_active_dp_cores() {
+ for (int core_index = 0; core_index < m_dp_core_count; core_index++) {
+ CFlowGenListPerThread *lpt = m_fl.m_threads_info[core_index];
+ if (lpt->are_any_pending_cp_messages()) {
+ m_active_dp_cores.push_back(core_index);
+ }
+ }
+}
+
int
SimStateless::run(const string &json_filename,
const string &out_filename,
@@ -168,6 +185,8 @@ SimStateless::run(const string &json_filename,
return (-1);
}
+ find_active_dp_cores();
+
run_dp(out_filename);
return 0;
@@ -353,14 +372,14 @@ SimStateless::run_dp(const std::string &out_filename) {
show_intro(out_filename);
if (is_multiple_capture()) {
- for (int i = 0; i < m_dp_core_count; i++) {
+ for (int i : m_active_dp_cores) {
std::stringstream ss;
ss << out_filename << "-" << i;
run_dp_core(i, ss.str(), core_stats, total);
}
} else {
- for (int i = 0; i < m_dp_core_count; i++) {
+ for (int i : m_active_dp_cores) {
run_dp_core(i, out_filename, core_stats, total);
}
}
@@ -414,9 +433,9 @@ SimStateless::get_limit_per_core(int core_index) {
if (m_limit == 0) {
return (0);
} else {
- uint64_t l = std::max((uint64_t)1, m_limit / m_dp_core_count);
- if (core_index == 0) {
- l += (m_limit % m_dp_core_count);
+ uint64_t l = std::max((uint64_t)1, m_limit / m_active_dp_cores.size());
+ if (core_index == m_active_dp_cores[0]) {
+ l += (m_limit % m_active_dp_cores.size());
}
return l;
}
diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp
index 376453b9..134d4c98 100644
--- a/src/stateless/cp/trex_stateless_port.cpp
+++ b/src/stateless/cp/trex_stateless_port.cpp
@@ -241,7 +241,7 @@ TrexStatelessPort::release(void) {
*
*/
void
-TrexStatelessPort::start_traffic(const TrexPortMultiplier &mul, double duration, bool force) {
+TrexStatelessPort::start_traffic(const TrexPortMultiplier &mul, double duration, bool force, uint64_t core_mask) {
/* command allowed only on state stream */
verify_state(PORT_STATE_STREAMS);
@@ -262,10 +262,12 @@ TrexStatelessPort::start_traffic(const TrexPortMultiplier &mul, double duration,
std::string fail_msg;
TrexStreamsCompiler compiler;
+ TrexDPCoreMask mask(get_dp_core_count(), core_mask);
+
bool rc = compiler.compile(m_port_id,
feeder.get_streams(),
compiled_objs,
- get_dp_core_count(),
+ mask,
factor,
&fail_msg);
@@ -282,7 +284,7 @@ TrexStatelessPort::start_traffic(const TrexPortMultiplier &mul, double duration,
/* update object status */
m_factor = factor;
- m_last_all_streams_continues = compiled_objs[0]->get_all_streams_continues();
+ m_last_all_streams_continues = compiled_objs[mask.get_active_cores()[0]]->get_all_streams_continues();
m_last_duration = duration;
change_state(PORT_STATE_TX);
@@ -484,7 +486,7 @@ TrexStatelessPort::update_traffic(const TrexPortMultiplier &mul, bool force) {
}
TrexStatelessCpToDpMsgBase *update_msg = new TrexStatelessDpUpdate(m_port_id, factor);
- send_message_to_all_dp(update_msg);
+ send_message_to_all_dp(update_msg, true);
m_factor *= factor;
@@ -820,13 +822,17 @@ TrexStatelessPort::validate(void) {
}
TrexStreamsCompiler compiler;
+
+ /* TODO: think of this mask...*/
+ TrexDPCoreMask core_mask(get_dp_core_count(), TrexDPCoreMask::MASK_ALL);
+
std::vector<TrexStreamsCompiledObj *> compiled_objs;
std::string fail_msg;
bool rc = compiler.compile(m_port_id,
streams,
compiled_objs,
- get_dp_core_count(),
+ core_mask,
1.0,
&fail_msg);
if (!rc) {
diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h
index b1f6ddfe..7d976e46 100644
--- a/src/stateless/cp/trex_stateless_port.h
+++ b/src/stateless/cp/trex_stateless_port.h
@@ -178,7 +178,7 @@ public:
* start traffic
* throws TrexException in case of an error
*/
- void start_traffic(const TrexPortMultiplier &mul, double duration, bool force = false);
+ void start_traffic(const TrexPortMultiplier &mul, double duration, bool force = false, uint64_t core_mask = UINT64_MAX);
/**
* stop traffic
@@ -376,11 +376,12 @@ public:
void get_pci_info(std::string &pci_addr, int &numa_node);
+
private:
bool is_core_active(int core_id);
- const std::vector<int> get_core_id_list () {
+ const std::vector<uint8_t> get_core_id_list () {
return m_cores_id_list;
}
@@ -446,7 +447,7 @@ private:
uint16_t m_rx_caps;
/* holds the DP cores associated with this port */
- std::vector<int> m_cores_id_list;
+ std::vector<uint8_t> m_cores_id_list;
bool m_last_all_streams_continues;
double m_last_duration;
diff --git a/src/stateless/cp/trex_streams_compiler.cpp b/src/stateless/cp/trex_streams_compiler.cpp
index e54c5f9c..97f7a250 100644
--- a/src/stateless/cp/trex_streams_compiler.cpp
+++ b/src/stateless/cp/trex_streams_compiler.cpp
@@ -375,19 +375,29 @@ bool
TrexStreamsCompiler::compile(uint8_t port_id,
const std::vector<TrexStream *> &streams,
std::vector<TrexStreamsCompiledObj *> &objs,
- uint8_t dp_core_count,
+ TrexDPCoreMask &core_mask,
double factor,
std::string *fail_msg) {
- assert(dp_core_count > 0);
+ assert(core_mask.get_active_count() > 0);
+
+ uint8_t indirect_core_count = core_mask.get_active_count();
+ std::vector<TrexStreamsCompiledObj *> indirect_objs(indirect_core_count);
+
+ for (int i = 0; i < indirect_core_count; i++) {
+ indirect_objs[i] = NULL;
+ }
try {
- return compile_internal(port_id,
- streams,
- objs,
- dp_core_count,
- factor,
- fail_msg);
+ bool rc = compile_internal(port_id,
+ streams,
+ indirect_objs,
+ indirect_core_count,
+ factor,
+ fail_msg);
+ if (!rc) {
+ return rc;
+ }
} catch (const TrexException &ex) {
if (fail_msg) {
@@ -398,6 +408,21 @@ TrexStreamsCompiler::compile(uint8_t port_id,
return false;
}
+ /* prepare the result */
+ objs.resize(core_mask.get_total_count());
+ for (int i = 0; i < core_mask.get_total_count(); i++) {
+ objs.push_back(NULL);
+ }
+
+ uint8_t index = 0;
+ for (uint8_t active_core_id : core_mask.get_active_cores()) {
+ if (indirect_objs[index] == NULL) {
+ break;
+ }
+ objs[active_core_id] = indirect_objs[index++];
+ }
+
+ return true;
}
bool
@@ -471,12 +496,7 @@ TrexStreamsCompiler::compile_on_single_core(uint8_t
/* allocate object only for core 0 */
TrexStreamsCompiledObj *obj = new TrexStreamsCompiledObj(port_id);
obj->m_all_continues = all_continues;
- objs.push_back(obj);
-
- /* put NULL for the rest */
- for (uint8_t i = 1; i < dp_core_count; i++) {
- objs.push_back(NULL);
- }
+ objs[0] = obj;
/* compile all the streams */
for (auto const stream : streams) {
@@ -508,7 +528,7 @@ TrexStreamsCompiler::compile_on_all_cores(uint8_t
for (uint8_t i = 0; i < dp_core_count; i++) {
TrexStreamsCompiledObj *obj = new TrexStreamsCompiledObj(port_id);
obj->m_all_continues = all_continues;
- objs.push_back(obj);
+ objs[i] = obj;
}
/* compile all the streams */
diff --git a/src/stateless/cp/trex_streams_compiler.h b/src/stateless/cp/trex_streams_compiler.h
index 171e3aff..b95bf176 100644
--- a/src/stateless/cp/trex_streams_compiler.h
+++ b/src/stateless/cp/trex_streams_compiler.h
@@ -32,6 +32,66 @@ class TrexStreamsCompiler;
class TrexStream;
class GraphNodeMap;
+class TrexDPCoreMask {
+
+public:
+
+ TrexDPCoreMask(uint8_t dp_core_count, uint64_t dp_core_mask) {
+ assert(is_valid_mask(dp_core_count, dp_core_mask));
+
+ m_dp_core_count = dp_core_count;
+ m_dp_core_mask = dp_core_mask;
+
+ for (int i = 0; i < m_dp_core_count; i++) {
+ if (is_core_active(i)) {
+ m_active_cores.push_back(i);
+ }
+ }
+ }
+
+
+ uint8_t get_total_count() const {
+ return m_dp_core_count;
+ }
+
+ bool is_core_active(uint8_t core_id) const {
+ assert(core_id < m_dp_core_count);
+ return ( (1 << core_id) & m_dp_core_mask );
+ }
+
+ bool is_core_disabled(uint8_t core_id) const {
+ return (!is_core_active(core_id));
+ }
+
+ uint8_t get_active_count() const {
+ return m_active_cores.size();
+ }
+
+ const std::vector<uint8_t> & get_active_cores() const {
+ return m_active_cores;
+ }
+
+ static bool is_valid_mask(uint8_t dp_core_count, uint64_t dp_core_mask) {
+ if ( (dp_core_count < 1) || (dp_core_count > 64) ) {
+ return false;
+ }
+ /* highest bit pushed to left and then -1 will give all the other bits on */
+ return ( (dp_core_mask & ( (1 << dp_core_count) - 1 ) ) != 0);
+ }
+private:
+
+
+ uint8_t m_dp_core_count;
+ uint64_t m_dp_core_mask;
+
+ std::vector<uint8_t> m_active_cores;
+
+public:
+ static const uint64_t MASK_ALL = UINT64_MAX;
+
+};
+
+
/**
* compiled object for a table of streams
*
@@ -92,7 +152,7 @@ public:
bool compile(uint8_t port_id,
const std::vector<TrexStream *> &streams,
std::vector<TrexStreamsCompiledObj *> &objs,
- uint8_t dp_core_count = 1,
+ TrexDPCoreMask &core_mask,
double factor = 1.0,
std::string *fail_msg = NULL);
diff --git a/src/stateless/dp/trex_stateless_dp_core.h b/src/stateless/dp/trex_stateless_dp_core.h
index 31cb0be3..9babb172 100644
--- a/src/stateless/dp/trex_stateless_dp_core.h
+++ b/src/stateless/dp/trex_stateless_dp_core.h
@@ -83,10 +83,14 @@ public:
bool update_number_of_active_streams(uint32_t d);
- state_e get_state() {
+ state_e get_state() const {
return m_state;
}
+ bool is_active() const {
+ return (get_state() != ppSTATE_IDLE);
+ }
+
void set_event_id(int event_id) {
m_event_id = event_id;
}
@@ -261,6 +265,11 @@ public:
/* simply sends a message back (acts as a barrier for previous messages) */
void barrier(uint8_t port_id, int event_id);
+ bool is_port_active(uint8_t port_id) {
+ return get_port_db(port_id)->is_active();
+ }
+
+
private:
void schedule_exit();
diff --git a/src/trex_defs.h b/src/trex_defs.h
index 9abb38f5..c659c337 100644
--- a/src/trex_defs.h
+++ b/src/trex_defs.h
@@ -39,9 +39,18 @@ limitations under the License.
#define UINT64_MAX 0xFFFFFFFFFFFFFFFF
#endif
+struct cpu_vct_st {
+ cpu_vct_st() {
+ m_port1 = -1;
+ m_port2 = -1;
+ }
+ std::vector<uint8_t> m_history;
+ int m_port1;
+ int m_port2;
+};
+
typedef std::set<uint32_t> flow_stat_active_t;
typedef std::set<uint32_t>::iterator flow_stat_active_it_t;
-typedef std::vector<std::vector<uint8_t>> cpu_util_full_t;
-typedef std::vector<uint8_t> cpu_vct_t;
+typedef std::vector<cpu_vct_st> cpu_util_full_t;
#endif
diff --git a/src/utl_cpuu.cpp b/src/utl_cpuu.cpp
index 7786356e..47c78c8e 100755
--- a/src/utl_cpuu.cpp
+++ b/src/utl_cpuu.cpp
@@ -62,10 +62,10 @@ uint8_t CCpuUtlCp::GetValRaw(){
}
/* get cpu % utilization history */
-void CCpuUtlCp::GetHistory(cpu_vct_t &cpu_vct){
- cpu_vct.clear();
+void CCpuUtlCp::GetHistory(cpu_vct_st &cpu_vct){
+ cpu_vct.m_history.clear();
for (int i = m_history_latest_index + m_history_size; i > m_history_latest_index; i--) {
- cpu_vct.push_back(m_cpu_util[i % m_history_size]);
+ cpu_vct.m_history.push_back(m_cpu_util[i % m_history_size]);
}
}
diff --git a/src/utl_cpuu.h b/src/utl_cpuu.h
index 109fff4f..b0a76fce 100755
--- a/src/utl_cpuu.h
+++ b/src/utl_cpuu.h
@@ -59,7 +59,7 @@ public:
/* return cpu % */
double GetVal();
uint8_t GetValRaw();
- void GetHistory(cpu_vct_t &cpu_vct);
+ void GetHistory(cpu_vct_st &cpu_vct);
private:
void AppendHistory(uint8_t);
CCpuUtlDp * m_dpcpu;