diff options
author | 2016-05-08 13:50:57 +0300 | |
---|---|---|
committer | 2016-05-08 13:50:57 +0300 | |
commit | c2912dfc5ad81e2edcf77b7ee992f92216ed0bad (patch) | |
tree | 4676234974ed4de8c804047b2e4463b893518932 /src | |
parent | f27bfbab72f9221b221a7f36f4063e9ff8e9d307 (diff) |
add cache capability to stateless node object
Diffstat (limited to 'src')
-rwxr-xr-x | src/bp_gtest.cpp | 2 | ||||
-rwxr-xr-x | src/bp_sim.cpp | 20 | ||||
-rwxr-xr-x | src/bp_sim.h | 2 | ||||
-rw-r--r-- | src/gtest/trex_stateless_gtest.cpp | 27 | ||||
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmd_stream.cpp | 1 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream.cpp | 3 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream.h | 3 | ||||
-rw-r--r-- | src/stateless/dp/trex_stateless_dp_core.cpp | 97 | ||||
-rw-r--r-- | src/stateless/dp/trex_stream_node.h | 72 | ||||
-rwxr-xr-x | src/utl_cpuu.h | 10 |
10 files changed, 209 insertions, 28 deletions
diff --git a/src/bp_gtest.cpp b/src/bp_gtest.cpp index 3189e886..6085de76 100755 --- a/src/bp_gtest.cpp +++ b/src/bp_gtest.cpp @@ -1134,6 +1134,7 @@ TEST_F(basic, http1_ipv6) { void delay(int msec); +#if 0 TEST_F(cpu, cpu1) { CCpuUtlDp cpu_dp; @@ -1176,6 +1177,7 @@ TEST_F(cpu, cpu2) { cpu_cp.Delete(); } +#endif #if 0 TEST_F(cpu, cpu3) { diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp index 94f8a2ba..9725084c 100755 --- a/src/bp_sim.cpp +++ b/src/bp_sim.cpp @@ -3576,16 +3576,22 @@ int CNodeGenerator::flush_file(dsec_t max_time, CFlowGenListPerThread * thread, double &old_offset){ CGenNode * node; + #ifdef TREX_SIM dsec_t flush_time=now_sec(); + #endif dsec_t offset=0.0; + #ifdef TREX_SIM dsec_t n_time; + #endif if (always) { offset=old_offset; } + #ifdef TREX_SIM uint32_t events=0; + #endif bool done=false; - thread->m_cpu_dp_u.start_work(); + thread->m_cpu_dp_u.start_work1(); /** * if a positive value was given to max time @@ -3602,18 +3608,25 @@ int CNodeGenerator::flush_file(dsec_t max_time, while (true) { node = m_p_queue.top(); + #ifdef TREX_SIM n_time = node->m_time + offset; events++; + #endif /*#ifdef VALG if (events > 1 ) { CALLGRIND_START_INSTRUMENTATION; } #endif*/ + thread->m_cpu_dp_u.commit1(); + thread->m_cpu_dp_u.start_work1(); + + #ifdef TREX_SIM + if ( likely ( m_is_realtime ) ){ dsec_t dt ; - thread->m_cpu_dp_u.commit(); + thread->m_cpu_dp_u.commit1(); while ( true ) { dt = now_sec() - n_time ; @@ -3624,7 +3637,7 @@ int CNodeGenerator::flush_file(dsec_t max_time, rte_pause(); } - thread->m_cpu_dp_u.start_work(); + thread->m_cpu_dp_u.start_work1(); /* add offset in case of faliures more than 100usec */ if ( unlikely( dt > 0.000100 ) ) { @@ -3640,6 +3653,7 @@ int CNodeGenerator::flush_file(dsec_t max_time, flush_time=now_sec(); } } + #endif uint8_t type=node->m_type; diff --git a/src/bp_sim.h b/src/bp_sim.h index 1ec036c0..c077b0b9 100755 --- a/src/bp_sim.h +++ b/src/bp_sim.h @@ -1436,7 +1436,7 @@ public: NODE_FLAGS_LATENCY =0x20, /* got NAT msg */ NODE_FLAGS_INIT_START_FROM_SERVER_SIDE = 0x40, NODE_FLAGS_ALL_FLOW_SAME_PORT_SIDE = 0x80, - NODE_FLAGS_INIT_START_FROM_SERVER_SIDE_SERVER_ADDR = 0x100 /* init packet start from server side with server addr */ + NODE_FLAGS_INIT_START_FROM_SERVER_SIDE_SERVER_ADDR = 0x100, /* init packet start from server side with server addr */ }; diff --git a/src/gtest/trex_stateless_gtest.cpp b/src/gtest/trex_stateless_gtest.cpp index a5cf3307..a33d2d74 100644 --- a/src/gtest/trex_stateless_gtest.cpp +++ b/src/gtest/trex_stateless_gtest.cpp @@ -140,6 +140,29 @@ class basic_vm : public testing::Test { }; +TEST_F(basic_vm, cache_basic) { + + CGenNodeStateless *node = new CGenNodeStateless(); + + node->cache_mbuf_array_init(); + int i; + node->cache_mbuf_array_alloc(10); + for (i=0; i<10; i++) { + rte_mbuf_t * m =CGlobalInfo::pktmbuf_alloc_small(0); + m->data_off=i; + node->cache_mbuf_array_set(i,(rte_mbuf_t *) m); + } + + 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(); + + delete node; +} TEST_F(basic_vm, pkt_size) { @@ -3585,3 +3608,7 @@ TEST_F(rx_stat_pkt_parse, x710_parser) { parser.test(); } + + + + diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp index 40719325..54e35d4e 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp @@ -60,6 +60,7 @@ TrexRpcCmdAddStream::_run(const Json::Value ¶ms, Json::Value &result) { stream->m_flags = parse_int(section, "flags", result); stream->m_action_count = parse_uint16(section, "action_count", result); stream->m_random_seed = parse_uint32(section, "random_seed", result,0); /* default is zero */ + stream->m_cache_size = parse_uint16(section, "cache", result,0); /* default is zero */ /* inter stream gap */ stream->m_isg_usec = parse_double(section, "isg", result); diff --git a/src/stateless/cp/trex_stream.cpp b/src/stateless/cp/trex_stream.cpp index 4325858c..5a24e2b3 100644 --- a/src/stateless/cp/trex_stream.cpp +++ b/src/stateless/cp/trex_stream.cpp @@ -121,7 +121,7 @@ void TrexStream::Dump(FILE *fd){ fprintf(fd," bps L1 : %f\n", m_rate.get_bps_L1()); fprintf(fd," bps L2 : %f\n", m_rate.get_bps_L2()); fprintf(fd," percentage : %f\n", m_rate.get_percentage()); - + fprintf(fd," cache_size : %lu\n", (ulong)m_cache_size); } @@ -134,6 +134,7 @@ TrexStream::TrexStream(uint8_t type, m_next_stream_id = -1; m_enabled = false; m_self_start = false; + m_cache_size = 0; m_mc_phase_pre_sec = 0; m_mc_phase_post_sec = 0; diff --git a/src/stateless/cp/trex_stream.h b/src/stateless/cp/trex_stream.h index c5bfdb98..ba5fa214 100644 --- a/src/stateless/cp/trex_stream.h +++ b/src/stateless/cp/trex_stream.h @@ -440,6 +440,7 @@ public: dp->m_num_bursts = m_num_bursts; dp->m_ibg_usec = m_ibg_usec; dp->m_flags = m_flags; + dp->m_cache_size = m_cache_size; dp->m_action_count = m_action_count; dp->m_random_seed = m_random_seed; @@ -514,8 +515,10 @@ public: uint8_t m_type; uint8_t m_port_id; uint16_t m_flags; + uint32_t m_stream_id; /* id from RPC can be anything */ uint16_t m_action_count; + uint16_t m_cache_size; uint32_t m_random_seed; diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp index d3d49a34..23f1f4c2 100644 --- a/src/stateless/dp/trex_stateless_dp_core.cpp +++ b/src/stateless/dp/trex_stateless_dp_core.cpp @@ -26,6 +26,75 @@ limitations under the License. #include "trex_stream_node.h" #include "trex_streams_compiler.h" + + + +void CGenNodeStateless::cache_mbuf_array_init(){ + m_cache_size=0; + m_cache_array_cnt=0; +} + + + +rte_mbuf_t ** CGenNodeStateless::cache_mbuf_array_alloc(uint16_t size){ + + uint32_t buf_size = CGenNodeCacheMbuf::get_object_size(size); + /* TBD replace with align, zero API */ + m_cache_mbuf = (void *)malloc(buf_size); + assert(m_cache_mbuf); + memset(m_cache_mbuf,0,buf_size); + + m_flags |= SL_NODE_CONST_MBUF_CACHE_ARRAY; + m_cache_size=size; + m_cache_array_cnt=0; + return ((rte_mbuf_t **)m_cache_mbuf); +} + +void CGenNodeStateless::cache_mbuf_array_free(){ + + assert(m_cache_mbuf); + int i; + for (i=0; i<(int)m_cache_size; i++) { + rte_mbuf_t * m=cache_mbuf_array_get((uint16_t)i); + assert(m); + rte_pktmbuf_free(m); + } + + /* free the const */ + rte_mbuf_t * m=cache_mbuf_array_get_const_mbuf() ; + if (m) { + rte_pktmbuf_free(m); + } + + free(m_cache_mbuf); + m_cache_mbuf=0; +} + + +rte_mbuf_t * CGenNodeStateless::cache_mbuf_array_get(uint16_t index){ + + CGenNodeCacheMbuf *p =(CGenNodeCacheMbuf *) m_cache_mbuf; + return (p->m_array[index]); +} + +void CGenNodeStateless::cache_mbuf_array_set_const_mbuf(rte_mbuf_t * m){ + CGenNodeCacheMbuf *p =(CGenNodeCacheMbuf *) m_cache_mbuf; + p->m_mbuf_const=m; +} + +rte_mbuf_t * CGenNodeStateless::cache_mbuf_array_get_const_mbuf(){ + CGenNodeCacheMbuf *p =(CGenNodeCacheMbuf *) m_cache_mbuf; + return (p->m_mbuf_const); +} + + +void CGenNodeStateless::cache_mbuf_array_set(uint16_t index, + rte_mbuf_t * m){ + CGenNodeCacheMbuf *p =(CGenNodeCacheMbuf *) m_cache_mbuf; + p->m_array[index]=m; +} + + void CDpOneStream::Delete(CFlowGenListPerThread * core){ assert(m_node->get_state() == CGenNodeStateless::ss_INACTIVE); core->free_node((CGenNode *)m_node); @@ -188,18 +257,24 @@ rte_mbuf_t * CGenNodeStateless::alloc_node_with_vm(){ void CGenNodeStateless::free_stl_node(){ - /* if we have cache mbuf free it */ - rte_mbuf_t * m=get_cache_mbuf(); - if (m) { - rte_pktmbuf_free(m); - m_cache_mbuf=0; + + if ( is_cache_mbuf_array() ){ + /* do we have cache of mbuf pre allocated */ + cache_mbuf_array_free(); }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 we have cache mbuf free it */ + rte_mbuf_t * m=get_cache_mbuf(); + 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 */ diff --git a/src/stateless/dp/trex_stream_node.h b/src/stateless/dp/trex_stream_node.h index c85bf8b5..4d3c2ae1 100644 --- a/src/stateless/dp/trex_stream_node.h +++ b/src/stateless/dp/trex_stream_node.h @@ -49,6 +49,15 @@ public: static_assert(sizeof(CGenNodeCommand) == sizeof(CGenNode), "sizeof(CGenNodeCommand) != sizeof(CGenNode)" ); +struct CGenNodeCacheMbuf { + rte_mbuf_t * m_mbuf_const; + rte_mbuf_t * m_array[0]; +public: + static uint32_t get_object_size(uint32_t size){ + return ( sizeof(CGenNodeCacheMbuf) + sizeof(rte_mbuf_t *) * size ); + } +}; + /* this is a event for stateless */ struct CGenNodeStateless : public CGenNodeBase { friend class TrexStatelessDpCore; @@ -61,10 +70,10 @@ public: SL_NODE_FLAGS_MBUF_CACHE =2, //USED by master SL_NODE_CONST_MBUF =4, - - SL_NODE_VAR_PKT_SIZE =8, - SL_NODE_STATS_NEEDED = 0x10 - + + SL_NODE_VAR_PKT_SIZE = 8, + SL_NODE_STATS_NEEDED = 0x10, + SL_NODE_CONST_MBUF_CACHE_ARRAY = 0x20 /* array of mbuf - cache */ }; enum { @@ -77,15 +86,18 @@ public: static std::string get_stream_state_str(stream_state_t stream_state); private: - /* cache line 0 */ - /* important stuff here */ - void * m_cache_mbuf; + /******************************/ + /* cache line 0 */ + /* important stuff here R/W */ + /******************************/ + void * m_cache_mbuf; /* could be an array or a one mbuf */ double m_next_time_offset; /* in sec */ uint16_t m_action_counter; uint8_t m_stat_hw_id; // hw id used to count rx and tx stats uint8_t m_null_stream; - uint32_t m_pad12; + uint16_t m_cache_array_cnt; + uint16_t m_pad12; stream_state_t m_state; uint8_t m_port_id; @@ -97,7 +109,10 @@ private: uint32_t m_multi_bursts; /* in case of multi_burst how many bursts */ - /* cache line 1 */ + /******************************/ + /* cache line 1 + this cache line should be READONLY ! you can write only at init time */ + /******************************/ TrexStream * m_ref_stream_info; /* the stream info */ CGenNodeStateless * m_next_stream; @@ -107,8 +122,11 @@ private: 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 */ - uint16_t m_pad2; - uint32_t m_pad3; + uint16_t m_cache_size; /*RO*/ /* the size of the mbuf array */ + uint8_t m_batch_size; /*RO*/ /* the batch size */ + + uint8_t m_pad4; + uint16_t m_pad5; /* End Fast Field VM Section */ @@ -118,6 +136,8 @@ private: public: + + void set_random_seed(uint32_t seed){ uint32_t *p=get_random_bss_seed_memory(); *p=seed; @@ -369,6 +389,36 @@ public: void free_stl_node(); public: + void cache_mbuf_array_init(); + + inline bool is_cache_mbuf_array(){ + return ( m_flags & SL_NODE_CONST_MBUF_CACHE_ARRAY ? true:false ); + } + + rte_mbuf_t ** cache_mbuf_array_alloc(uint16_t size); + + void cache_mbuf_array_free(); + + void cache_mbuf_array_set(uint16_t index,rte_mbuf_t * m); + + void cache_mbuf_array_set_const_mbuf(rte_mbuf_t * m); + + rte_mbuf_t * cache_mbuf_array_get_const_mbuf(); + + rte_mbuf_t * cache_mbuf_array_get(uint16_t index); + + rte_mbuf_t * cache_mbuf_array_get_cur(void){ + CGenNodeCacheMbuf *p =(CGenNodeCacheMbuf *) m_cache_mbuf; + rte_mbuf_t * m=p->m_array[m_cache_array_cnt]; + assert(m); + m_cache_array_cnt++; + if (m_cache_array_cnt == m_cache_size) { + m_cache_array_cnt=0; + } + return m; + } + +public: /* debug functions */ int get_stream_id(); diff --git a/src/utl_cpuu.h b/src/utl_cpuu.h index e7bb50bb..bb3fe67c 100755 --- a/src/utl_cpuu.h +++ b/src/utl_cpuu.h @@ -32,6 +32,14 @@ public: m_total_cycles=0; m_data=0; } + inline void start_work1(){ + m_data=1; + + } + inline void commit1(){ + m_data=0; + } + inline void start_work(){ m_data=os_get_hr_tick_64(); } @@ -50,7 +58,7 @@ public: private: uint64_t m_total_cycles; - uint64_t m_data; + uint8_t m_data; } __rte_cache_aligned; |