summaryrefslogtreecommitdiffstats
path: root/src/stateless/cp
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2016-07-24 13:20:51 +0300
committerimarom <imarom@cisco.com>2016-07-24 13:54:50 +0300
commit47906bbc49195f2ef2ed44cd54337feb87f7dbc3 (patch)
tree447afe468656bd1443fa92bf8cb3a7452168656d /src/stateless/cp
parent6d028fcd21df1d1954f679443ffddc35364552f7 (diff)
BUG: trex-227 - random packet size with -m 100% does not give 100% line rate
https://trex-tgn.cisco.com/youtrack/issue/trex-227
Diffstat (limited to 'src/stateless/cp')
-rw-r--r--src/stateless/cp/trex_stream.cpp2
-rw-r--r--src/stateless/cp/trex_stream.h2
-rw-r--r--src/stateless/cp/trex_stream_vm.cpp65
-rw-r--r--src/stateless/cp/trex_stream_vm.h6
4 files changed, 67 insertions, 8 deletions
diff --git a/src/stateless/cp/trex_stream.cpp b/src/stateless/cp/trex_stream.cpp
index adc08ae2..7a3dfef7 100644
--- a/src/stateless/cp/trex_stream.cpp
+++ b/src/stateless/cp/trex_stream.cpp
@@ -141,7 +141,7 @@ TrexStream::TrexStream(uint8_t type,
m_pkt.binary = NULL;
m_pkt.len = 0;
- m_expected_pkt_len = 0;
+ m_expected_pkt_len = 0.0;
m_rx_check.m_enabled = false;
diff --git a/src/stateless/cp/trex_stream.h b/src/stateless/cp/trex_stream.h
index 8ac5ebc8..0f59356d 100644
--- a/src/stateless/cp/trex_stream.h
+++ b/src/stateless/cp/trex_stream.h
@@ -558,7 +558,7 @@ public:
StreamVmDp *m_vm_dp;
CStreamPktData m_pkt;
- uint16_t m_expected_pkt_len;
+ double m_expected_pkt_len;
/* pkt */
diff --git a/src/stateless/cp/trex_stream_vm.cpp b/src/stateless/cp/trex_stream_vm.cpp
index 7a1dc122..f04c9f3a 100644
--- a/src/stateless/cp/trex_stream_vm.cpp
+++ b/src/stateless/cp/trex_stream_vm.cpp
@@ -27,7 +27,64 @@ limitations under the License.
#include <common/Network/Packet/IPHeader.h>
#include <common/basic_utils.h>
+/**
+ * provides some tools for the fast rand function
+ * that is used by the datapath
+ * some features of this function is different
+ * from a regular random
+ * (such as average can be off by few percents)
+ *
+ * @author imarom (7/24/2016)
+ */
+class FastRandUtils {
+public:
+
+ /**
+ * searches the target in the cache
+ * if not found iterativly calculate it
+ * and add it to the cache
+ *
+ */
+ double calc_fastrand_avg(uint16_t target) {
+ auto search = m_avg_cache.find(target);
+ if (search != m_avg_cache.end()) {
+ return search->second;
+ }
+
+ /* not found - calculate it */
+ double avg = iterate_calc(target);
+
+ /* if there is enough space - to the cache */
+ if (m_avg_cache.size() <= G_MAX_CACHE_SIZE) {
+ m_avg_cache[target] = avg;
+ }
+
+ return avg;
+ }
+
+private:
+ /**
+ * hard calculate a value using iterations
+ *
+ */
+ double iterate_calc(uint16_t target) {
+ const int num_samples = 10000;
+ uint64_t tmp = 0;
+ uint32_t seed = 1;
+
+ for (int i = 0; i < num_samples; i++) {
+ tmp += fastrand(seed) % (target + 1);
+ }
+
+ return (tmp / double(num_samples));
+ }
+
+ std::unordered_map<uint16_t, double> m_avg_cache;
+ static const uint16_t G_MAX_CACHE_SIZE = 9230;
+};
+
+static FastRandUtils g_fastrand_util;
void StreamVmInstructionFixChecksumIpv4::Dump(FILE *fd){
@@ -350,9 +407,11 @@ void StreamVm::build_flow_var_table() {
var.m_ins.m_ins_flowv->m_min_value =60;
}
- m_expected_pkt_size = (var.m_ins.m_ins_flowv->m_min_value + var.m_ins.m_ins_flowv->m_max_value) / 2;
+ /* expected packet size calculation */
+ uint16_t range = var.m_ins.m_ins_flowv->m_max_value - var.m_ins.m_ins_flowv->m_min_value;
+ m_expected_pkt_size = var.m_ins.m_ins_flowv->m_min_value + g_fastrand_util.calc_fastrand_avg(range);
}
- }/* for */
+ }
}
@@ -962,7 +1021,7 @@ StreamVm::~StreamVm() {
* calculate expected packet size of stream's VM
*
*/
-uint16_t
+double
StreamVm::calc_expected_pkt_size(uint16_t regular_pkt_size) const {
/* if no packet size change - simply return the regular packet size */
diff --git a/src/stateless/cp/trex_stream_vm.h b/src/stateless/cp/trex_stream_vm.h
index 58d43bd4..f55d33c1 100644
--- a/src/stateless/cp/trex_stream_vm.h
+++ b/src/stateless/cp/trex_stream_vm.h
@@ -1417,7 +1417,7 @@ public:
m_prefix_size=0;
m_bss=0;
m_pkt_size=0;
- m_expected_pkt_size=0;
+ m_expected_pkt_size=0.0;
m_cur_var_offset=0;
m_is_random_var=false;
@@ -1435,7 +1435,7 @@ public:
* if the VM changes the packet length (random)
*
*/
- uint16_t calc_expected_pkt_size(uint16_t regular_pkt_size) const;
+ double calc_expected_pkt_size(uint16_t regular_pkt_size) const;
@@ -1576,7 +1576,7 @@ private:
uint16_t m_prefix_size;
uint16_t m_pkt_size;
- uint16_t m_expected_pkt_size;
+ double m_expected_pkt_size;
uint16_t m_cur_var_offset;
uint16_t m_max_field_update; /* the location of the last byte that is going to be changed in the packet */