summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/bp_sim.cpp24
-rw-r--r--src/gtest/trex_stateless_gtest.cpp25
-rw-r--r--src/main_dpdk.cpp26
-rwxr-xr-xsrc/pal/linux/mbuf.h7
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_stream.cpp2
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.cpp90
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.h5
-rw-r--r--src/stateless/dp/trex_stream_node.h11
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();