diff options
author | Hanoh Haim <hhaim@cisco.com> | 2015-12-15 14:45:55 +0200 |
---|---|---|
committer | Hanoh Haim <hhaim@cisco.com> | 2015-12-15 14:45:55 +0200 |
commit | e7ffce7b0317f9861264b17d003b22915177de33 (patch) | |
tree | ccf0b538a8bfbabb476f4f6e9b02139eb17dc11b /src/stateless | |
parent | e263b80e39391a7552d9b9f56940e4fe4a9c3fbc (diff) |
first test works
Diffstat (limited to 'src/stateless')
-rw-r--r-- | src/stateless/cp/trex_stream.cpp | 21 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream.h | 72 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream_vm.h | 7 | ||||
-rw-r--r-- | src/stateless/dp/trex_stateless_dp_core.cpp | 36 | ||||
-rw-r--r-- | src/stateless/dp/trex_stream_node.h | 11 |
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: |