summaryrefslogtreecommitdiffstats
path: root/src/stateless
diff options
context:
space:
mode:
authorHanoh Haim <hhaim@cisco.com>2015-12-15 14:45:55 +0200
committerHanoh Haim <hhaim@cisco.com>2015-12-15 14:45:55 +0200
commite7ffce7b0317f9861264b17d003b22915177de33 (patch)
treeccf0b538a8bfbabb476f4f6e9b02139eb17dc11b /src/stateless
parente263b80e39391a7552d9b9f56940e4fe4a9c3fbc (diff)
first test works
Diffstat (limited to 'src/stateless')
-rw-r--r--src/stateless/cp/trex_stream.cpp21
-rw-r--r--src/stateless/cp/trex_stream.h72
-rw-r--r--src/stateless/cp/trex_stream_vm.h7
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.cpp36
-rw-r--r--src/stateless/dp/trex_stream_node.h11
5 files changed, 137 insertions, 10 deletions
diff --git a/src/stateless/cp/trex_stream.cpp b/src/stateless/cp/trex_stream.cpp
index 8ea0c011..ef718529 100644
--- a/src/stateless/cp/trex_stream.cpp
+++ b/src/stateless/cp/trex_stream.cpp
@@ -53,6 +53,22 @@ std::string TrexStream::get_stream_type_str(stream_type_t stream_type){
}
+void TrexStream::post_vm_compile(){
+ /* if VM is enabled */
+ if (is_vm()) {
+ m_vm_dp = m_vm.cloneAsVmDp();
+
+
+ /* calc m_vm_prefix_size which is the size of the writable packet */
+ uint16_t max_pkt_offset = m_vm_dp->get_max_packet_update_offset();
+ uint16_t pkt_size = m_pkt.len;
+
+ /* calculate the mbuf size that we should allocate */
+ m_vm_prefix_size =calc_writable_mbuf_size(max_pkt_offset,pkt_size);
+ }
+}
+
+
void TrexStream::Dump(FILE *fd){
fprintf(fd,"\n");
@@ -113,12 +129,17 @@ TrexStream::TrexStream(uint8_t type,
m_burst_total_pkts=0;
m_num_bursts=1;
m_ibg_usec=0.0;
+ m_vm_dp = NULL;
}
TrexStream::~TrexStream() {
if (m_pkt.binary) {
delete [] m_pkt.binary;
}
+ if ( m_vm_dp ){
+ delete m_vm_dp;
+ m_vm_dp=NULL;
+ }
}
void
diff --git a/src/stateless/cp/trex_stream.h b/src/stateless/cp/trex_stream.h
index 529dcbe4..53b658fc 100644
--- a/src/stateless/cp/trex_stream.h
+++ b/src/stateless/cp/trex_stream.h
@@ -36,6 +36,54 @@ limitations under the License.
class TrexRpcCmdAddStream;
+static inline uint16_t get_log2_size(uint16_t size){
+
+ uint16_t _sizes[]={64,128,256,512,1024,2048};
+ int i;
+ for (i=0; i<sizeof(_sizes)/sizeof(_sizes[0]); i++) {
+ if (size<=_sizes[i]) {
+ return (_sizes[i]);
+ }
+ }
+ assert(0);
+ return (0);
+}
+
+/**
+ * calculate the size of writable mbuf in bytes. maximum size if packet size
+ *
+ * @param max_offset_writable
+ * the last byte that we don't write too. for example when 63 it means that bytes [62] in the array is written (zero base)
+ * @param pkt_size packet size in bytes
+ *
+ * @return the writable size of the first mbuf . the idea is to give at least 64 bytes const mbuf else all packet will be writeable
+ *
+ * examples:
+ * max_offset_writable =63
+ * pkt_size =62
+ * ==>62
+ *
+ */
+static inline uint16_t calc_writable_mbuf_size(uint16_t max_offset_writable,
+ uint16_t pkt_size){
+
+ if ( pkt_size<=64 ){
+ return (pkt_size);
+ }
+ if (pkt_size<=128) {
+ return (pkt_size);
+ }
+
+ //pkt_size> 128
+ uint16_t non_writable = pkt_size - (max_offset_writable -1) ;
+ if ( non_writable<64 ) {
+ return (pkt_size);
+ }
+ return(max_offset_writable-1);
+}
+
+
+
struct CStreamPktData {
uint8_t *binary;
uint16_t len;
@@ -132,9 +180,14 @@ public:
TrexStream * clone_as_dp() const {
TrexStream *dp = new TrexStream(m_type,m_port_id,m_stream_id);
-
-
dp->m_has_vm = m_has_vm;
+ if (m_vm_dp) {
+ /* should have vm */
+ assert(m_has_vm);
+ dp->m_vm_dp = m_vm_dp->clone();
+ }else{
+ dp->m_vm_dp = NULL;
+ }
dp->m_vm_prefix_size = m_vm_prefix_size;
dp->m_isg_usec = m_isg_usec;
@@ -165,11 +218,22 @@ public:
}
void Dump(FILE *fd);
+
+ bool is_vm(){
+ return ( m_has_vm );
+ }
+
+ StreamVmDp * getDpVm(){
+ return ( m_vm_dp);
+ }
+
+ void post_vm_compile();
+
public:
/* basic */
uint8_t m_type;
uint8_t m_port_id;
- uint16_t m_vm_prefix_size;
+ uint16_t m_vm_prefix_size; /* writeable mbuf size */
uint32_t m_stream_id; /* id from RPC can be anything */
@@ -183,6 +247,8 @@ public:
bool m_has_vm; /* do we have instructions to run */
+ StreamVmDp * m_vm_dp; /* compile VM */
+
CStreamPktData m_pkt;
/* pkt */
diff --git a/src/stateless/cp/trex_stream_vm.h b/src/stateless/cp/trex_stream_vm.h
index 2dd4ec19..2bf72829 100644
--- a/src/stateless/cp/trex_stream_vm.h
+++ b/src/stateless/cp/trex_stream_vm.h
@@ -842,6 +842,13 @@ public:
return (lp);
}
+ uint8_t* clone_bss(){
+ assert(m_bss_size>0);
+ uint8_t *p=(uint8_t *)malloc(m_bss_size);
+ assert(p);
+ memcpy(p,m_bss_ptr,m_bss_size);
+ return (p);
+ }
uint16_t get_bss_size(){
return(m_bss_size);
diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp
index 142b38bf..585ff2c7 100644
--- a/src/stateless/dp/trex_stateless_dp_core.cpp
+++ b/src/stateless/dp/trex_stateless_dp_core.cpp
@@ -120,7 +120,15 @@ rte_mbuf_t * CGenNodeStateless::alloc_node_with_vm(){
char *p=rte_pktmbuf_append(m, prefix_size);
memcpy( p ,m_original_packet_data_prefix, prefix_size);
- /* TBD run VM on the pointer p */
+
+ /* run the VM program */
+ StreamDPVmInstructionsRunner runner;
+
+ runner.run( m_vm_program_size,
+ m_vm_program,
+ m_vm_flow_var,
+ (uint8_t*)p);
+
rte_mbuf_t * m_const = get_const_mbuf();
if ( m_const != NULL) {
@@ -144,7 +152,11 @@ void CGenNodeStateless::free_stl_node(){
}
free_prefix_header();
}
-
+ if (m_vm_flow_var) {
+ /* free flow var */
+ free(m_vm_flow_var);
+ m_vm_flow_var=0;
+ }
}
@@ -527,7 +539,13 @@ TrexStatelessDpCore::add_stream(TrexStatelessDpPerPort * lp_port,
node->set_mbuf_cache_dir(dir);
- if (stream->m_has_vm == false ) {
+ if (stream->is_vm() == false ) {
+ /* no VM */
+
+ node->m_vm_flow_var = NULL;
+ node->m_vm_program = NULL;
+ node->m_vm_program_size =0;
+
/* allocate const mbuf */
rte_mbuf_t *m = CGlobalInfo::pktmbuf_alloc(node->get_socket_id(), pkt_size);
assert(m);
@@ -545,8 +563,18 @@ TrexStatelessDpCore::add_stream(TrexStatelessDpPerPort * lp_port,
node->m_original_packet_data_prefix =0;
}else{
- /* we need to copy the object */
+ /* set the program */
+ TrexStream * local_mem_stream = node->m_ref_stream_info;
+
+ StreamVmDp * lpDpVm = local_mem_stream->getDpVm();
+
+ node->m_vm_flow_var = lpDpVm->clone_bss(); /* clone the flow var */
+ node->m_vm_program = lpDpVm->get_program(); /* same ref to the program */
+ node->m_vm_program_size =lpDpVm->get_program_size();
+
+
+ /* we need to copy the object */
if ( pkt_size > stream->m_vm_prefix_size ) {
/* we need const packet */
uint16_t const_pkt_size = pkt_size - stream->m_vm_prefix_size ;
diff --git a/src/stateless/dp/trex_stream_node.h b/src/stateless/dp/trex_stream_node.h
index fc7d7a44..d33785fe 100644
--- a/src/stateless/dp/trex_stream_node.h
+++ b/src/stateless/dp/trex_stream_node.h
@@ -93,15 +93,20 @@ private:
uint32_t m_multi_bursts; /* in case of multi_burst how many bursts */
/* cache line 1 */
- TrexStream * m_ref_stream_info; /* the stream info */
+ TrexStream * m_ref_stream_info; /* the stream info */
CGenNodeStateless * m_next_stream;
uint8_t * m_original_packet_data_prefix; /* pointer to the original first pointer 64/128/512 */
- /* pad to match the size of CGenNode */
- uint8_t m_pad_end[48];
+ /* Fast Field VM section */
+ uint8_t * m_vm_flow_var; /* pointer to the vm flow var */
+ uint8_t * m_vm_program; /* pointer to the program */
+ uint16_t m_vm_program_size; /* up to 64K op codes */
+ /* End Fast Field VM Section */
+ /* pad to match the size of CGenNode */
+ uint8_t m_pad_end[30];
public: