diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/bp_sim.cpp | 24 | ||||
-rw-r--r-- | src/gtest/trex_stateless_gtest.cpp | 25 | ||||
-rw-r--r-- | src/main_dpdk.cpp | 26 | ||||
-rwxr-xr-x | src/pal/linux/mbuf.h | 7 | ||||
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmd_stream.cpp | 2 | ||||
-rw-r--r-- | src/stateless/dp/trex_stateless_dp_core.cpp | 90 | ||||
-rw-r--r-- | src/stateless/dp/trex_stateless_dp_core.h | 5 | ||||
-rw-r--r-- | src/stateless/dp/trex_stream_node.h | 11 |
8 files changed, 153 insertions, 37 deletions
diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp index 9725084c..687f51fd 100755 --- a/src/bp_sim.cpp +++ b/src/bp_sim.cpp @@ -4840,20 +4840,26 @@ int CErfIFStl::send_node(CGenNode * _no_to_use){ pkt_dir_t dir=(pkt_dir_t)node_sl->get_mbuf_cache_dir(); - /* check that we have mbuf */ - rte_mbuf_t * m=node_sl->get_cache_mbuf(); - if (m) { - /* cache packet */ + rte_mbuf_t * m; + if ( likely(node_sl->is_cache_mbuf_array()) ) { + m=node_sl->cache_mbuf_array_get_cur(); fill_raw_packet(m,_no_to_use,dir); - /* can't free the m, it is cached*/ }else{ + m=node_sl->get_cache_mbuf(); + if (m) { + /* cache packet */ + fill_raw_packet(m,_no_to_use,dir); + /* can't free the m, it is cached*/ + }else{ - m=node_sl->alloc_node_with_vm(); - assert(m); - fill_raw_packet(m,_no_to_use,dir); - rte_pktmbuf_free(m); + m=node_sl->alloc_node_with_vm(); + assert(m); + fill_raw_packet(m,_no_to_use,dir); + rte_pktmbuf_free(m); + } } + /* check that we have mbuf */ int rc = write_pkt(m_raw); BP_ASSERT(rc == 0); diff --git a/src/gtest/trex_stateless_gtest.cpp b/src/gtest/trex_stateless_gtest.cpp index a33d2d74..11070f5c 100644 --- a/src/gtest/trex_stateless_gtest.cpp +++ b/src/gtest/trex_stateless_gtest.cpp @@ -156,7 +156,6 @@ TEST_F(basic_vm, cache_basic) { for (i=0; i<10; i++) { rte_mbuf_t * m =node->cache_mbuf_array_get_cur(); printf(" %d \n",m->data_off); - //rte_pktmbuf_refcnt_update(m,1); /* both */ } node->cache_mbuf_array_free(); @@ -2775,13 +2774,13 @@ TEST_F(basic_stl, multi_pkt1) { class CEnableVm { public: - void run(bool full_packet,double duration ); + void run(bool full_packet,double duration,uint16_t cache ); public: std::string m_input_packet; //"cap2/udp_64B.pcap" std::string m_out_file; //"exp/stl_vm_enable0"; }; -void CEnableVm::run(bool full_packet,double duration=10.0){ +void CEnableVm::run(bool full_packet,double duration=10.0,uint16_t cache=0){ CBasicStl t1; CParserOption * po =&CGlobalInfo::m_options; @@ -2797,6 +2796,10 @@ void CEnableVm::run(bool full_packet,double duration=10.0){ TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); + if ( cache ){ + stream1->m_cache_size=cache; + } + stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0); stream1->m_enabled = true; @@ -2839,6 +2842,22 @@ void CEnableVm::run(bool full_packet,double duration=10.0){ EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; } +TEST_F(basic_stl, vm_enable_cache_10) { + + CEnableVm vm_test; + vm_test.m_out_file = "exp/stl_vm_enable0_cache_10"; + vm_test.m_input_packet = "cap2/udp_64B.pcap"; + vm_test.run(true,10.0,100); +} + +TEST_F(basic_stl, vm_enable_cache_500) { + /* multi mbuf cache */ + CEnableVm vm_test; + vm_test.m_out_file = "exp/stl_vm_enable1_cache_500"; + vm_test.m_input_packet = "stl/yaml/udp_594B_no_crc.pcap"; + vm_test.run(false,20.0,19); +} + TEST_F(basic_stl, vm_enable0) { diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 6dec3dec..3fa3ca68 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -1943,13 +1943,6 @@ int CCoreEthIF::send_pkt(CCorePerPort * lp_port, CVirtualIFPerSideStats * lp_stats ){ - //printf(" %lu \n",(ulong)rte_pktmbuf_pkt_len(m)); - //rte_pktmbuf_dump(stdout,m, rte_pktmbuf_pkt_len(m)); - - /* too expensive remove this for now */ - //lp_stats->m_tx_pkt +=1; - //lp_stats->m_tx_bytes += (rte_pktmbuf_pkt_len(m)+4); - uint16_t len = lp_port->m_len; lp_port->m_table[len]=m; len++; @@ -2001,16 +1994,23 @@ void CCoreEthIF::update_mac_addr(CGenNode * node,uint8_t *p){ int CCoreEthIFStateless::send_node(CGenNode * no){ CGenNodeStateless * node_sl=(CGenNodeStateless *) no; /* check that we have mbuf */ - rte_mbuf_t * m=node_sl->get_cache_mbuf(); + rte_mbuf_t * m; + pkt_dir_t dir=(pkt_dir_t)node_sl->get_mbuf_cache_dir(); CCorePerPort * lp_port=&m_ports[dir]; CVirtualIFPerSideStats * lp_stats = &m_stats[dir]; - if (m) { - /* cache case */ - rte_pktmbuf_refcnt_update(m,1); + if ( likely(node_sl->is_cache_mbuf_array()) ) { + m=node_sl->cache_mbuf_array_get_cur(); }else{ - m=node_sl->alloc_node_with_vm(); - assert(m); + m=node_sl->get_cache_mbuf(); + + if (m) { + /* cache case */ + rte_pktmbuf_refcnt_update(m,1); + }else{ + m=node_sl->alloc_node_with_vm(); + assert(m); + } } if (unlikely(node_sl->is_stat_needed())) { diff --git a/src/pal/linux/mbuf.h b/src/pal/linux/mbuf.h index 4132f842..50f00b94 100755 --- a/src/pal/linux/mbuf.h +++ b/src/pal/linux/mbuf.h @@ -182,6 +182,13 @@ static inline void utl_rte_pktmbuf_add_last(rte_mbuf_t *m,rte_mbuf_t *m_last){ } } +static inline void rte_pktmbuf_refcnt_update(struct rte_mbuf *m, int16_t v) +{ + do { + rte_mbuf_refcnt_update(m, v); + } while ((m = m->next) != NULL); +} + diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp index 54e35d4e..2013c9e8 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp @@ -396,6 +396,8 @@ TrexRpcCmdAddStream::parse_vm(const Json::Value &vm, std::unique_ptr<TrexStream> } stream->m_vm.set_split_instruction(instr); } + stream->m_cache_size = parse_uint16(vm, "cache", result,0); /* default is zero */ + } void diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp index 23f1f4c2..4bfeef4b 100644 --- a/src/stateless/dp/trex_stateless_dp_core.cpp +++ b/src/stateless/dp/trex_stateless_dp_core.cpp @@ -25,6 +25,7 @@ limitations under the License. #include "trex_stream.h" #include "trex_stream_node.h" #include "trex_streams_compiler.h" +#include "mbuf.h" @@ -35,6 +36,18 @@ void CGenNodeStateless::cache_mbuf_array_init(){ } + +void CGenNodeStateless::cache_mbuf_array_copy(CGenNodeCacheMbuf *obj, + uint16_t size){ + + int i; + cache_mbuf_array_alloc(size); + for (i=0; i<size; i++) { + cache_mbuf_array_set(i,obj->m_array[i]); + } + cache_mbuf_array_set_const_mbuf(obj->m_mbuf_const); +} + rte_mbuf_t ** CGenNodeStateless::cache_mbuf_array_alloc(uint16_t size){ @@ -255,6 +268,25 @@ rte_mbuf_t * CGenNodeStateless::alloc_node_with_vm(){ return (m); } +void CGenNodeStateless::free_stl_vm_buf(){ + rte_mbuf_t * m ; + m=get_const_mbuf(); + if (m) { + rte_pktmbuf_free(m); /* reduce the ref counter */ + /* clear the const marker */ + clear_const_mbuf(); + } + + free_prefix_header(); + + if (m_vm_flow_var) { + /* free flow var */ + free(m_vm_flow_var); + m_vm_flow_var=0; + } +} + + void CGenNodeStateless::free_stl_node(){ @@ -267,20 +299,9 @@ void CGenNodeStateless::free_stl_node(){ if (m) { rte_pktmbuf_free(m); m_cache_mbuf=0; - }else{ - /* non cache - must have an header */ - m=get_const_mbuf(); - if (m) { - rte_pktmbuf_free(m); /* reduce the ref counter */ - } - free_prefix_header(); } } - if (m_vm_flow_var) { - /* free flow var */ - free(m_vm_flow_var); - m_vm_flow_var=0; - } + free_stl_vm_buf(); } @@ -650,12 +671,52 @@ void TrexStatelessDpCore::update_mac_addr(TrexStream * stream, } +void TrexStatelessDpCore::replay_vm_into_cache(TrexStream * stream, + CGenNodeStateless *node){ + + uint16_t cache_size = stream->m_cache_size; + assert(cache_size>0); + rte_mbuf_t * m=0; + + /* TBD do we have enough from this type of object , need to ask ! */ + + uint32_t buf_size = CGenNodeCacheMbuf::get_object_size(cache_size); + /* TBD replace with align, zero API */ + CGenNodeCacheMbuf * p = (CGenNodeCacheMbuf *)malloc(buf_size); + assert(p); + memset(p,0,buf_size); + + int i; + for (i=0; i<cache_size; i++) { + p->m_array[i] = node->alloc_node_with_vm(); + } + /* save const */ + m=node->get_const_mbuf(); + if (m) { + p->m_mbuf_const=m; + rte_pktmbuf_refcnt_update(m,1); + } + + /* free all VM and const mbuf */ + node->free_stl_vm_buf(); + + /* copy to local node meory */ + node->cache_mbuf_array_copy(p,cache_size); + + /* free the memory */ + free(p); +} + + void TrexStatelessDpCore::add_stream(TrexStatelessDpPerPort * lp_port, TrexStream * stream, TrexStreamsCompiledObj *comp) { CGenNodeStateless *node = m_core->create_node_sl(); + node->cache_mbuf_array_init(); + node->m_batch_size=0; + /* add periodic */ node->m_cache_mbuf=0; node->m_type = CGenNode::STATELESS_PKT; @@ -815,6 +876,11 @@ TrexStatelessDpCore::add_stream(TrexStatelessDpPerPort * lp_port, memcpy(p,stream_pkt , header_size); update_mac_addr(stream,node,dir,(char *)p); + + if (stream->m_cache_size > 0 ) { + /* we need to create cache of objects */ + replay_vm_into_cache(stream, node); + } } diff --git a/src/stateless/dp/trex_stateless_dp_core.h b/src/stateless/dp/trex_stateless_dp_core.h index cb102b8d..cd61b486 100644 --- a/src/stateless/dp/trex_stateless_dp_core.h +++ b/src/stateless/dp/trex_stateless_dp_core.h @@ -281,6 +281,11 @@ private: TrexStream * stream, TrexStreamsCompiledObj *comp); + + void replay_vm_into_cache(TrexStream * stream, + CGenNodeStateless *node); + + uint8_t m_thread_id; uint8_t m_local_port_offset; diff --git a/src/stateless/dp/trex_stream_node.h b/src/stateless/dp/trex_stream_node.h index 4d3c2ae1..e9e5cf5b 100644 --- a/src/stateless/dp/trex_stream_node.h +++ b/src/stateless/dp/trex_stream_node.h @@ -361,6 +361,10 @@ public: } } + void clear_const_mbuf(){ + m_flags= ( m_flags & ~SL_NODE_CONST_MBUF ); + } + /* prefix header exits only in non cache mode size is 64/128/512 other are not possible right now */ inline void alloc_prefix_header(uint16_t size){ set_prefix_header_size(size); @@ -371,6 +375,7 @@ public: inline void free_prefix_header(){ if (m_original_packet_data_prefix) { free(m_original_packet_data_prefix); + m_original_packet_data_prefix=0; } } @@ -388,6 +393,10 @@ public: void free_stl_node(); +protected: + + void free_stl_vm_buf(); + public: void cache_mbuf_array_init(); @@ -395,6 +404,8 @@ public: return ( m_flags & SL_NODE_CONST_MBUF_CACHE_ARRAY ? true:false ); } + void cache_mbuf_array_copy(CGenNodeCacheMbuf *obj,uint16_t size); + rte_mbuf_t ** cache_mbuf_array_alloc(uint16_t size); void cache_mbuf_array_free(); |