diff options
author | 2015-12-20 00:07:44 +0200 | |
---|---|---|
committer | 2015-12-20 00:07:44 +0200 | |
commit | 4ca24cf31919870a684fe78f17c856e0d220e6d5 (patch) | |
tree | f40ab95e52adca3ac713d61eb9fa3fd0d136e4ea /src/stateless/dp | |
parent | 1895d21485621c3428d045fa0f5b9daf165c8260 (diff) | |
parent | 5cef472bcdc6c0b7e20e5cc42485ed5570c10f8c (diff) |
Merge branch 'master' into dan_stateless
Diffstat (limited to 'src/stateless/dp')
-rw-r--r-- | src/stateless/dp/trex_stateless_dp_core.cpp | 140 | ||||
-rw-r--r-- | src/stateless/dp/trex_stateless_dp_core.h | 2 | ||||
-rw-r--r-- | src/stateless/dp/trex_stream_node.h | 69 |
3 files changed, 184 insertions, 27 deletions
diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp index dd4937cd..585ff2c7 100644 --- a/src/stateless/dp/trex_stateless_dp_core.cpp +++ b/src/stateless/dp/trex_stateless_dp_core.cpp @@ -106,12 +106,56 @@ std::string CGenNodeStateless::get_stream_state_str(stream_state_t stream_state) } +rte_mbuf_t * CGenNodeStateless::alloc_node_with_vm(){ + + rte_mbuf_t * m; + /* alloc small packet buffer*/ + uint16_t prefix_size = prefix_header_size(); + m = CGlobalInfo::pktmbuf_alloc( get_socket_id(), prefix_size ); + if (m==0) { + return (m); + } + /* TBD remove this, should handle cases of error */ + assert(m); + char *p=rte_pktmbuf_append(m, prefix_size); + memcpy( p ,m_original_packet_data_prefix, prefix_size); + + + /* 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) { + utl_rte_pktmbuf_add_after(m,m_const); + } + return (m); +} + + 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; + }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; } } @@ -139,7 +183,7 @@ bool TrexStatelessDpPerPort::resume_traffic(uint8_t port_id){ return (true); } -bool TrexStatelessDpPerPort::update_traffic(uint8_t port_id, double mul) { +bool TrexStatelessDpPerPort::update_traffic(uint8_t port_id, double factor) { assert( (m_state == TrexStatelessDpPerPort::ppSTATE_TRANSMITTING || (m_state == TrexStatelessDpPerPort::ppSTATE_PAUSE)) ); @@ -148,7 +192,7 @@ bool TrexStatelessDpPerPort::update_traffic(uint8_t port_id, double mul) { CGenNodeStateless * node = dp_stream.m_node; assert(node->get_port_id() == port_id); - node->set_multiplier(mul); + node->update_rate(factor); } return (true); @@ -423,6 +467,7 @@ TrexStatelessDpCore::add_stream(TrexStatelessDpPerPort * lp_port, CGenNodeStateless *node = m_core->create_node_sl(); /* add periodic */ + node->m_cache_mbuf=0; node->m_type = CGenNode::STATELESS_PKT; node->m_ref_stream_info = stream->clone_as_dp(); @@ -442,6 +487,10 @@ TrexStatelessDpCore::add_stream(TrexStatelessDpPerPort * lp_port, pkt_dir_t dir = m_core->m_node_gen.m_v_if->port_id_to_dir(stream->m_port_id); node->m_flags = 0; + node->m_src_port =0; + node->m_original_packet_data_prefix = 0; + + /* set socket id */ node->set_socket_id(m_core->m_node_gen.m_socket_id); @@ -453,8 +502,7 @@ TrexStatelessDpCore::add_stream(TrexStatelessDpPerPort * lp_port, node->m_pause =0; node->m_stream_type = stream->m_type; - node->m_base_pps = stream->get_pps(); - node->set_multiplier(comp->get_multiplier()); + node->m_next_time_offset = 1.0 / stream->get_pps(); /* stateless specific fields */ switch ( stream->m_type ) { @@ -487,23 +535,77 @@ TrexStatelessDpCore::add_stream(TrexStatelessDpPerPort * lp_port, node->m_port_id = stream->m_port_id; - /* allocate const mbuf */ - rte_mbuf_t *m = CGlobalInfo::pktmbuf_alloc(node->get_socket_id(), pkt_size); - assert(m); - - char *p = rte_pktmbuf_append(m, pkt_size); - assert(p); - /* copy the packet */ - memcpy(p,stream_pkt,pkt_size); - /* set dir 0 or 1 client or server */ node->set_mbuf_cache_dir(dir); - /* TBD repace the mac if req we should add flag */ - m_core->m_node_gen.m_v_if->update_mac_addr_from_global_cfg(dir, m); - /* set the packet as a readonly */ - node->set_cache_mbuf(m); + 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); + + char *p = rte_pktmbuf_append(m, pkt_size); + assert(p); + /* copy the packet */ + memcpy(p,stream_pkt,pkt_size); + + /* TBD repace the mac if req we should add flag */ + m_core->m_node_gen.m_v_if->update_mac_addr_from_global_cfg(dir,(uint8_t*) p); + + /* set the packet as a readonly */ + node->set_cache_mbuf(m); + + node->m_original_packet_data_prefix =0; + }else{ + + /* 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 ; + rte_mbuf_t *m = CGlobalInfo::pktmbuf_alloc(node->get_socket_id(), const_pkt_size ); + assert(m); + + char *p = rte_pktmbuf_append(m, const_pkt_size); + assert(p); + + /* copy packet data */ + memcpy(p,(stream_pkt+ stream->m_vm_prefix_size),const_pkt_size); + + node->set_const_mbuf(m); + } + + + if (stream->m_vm_prefix_size > pkt_size ) { + stream->m_vm_prefix_size = pkt_size; + } + /* copy the headr */ + uint16_t header_size = stream->m_vm_prefix_size; + assert(header_size); + node->alloc_prefix_header(header_size); + uint8_t *p=node->m_original_packet_data_prefix; + assert(p); + + memcpy(p,stream_pkt , header_size); + /* TBD repace the mac if req we should add flag */ + m_core->m_node_gen.m_v_if->update_mac_addr_from_global_cfg(dir, p); + } + CDpOneStream one_stream; @@ -597,11 +699,11 @@ TrexStatelessDpCore::pause_traffic(uint8_t port_id){ } void -TrexStatelessDpCore::update_traffic(uint8_t port_id, double mul) { +TrexStatelessDpCore::update_traffic(uint8_t port_id, double factor) { TrexStatelessDpPerPort * lp_port = get_port_db(port_id); - lp_port->update_traffic(port_id, mul); + lp_port->update_traffic(port_id, factor); } diff --git a/src/stateless/dp/trex_stateless_dp_core.h b/src/stateless/dp/trex_stateless_dp_core.h index 563159b2..7dc4a2b2 100644 --- a/src/stateless/dp/trex_stateless_dp_core.h +++ b/src/stateless/dp/trex_stateless_dp_core.h @@ -68,7 +68,7 @@ public: bool resume_traffic(uint8_t port_id); - bool update_traffic(uint8_t port_id, double mul); + bool update_traffic(uint8_t port_id, double factor); bool stop_traffic(uint8_t port_id, bool stop_on_id, diff --git a/src/stateless/dp/trex_stream_node.h b/src/stateless/dp/trex_stream_node.h index 5997376f..d33785fe 100644 --- a/src/stateless/dp/trex_stream_node.h +++ b/src/stateless/dp/trex_stream_node.h @@ -54,6 +54,16 @@ struct CGenNodeStateless : public CGenNodeBase { friend class TrexStatelessDpCore; public: + + /* flags MASKS*/ + enum { + SL_NODE_FLAGS_DIR =1, //USED by master + SL_NODE_FLAGS_MBUF_CACHE =2, //USED by master + + SL_NODE_CONST_MBUF =4 + + }; + enum { ss_FREE_RESUSE =1, /* should be free by scheduler */ ss_INACTIVE =2, /* will be active by other stream or stopped */ @@ -83,14 +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; - double m_base_pps; - /* pad to match the size of CGenNode */ - uint8_t m_pad_end[48]; + uint8_t * m_original_packet_data_prefix; /* pointer to the original first pointer 64/128/512 */ + + /* 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: @@ -105,8 +121,9 @@ public: * on the PPS and multiplier * */ - void set_multiplier(double mul) { - m_next_time_offset = 1.0 / (m_base_pps * mul) ; + void update_rate(double factor) { + /* update the inter packet gap */ + m_next_time_offset = m_next_time_offset / factor; } /* we restart the stream, schedule it using stream isg */ @@ -256,13 +273,51 @@ public: } inline rte_mbuf_t * get_cache_mbuf(){ - if ( m_flags &NODE_FLAGS_MBUF_CACHE ) { + if ( m_flags & NODE_FLAGS_MBUF_CACHE ) { + return ((rte_mbuf_t *)m_cache_mbuf); + }else{ + return ((rte_mbuf_t *)0); + } + } + + inline void set_const_mbuf(rte_mbuf_t * m){ + m_cache_mbuf=(void *)m; + m_flags |= SL_NODE_CONST_MBUF; + } + + inline rte_mbuf_t * get_const_mbuf(){ + if ( m_flags &SL_NODE_CONST_MBUF ) { return ((rte_mbuf_t *)m_cache_mbuf); }else{ return ((rte_mbuf_t *)0); } } + /* 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); + m_original_packet_data_prefix = (uint8_t *)malloc(size); + assert(m_original_packet_data_prefix); + } + + inline void free_prefix_header(){ + if (m_original_packet_data_prefix) { + free(m_original_packet_data_prefix); + } + } + + /* prefix headr could be 64/128/512 */ + inline void set_prefix_header_size(uint16_t size){ + m_src_port=size; + } + + inline uint16_t prefix_header_size(){ + return (m_src_port); + } + + + rte_mbuf_t * alloc_node_with_vm(); + void free_stl_node(); public: |