diff options
author | 2015-12-15 14:45:55 +0200 | |
---|---|---|
committer | 2015-12-15 14:45:55 +0200 | |
commit | e7ffce7b0317f9861264b17d003b22915177de33 (patch) | |
tree | ccf0b538a8bfbabb476f4f6e9b02139eb17dc11b | |
parent | e263b80e39391a7552d9b9f56940e4fe4a9c3fbc (diff) |
first test works
-rw-r--r-- | scripts/exp/stl_vm_enable0-0-ex.erf | bin | 880 -> 880 bytes | |||
-rw-r--r-- | src/gtest/trex_stateless_gtest.cpp | 77 | ||||
-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 |
7 files changed, 180 insertions, 44 deletions
diff --git a/scripts/exp/stl_vm_enable0-0-ex.erf b/scripts/exp/stl_vm_enable0-0-ex.erf Binary files differindex 92883717..c6285be1 100644 --- a/scripts/exp/stl_vm_enable0-0-ex.erf +++ b/scripts/exp/stl_vm_enable0-0-ex.erf diff --git a/src/gtest/trex_stateless_gtest.cpp b/src/gtest/trex_stateless_gtest.cpp index 2b08ebbb..d758ea7e 100644 --- a/src/gtest/trex_stateless_gtest.cpp +++ b/src/gtest/trex_stateless_gtest.cpp @@ -33,6 +33,8 @@ limitations under the License. #include <vector> + + class CPcapLoader { public: CPcapLoader(); @@ -136,6 +138,23 @@ class basic_vm : public testing::Test { }; + + +TEST_F(basic_vm, pkt_size) { + + EXPECT_EQ(calc_writable_mbuf_size(36,62),62); + EXPECT_EQ(calc_writable_mbuf_size(63,62),62); + EXPECT_EQ(calc_writable_mbuf_size(45,65),65); + EXPECT_EQ(calc_writable_mbuf_size(66,65),65); + EXPECT_EQ(calc_writable_mbuf_size(62,128),128); + EXPECT_EQ(calc_writable_mbuf_size(62,252),61); + EXPECT_EQ(calc_writable_mbuf_size(121,252),120); + EXPECT_EQ(calc_writable_mbuf_size(253,252),252); + EXPECT_EQ(calc_writable_mbuf_size(250,252),252); + EXPECT_EQ(calc_writable_mbuf_size(184,252),183); +} + + /* start/stop/stop back to back */ TEST_F(basic_vm, vm0) { @@ -764,11 +783,8 @@ TEST_F(basic_vm, vm8) { EXPECT_EQ(1, res1?1:0); } -TEST_F(basic_vm, vm9) { - - - - StreamVm vm; +static void vm_build_program_seq(StreamVm & vm, + uint16_t packet_size ){ vm.add_instruction( new StreamVmInstructionFlowClient( "tuple_gen", 0x10000001, @@ -792,6 +808,15 @@ TEST_F(basic_vm, vm9) { vm.set_packet_size(128); vm.compile_next(); +} + + +TEST_F(basic_vm, vm9) { + + + StreamVm vm; + + vm_build_program_seq(vm,128); printf(" max packet update %lu \n",(ulong)vm.get_max_packet_update_offset()); @@ -837,32 +862,9 @@ TEST_F(basic_vm, vm9) { /* test vmDP object */ TEST_F(basic_vm, vm10) { - - StreamVm vm; - vm.add_instruction( new StreamVmInstructionFlowClient( "tuple_gen", - 0x10000001, - 0x10000006, - 1025, - 1027, - 20, - 0) ); - - /* src ip */ - vm.add_instruction( new StreamVmInstructionWriteToPkt( "tuple_gen.ip",26, 0,true) - ); - - vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) ); - - /* src port */ - vm.add_instruction( new StreamVmInstructionWriteToPkt( "tuple_gen.port",34, 0,true) - ); - - - vm.set_packet_size(128); - - vm.compile_next(); + vm_build_program_seq(vm,128); printf(" max packet update %lu \n",(ulong)vm.get_max_packet_update_offset()); @@ -2009,7 +2011,6 @@ TEST_F(basic_stl, multi_pkt1) { - TEST_F(basic_stl, vm_enable0) { CBasicStl t1; @@ -2025,20 +2026,26 @@ TEST_F(basic_stl, vm_enable0) { std::vector<TrexStream *> streams; TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); - stream1->m_has_vm = true; - stream1->m_vm_prefix_size =64; - stream1->set_pps(1.0); + stream1->set_pps(1.0); stream1->m_enabled = true; stream1->m_self_start = true; stream1->m_port_id= port_id; - CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000001); pcap.clone_packet_into_stream(stream1); + + uint16_t pkt_size=pcap.m_raw.pkt_len; + + stream1->m_has_vm = true; + vm_build_program_seq(stream1->m_vm,pkt_size); + stream1->post_vm_compile(); + printf(" vm_prefix_size %d \n",stream1->m_vm_prefix_size); + EXPECT_EQ(stream1->m_vm_prefix_size,pkt_size); + streams.push_back(stream1); @@ -2062,6 +2069,7 @@ TEST_F(basic_stl, vm_enable0) { } +#if 0 TEST_F(basic_stl, vm_enable1) { CBasicStl t1; @@ -2162,6 +2170,7 @@ TEST_F(basic_stl, vm_enable2) { EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; } +#endif 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: |