summaryrefslogtreecommitdiffstats
path: root/src/stateless
diff options
context:
space:
mode:
authorIdo Barnea <ibarnea@cisco.com>2016-05-15 19:07:49 +0300
committerIdo Barnea <ibarnea@cisco.com>2016-05-18 19:23:46 +0300
commitc38d567b84cc9c8a5c2f88a598c89bbbb9b3279b (patch)
treea576bb2c4517b2a74478c10ed1b6db941f0e75bf /src/stateless
parentdc75957648608bf0355fca31d4502ef41ee3a3a3 (diff)
fixes according to Hanoch's code review
Diffstat (limited to 'src/stateless')
-rw-r--r--src/stateless/cp/trex_stream.h6
-rw-r--r--src/stateless/rx/trex_stateless_rx_core.cpp13
-rw-r--r--src/stateless/rx/trex_stateless_rx_core.h56
3 files changed, 67 insertions, 8 deletions
diff --git a/src/stateless/cp/trex_stream.h b/src/stateless/cp/trex_stream.h
index de45555a..b0bfba52 100644
--- a/src/stateless/cp/trex_stream.h
+++ b/src/stateless/cp/trex_stream.h
@@ -36,7 +36,7 @@ limitations under the License.
#include "trex_stream_vm.h"
#include <common/captureFile.h>
#include <common/bitMan.h>
-
+#include "internal_api/trex_platform_api.h"
class TrexRpcCmdAddStream;
@@ -376,6 +376,10 @@ public:
/* can this stream be split ? */
bool is_splitable(uint8_t dp_core_count) const {
+ if (m_rx_check.m_enabled && (m_rx_check.m_rule_type == TrexPlatformApi::IF_STAT_PAYLOAD)) {
+ // because of sequence number, can't split streams with payload rule to different cores
+ return false;
+ }
/* cont stream is always splitable */
if (m_type == stCONTINUOUS) {
return true;
diff --git a/src/stateless/rx/trex_stateless_rx_core.cpp b/src/stateless/rx/trex_stateless_rx_core.cpp
index d624f455..72b0f749 100644
--- a/src/stateless/rx/trex_stateless_rx_core.cpp
+++ b/src/stateless/rx/trex_stateless_rx_core.cpp
@@ -33,7 +33,7 @@ void CRxCoreStateless::create(const CRxSlCfg &cfg) {
// This is the seq num value we expect next packet to have.
// Init value should match m_seq_num in CVirtualIFPerSideStats
m_per_flow_seq[i] = UINT32_MAX - 1; // catch wrap around issues early
- m_per_flow_hist[i].Reset();
+ m_per_flow_hist[i].Create();
m_per_flow_jitter[i].reset();
m_per_flow_seq_error[i] = 0;
m_per_flow_out_of_order[i] = 0;
@@ -101,13 +101,9 @@ void CRxCoreStateless::start() {
while (true) {
if (m_state == STATE_WORKING) {
i++;
- if (i == 100) {
+ //??? need to calculate value for 10msec instead of 1000
+ if (i == 1000) {
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(); // m_state might change in here
}
} else {
@@ -124,6 +120,7 @@ void CRxCoreStateless::start() {
}
count += try_rx();
}
+ rte_pause();
}
void CRxCoreStateless::handle_rx_pkt(CLatencyManagerPerPortStl *lp, rte_mbuf_t *m) {
@@ -181,6 +178,7 @@ void CRxCoreStateless::handle_rx_pkt(CLatencyManagerPerPortStl *lp, rte_mbuf_t *
uint64_t d = (os_get_hr_tick_64() - fsp_head->time_stamp );
dsec_t ctime = ptime_convert_hr_dsec(d);
m_per_flow_hist[hw_id].Add(ctime);
+ m_per_flow_last_max[hw_id].update(ctime);
m_per_flow_jitter[hw_id].calc(ctime);
}
} else {
@@ -336,6 +334,7 @@ int CRxCoreStateless::get_rfc2544_info(rfc2544_info_t *rfc2544_info, int min, in
m_per_flow_hist[hw_id].update();
m_per_flow_hist[hw_id].dump_json("", json);
rfc2544_info[hw_id - min].set_latency_json(json);
+ rfc2544_info[hw_id - min].set_last_max(m_per_flow_last_max[hw_id].switchMax());
if (reset) {
m_per_flow_seq_error[hw_id] = 0;
diff --git a/src/stateless/rx/trex_stateless_rx_core.h b/src/stateless/rx/trex_stateless_rx_core.h
index 2ebd209a..604ad260 100644
--- a/src/stateless/rx/trex_stateless_rx_core.h
+++ b/src/stateless/rx/trex_stateless_rx_core.h
@@ -22,10 +22,65 @@
#define __TREX_STATELESS_RX_CORE_H__
#include <stdint.h>
#include "latency.h"
+#include "os_time.h"
+#include "pal/linux/sanb_atomic.h"
#include "utl_cpuu.h"
class TrexStatelessCpToRxMsgBase;
+class CLastMax {
+ public:
+ CLastMax() {
+ m_max1 = 0;
+ m_max1 = 1;
+ m_choose = true;
+ }
+
+ void update(dsec_t val) {
+ if (m_choose) {
+ if (val > m_max1) {
+ m_max1 = val;
+ sanb_smp_memory_barrier();
+ }
+ } else {
+ if (val > m_max2) {
+ m_max2 = val;
+ sanb_smp_memory_barrier();
+ }
+ }
+ }
+
+ dsec_t getMax() {
+ if (m_choose)
+ return m_max1;
+ else
+ return m_max2;
+ }
+
+ dsec_t switchMax() {
+ dsec_t ret;
+ if (m_choose) {
+ m_choose = false;
+ sanb_smp_memory_barrier();
+ ret = m_max1;
+ m_max1 = 0;
+ }
+ else {
+ m_choose = true;
+ sanb_smp_memory_barrier();
+ ret = m_max2;
+ m_max2 = 0;
+ }
+ return ret;
+ }
+
+ private:
+ dsec_t m_max1;
+ dsec_t m_max2;
+ bool m_choose;
+};
+
+
class CCPortLatencyStl {
public:
void reset();
@@ -107,5 +162,6 @@ class CRxCoreStateless {
uint64_t m_per_flow_seq_error[MAX_FLOW_STATS_PAYLOAD]; // How many packet seq num gaps we saw (packets lost or out of order)
uint64_t m_per_flow_out_of_order[MAX_FLOW_STATS_PAYLOAD]; // Packets we got with seq num lower than expected
uint64_t m_per_flow_dup[MAX_FLOW_STATS_PAYLOAD]; // Packets we got with same seq num
+ CLastMax m_per_flow_last_max[MAX_FLOW_STATS_PAYLOAD];
};
#endif