DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [Pktgen] [PATCH] pktgen_setup_packets: fix race for packet header
@ 2015-09-09 14:22 Ilya Maximets
  2015-09-16  9:09 ` Ilya Maximets
  0 siblings, 1 reply; 7+ messages in thread
From: Ilya Maximets @ 2015-09-09 14:22 UTC (permalink / raw)
  To: dev, Keith Wiles; +Cc: Ilya Maximets, Dyasly Sergey

While pktgen_setup_packets() all threads of one port uses same
info->seq_pkt. This leads to constructing packets in the same memory region
(&pkt->hdr). As a result, pktgen_setup_packets generates random headers.

Fix that by making a local copy of info->seq_pkt and using it for
constructing of packets.

Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
---
 app/pktgen-arp.c  |  2 +-
 app/pktgen-cmds.c | 40 ++++++++++++++++++++--------------------
 app/pktgen-ipv4.c |  2 +-
 app/pktgen.c      | 39 +++++++++++++++++++++++++++------------
 app/pktgen.h      |  4 ++--
 app/t/pktgen.t.c  |  6 +++---
 6 files changed, 54 insertions(+), 39 deletions(-)

diff --git a/app/pktgen-arp.c b/app/pktgen-arp.c
index c378880..b7040d7 100644
--- a/app/pktgen-arp.c
+++ b/app/pktgen-arp.c
@@ -190,7 +190,7 @@ pktgen_process_arp( struct rte_mbuf * m, uint32_t pid, uint32_t vlan )
 
 				rte_memcpy(&pkt->eth_dst_addr, &arp->sha, 6);
 				for (i = 0; i < info->seqCnt; i++)
-					pktgen_packet_ctor(info, i, -1);
+					pktgen_packet_ctor(info, i, -1, NULL);
 			}
 
 			// Swap the two MAC addresses
diff --git a/app/pktgen-cmds.c b/app/pktgen-cmds.c
index da040e5..a6abb41 100644
--- a/app/pktgen-cmds.c
+++ b/app/pktgen-cmds.c
@@ -931,7 +931,7 @@ pktgen_set_proto(port_info_t * info, char type)
 	if ( type == 'i' )
 		info->seq_pkt[SINGLE_PKT].ethType = ETHER_TYPE_IPv4;
 
-	pktgen_packet_ctor(info, SINGLE_PKT, -1);
+	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
 }
 
 /**************************************************************************//**
@@ -1067,7 +1067,7 @@ pktgen_set_pkt_type(port_info_t * info, const char * type)
 										(type[3] == '6') ? ETHER_TYPE_IPv6 :
 										/* TODO print error: unknown type */ ETHER_TYPE_IPv4;
 
-	pktgen_packet_ctor(info, SINGLE_PKT, -1);
+	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
 }
 
 /**************************************************************************//**
@@ -1092,7 +1092,7 @@ pktgen_set_vlan(port_info_t * info, uint32_t onOff)
 	}
 	else
 		pktgen_clr_port_flags(info, SEND_VLAN_ID);
-	pktgen_packet_ctor(info, SINGLE_PKT, -1);
+	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
 }
 
 /**************************************************************************//**
@@ -1112,7 +1112,7 @@ pktgen_set_vlanid(port_info_t * info, uint16_t vlanid)
 {
 	info->vlanid = vlanid;
 	info->seq_pkt[SINGLE_PKT].vlanid = info->vlanid;
-	pktgen_packet_ctor(info, SINGLE_PKT, -1);
+	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
 }
 
 /**************************************************************************//**
@@ -1137,7 +1137,7 @@ pktgen_set_mpls(port_info_t * info, uint32_t onOff)
 	}
 	else
 		pktgen_clr_port_flags(info, SEND_MPLS_LABEL);
-	pktgen_packet_ctor(info, SINGLE_PKT, -1);
+	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
 }
 
 /**************************************************************************//**
@@ -1157,7 +1157,7 @@ pktgen_set_mpls_entry(port_info_t * info, uint32_t mpls_entry)
 {
 	info->mpls_entry = mpls_entry;
 	info->seq_pkt[SINGLE_PKT].mpls_entry = info->mpls_entry;
-	pktgen_packet_ctor(info, SINGLE_PKT, -1);
+	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
 }
 
 /**************************************************************************//**
@@ -1182,7 +1182,7 @@ pktgen_set_qinq(port_info_t * info, uint32_t onOff)
 	}
 	else
 		pktgen_clr_port_flags(info, SEND_Q_IN_Q_IDS);
-	pktgen_packet_ctor(info, SINGLE_PKT, -1);
+	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
 }
 
 /**************************************************************************//**
@@ -1204,7 +1204,7 @@ pktgen_set_qinqids(port_info_t * info, uint16_t outerid, uint16_t innerid)
 	info->seq_pkt[SINGLE_PKT].qinq_outerid = info->qinq_outerid;
 	info->qinq_innerid = innerid;
 	info->seq_pkt[SINGLE_PKT].qinq_innerid = info->qinq_innerid;
-	pktgen_packet_ctor(info, SINGLE_PKT, -1);
+	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
 }
 
 /**************************************************************************//**
@@ -1228,7 +1228,7 @@ pktgen_set_gre(port_info_t * info, uint32_t onOff)
 	}
 	else
 		pktgen_clr_port_flags(info, SEND_GRE_IPv4_HEADER);
-	pktgen_packet_ctor(info, SINGLE_PKT, -1);
+	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
 }
 
 /**************************************************************************//**
@@ -1252,7 +1252,7 @@ pktgen_set_gre_eth(port_info_t * info, uint32_t onOff)
 	}
 	else
 		pktgen_clr_port_flags(info, SEND_GRE_ETHER_HEADER);
-	pktgen_packet_ctor(info, SINGLE_PKT, -1);
+	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
 }
 
 /**************************************************************************//**
@@ -1272,7 +1272,7 @@ pktgen_set_gre_key(port_info_t * info, uint32_t gre_key)
 {
 	info->gre_key = gre_key;
 	info->seq_pkt[SINGLE_PKT].gre_key = info->gre_key;
-	pktgen_packet_ctor(info, SINGLE_PKT, -1);
+	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
 }
 
 /**************************************************************************//**
@@ -1401,7 +1401,7 @@ void pktgen_port_defaults(uint32_t pid, uint8_t seq)
 		memset(&pkt->eth_dst_addr, 0, sizeof (pkt->eth_dst_addr));
 
 
-	pktgen_packet_ctor(info, seq, -1);
+	pktgen_packet_ctor(info, seq, -1, NULL);
 
     pktgen.flags	|= PRINT_LABELS_FLAG;
 }
@@ -1423,7 +1423,7 @@ void pktgen_ping4(port_info_t * info)
 	memcpy(&info->seq_pkt[PING_PKT],
 		   &info->seq_pkt[SINGLE_PKT], sizeof(pkt_seq_t));
 	info->seq_pkt[PING_PKT].ipProto = PG_IPPROTO_ICMP;
-	pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO);
+	pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO, NULL);
 	pktgen_set_port_flags(info, SEND_PING4_REQUEST);
 }
 
@@ -1445,7 +1445,7 @@ void pktgen_ping6(port_info_t * info)
 	memcpy(&info->pkt[PING_PKT],
 		   &info->pkt[SINGLE_PKT], sizeof(pkt_seq_t));
 	info->pkt[PING_PKT].ipProto = PG_IPPROTO_ICMP;
-	pktgen_packet_ctor(info, PING_PKT, ICMP6_ECHO);
+	pktgen_packet_ctor(info, PING_PKT, ICMP6_ECHO, NULL);
 	pktgen_set_port_flags(info, SEND_PING6_REQUEST);
 }
 #endif
@@ -1645,7 +1645,7 @@ void pktgen_set_pkt_size(port_info_t * info, uint32_t size)
 	else if ( (size - FCS_SIZE) > MAX_PKT_SIZE)
 		size = MAX_PKT_SIZE + FCS_SIZE;
 	info->seq_pkt[SINGLE_PKT].pktSize = (size - FCS_SIZE);
-	pktgen_packet_ctor(info, SINGLE_PKT, -1);
+	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
 	pktgen_packet_rate(info);
 }
 
@@ -1667,7 +1667,7 @@ void pktgen_set_port_value(port_info_t * info, char type, uint32_t portValue)
 		info->seq_pkt[SINGLE_PKT].dport = (uint16_t)portValue;
 	else
 		info->seq_pkt[SINGLE_PKT].sport = (uint16_t)portValue;
-	pktgen_packet_ctor(info, SINGLE_PKT, -1);
+	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
 }
 
 /**************************************************************************//**
@@ -1711,7 +1711,7 @@ void pktgen_set_ipaddr(port_info_t * info, char type, cmdline_ipaddr_t * ip)
 		info->seq_pkt[SINGLE_PKT].ip_src_addr = ntohl(ip->addr.ipv4.s_addr);
 	} else
 		info->seq_pkt[SINGLE_PKT].ip_dst_addr = ntohl(ip->addr.ipv4.s_addr);
-	pktgen_packet_ctor(info, SINGLE_PKT, -1);
+	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
 }
 
 /**************************************************************************//**
@@ -1729,7 +1729,7 @@ void pktgen_set_ipaddr(port_info_t * info, char type, cmdline_ipaddr_t * ip)
 void pktgen_set_dst_mac(port_info_t * info, cmdline_etheraddr_t * mac)
 {
 	memcpy(&info->seq_pkt[SINGLE_PKT].eth_dst_addr, mac->mac, 6);
-	pktgen_packet_ctor(info, SINGLE_PKT, -1);
+	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
 }
 
 /**************************************************************************//**
@@ -2111,7 +2111,7 @@ void pktgen_set_seq(port_info_t * info, uint32_t seqnum,
 		type = '4';
 	pkt->ethType		= (type == '6')? ETHER_TYPE_IPv6 : ETHER_TYPE_IPv4;
 	pkt->vlanid			= vlanid;
-	pktgen_packet_ctor(info, seqnum, -1);
+	pktgen_packet_ctor(info, seqnum, -1, NULL);
 }
 
 /**************************************************************************//**
@@ -2156,7 +2156,7 @@ void pktgen_compile_pkt(port_info_t * info, uint32_t seqnum,
 						  (type == '6')? ETHER_TYPE_IPv6 :
 						  (type == 'n')? ETHER_TYPE_VLAN : ETHER_TYPE_IPv4;
 	pkt->vlanid			= vlanid;
-	pktgen_packet_ctor(info, seqnum, -1);
+	pktgen_packet_ctor(info, seqnum, -1, NULL);
 }
 
 /**************************************************************************//**
diff --git a/app/pktgen-ipv4.c b/app/pktgen-ipv4.c
index 7813c36..a8b6be2 100644
--- a/app/pktgen-ipv4.c
+++ b/app/pktgen-ipv4.c
@@ -138,7 +138,7 @@ pktgen_send_ping4( uint32_t pid, uint8_t seq_idx )
         return;
     }
 	*ppkt = *spkt;		// Copy the sequence setup to the ping setup.
-    pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO);
+    pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO, NULL);
 	rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t *)&ppkt->hdr, ppkt->pktSize);
 
     m->pkt_len  = ppkt->pktSize;
diff --git a/app/pktgen.c b/app/pktgen.c
index 2dcdbfd..ecd4560 100644
--- a/app/pktgen.c
+++ b/app/pktgen.c
@@ -401,8 +401,8 @@ static __inline__ int pktgen_has_work(void) {
 */
 
 void
-pktgen_packet_ctor(port_info_t * info, int32_t seq_idx, int32_t type) {
-	pkt_seq_t		  * pkt = &info->seq_pkt[seq_idx];
+pktgen_packet_ctor(port_info_t * info, int32_t seq_idx, int32_t type, pkt_seq_t * seq_pkt) {
+	pkt_seq_t		  * pkt = (seq_pkt == NULL) ? &info->seq_pkt[seq_idx] : &seq_pkt[seq_idx];
 	struct ether_hdr  * eth = (struct ether_hdr *)&pkt->hdr.eth;
 	uint16_t			tlen;
 
@@ -812,22 +812,35 @@ static __inline__ void
 pktgen_setup_packets(port_info_t * info, struct rte_mempool * mp, uint16_t qid)
 {
 	struct rte_mbuf	* m, * mm;
-	pkt_seq_t * pkt;
+	pkt_seq_t * pkt, * seq_pkt = NULL;
+	uint16_t seqIdx;
+	char buff[RTE_MEMZONE_NAMESIZE];
 
 	pktgen_clr_q_flags(info, qid, CLEAR_FAST_ALLOC_FLAG);
 
 	if ( mp == info->q[qid].pcap_mp )
 		return;
 
+	snprintf(buff, sizeof(buff), "tmp_seq_pkt_%d_%d", info->pid, qid);
+	seq_pkt = (pkt_seq_t *)rte_zmalloc(buff,
+				(sizeof(pkt_seq_t) * NUM_TOTAL_PKTS), RTE_CACHE_LINE_SIZE);
+	if (seq_pkt == NULL)
+		pktgen_log_panic("Unable to allocate %d pkt_seq_t headers",
+						 NUM_TOTAL_PKTS);
+	/* Copy global configuration to construct new packets locally */
+	rte_memcpy((uint8_t *)seq_pkt, (uint8_t *)info->seq_pkt,
+			   sizeof(pkt_seq_t) * NUM_TOTAL_PKTS);
+	seqIdx = info->seqIdx;
+
 	mm	= NULL;
 	pkt = NULL;
 
 	if ( mp == info->q[qid].tx_mp )
-		pkt = &info->seq_pkt[SINGLE_PKT];
+		pkt = &seq_pkt[SINGLE_PKT];
 	else if ( mp == info->q[qid].range_mp )
-		pkt = &info->seq_pkt[RANGE_PKT];
+		pkt = &seq_pkt[RANGE_PKT];
 	else if ( mp == info->q[qid].seq_mp )
-		pkt = &info->seq_pkt[info->seqIdx];
+		pkt = &seq_pkt[seqIdx];
 
 	// allocate each mbuf and put them on a list to be freed.
 	for(;;) {
@@ -840,7 +853,7 @@ pktgen_setup_packets(port_info_t * info, struct rte_mempool * mp, uint16_t qid)
 		mm = m;
 
 		if ( mp == info->q[qid].tx_mp ) {
-			pktgen_packet_ctor(info, SINGLE_PKT, -1);
+			pktgen_packet_ctor(info, SINGLE_PKT, -1, seq_pkt);
 
 			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t *)&pkt->hdr, MAX_PKT_SIZE);
 
@@ -848,16 +861,16 @@ pktgen_setup_packets(port_info_t * info, struct rte_mempool * mp, uint16_t qid)
 			m->data_len = pkt->pktSize;
 		} else if ( mp == info->q[qid].range_mp ) {
 			pktgen_range_ctor(&info->range, pkt);
-			pktgen_packet_ctor(info, RANGE_PKT, -1);
+			pktgen_packet_ctor(info, RANGE_PKT, -1, seq_pkt);
 
 			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t *)&pkt->hdr, MAX_PKT_SIZE);
 
 			m->pkt_len  = pkt->pktSize;
 			m->data_len = pkt->pktSize;
 		} else if ( mp == info->q[qid].seq_mp ) {
-			pktgen_packet_ctor(info, info->seqIdx++, -1);
-			if ( unlikely(info->seqIdx >= info->seqCnt) )
-				info->seqIdx = 0;
+			pktgen_packet_ctor(info, seqIdx++, -1, seq_pkt);
+			if ( unlikely(seqIdx >= info->seqCnt) )
+				seqIdx = 0;
 
 			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t *)&pkt->hdr, MAX_PKT_SIZE);
 
@@ -865,12 +878,14 @@ pktgen_setup_packets(port_info_t * info, struct rte_mempool * mp, uint16_t qid)
 			m->data_len = pkt->pktSize;
 
 			// move to the next packet in the sequence.
-			pkt = &info->seq_pkt[info->seqIdx];
+			pkt = &seq_pkt[seqIdx];
 		}
 	}
 
 	if ( mm != NULL )
 		rte_pktmbuf_free(mm);
+
+	rte_free(seq_pkt);
 }
 
 /**************************************************************************//**
diff --git a/app/pktgen.h b/app/pktgen.h
index 2c5c98c..f3f76f2 100644
--- a/app/pktgen.h
+++ b/app/pktgen.h
@@ -151,7 +151,7 @@
 #include "pktgen-port-cfg.h"
 #include "pktgen-capture.h"
 #include "pktgen-log.h"
-
+#include "pktgen-seq.h"
 
 #define PKTGEN_VERSION			"2.9.2"
 #define PKTGEN_APP_NAME			"Pktgen"
@@ -386,7 +386,7 @@ extern pktgen_t		pktgen;
 
 extern void pktgen_page_display(__attribute__((unused)) struct rte_timer *tim, __attribute__((unused)) void *arg);
 
-extern void pktgen_packet_ctor(port_info_t * info, int32_t seq_idx, int32_t type);
+extern void pktgen_packet_ctor(port_info_t * info, int32_t seq_idx, int32_t type, pkt_seq_t * seq_pkt);
 extern void pktgen_packet_rate(port_info_t * info);
 
 extern void pktgen_send_mbuf(struct rte_mbuf *m, uint8_t pid, uint16_t qid);
diff --git a/app/t/pktgen.t.c b/app/t/pktgen.t.c
index 0eca4c4..77bf300 100644
--- a/app/t/pktgen.t.c
+++ b/app/t/pktgen.t.c
@@ -77,7 +77,7 @@ void test_pktgen_packet_ctor_IPv4_UDP(void)
 	};
 
 
-	lives_ok( { pktgen_packet_ctor(&info, 0, 0); }, "pktgen_packet_ctor must generate IPv4/UDP");
+	lives_ok( { pktgen_packet_ctor(&info, 0, 0, NULL); }, "pktgen_packet_ctor must generate IPv4/UDP");
 
 	note("... with Ethernet header");
 	cmp_mem_lit_incr(data, (0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd), "    ... with correct dest MAC");
@@ -133,9 +133,9 @@ void test_pktgen_packet_ctor_IPv4_GRE_Ether(void)
 		.pktSize      = 102,		// Subtract 4 for FCS
 	};
 
-	pktgen_packet_ctor(&info, 0, 0);
+	pktgen_packet_ctor(&info, 0, 0, NULL);
 
-	lives_ok( { pktgen_packet_ctor(&info, 0, 0); }, "pktgen_packet_ctor must generate IPv4 GRE Ethernet frame");
+	lives_ok( { pktgen_packet_ctor(&info, 0, 0, NULL); }, "pktgen_packet_ctor must generate IPv4 GRE Ethernet frame");
 
 	note("... with outer Ethernet header");
 	cmp_mem_lit_incr(data, (0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd), "    ... with correct dest MAC");
-- 
2.1.4

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [dpdk-dev] [Pktgen] [PATCH] pktgen_setup_packets: fix race for packet header
  2015-09-09 14:22 [dpdk-dev] [Pktgen] [PATCH] pktgen_setup_packets: fix race for packet header Ilya Maximets
@ 2015-09-16  9:09 ` Ilya Maximets
  2015-09-16 15:37   ` Wiles, Keith
  0 siblings, 1 reply; 7+ messages in thread
From: Ilya Maximets @ 2015-09-16  9:09 UTC (permalink / raw)
  To: dev, Keith Wiles; +Cc: Dyasly Sergey

Ping.

On 09.09.2015 17:22, Ilya Maximets wrote:
> While pktgen_setup_packets() all threads of one port uses same
> info->seq_pkt. This leads to constructing packets in the same memory region
> (&pkt->hdr). As a result, pktgen_setup_packets generates random headers.
> 
> Fix that by making a local copy of info->seq_pkt and using it for
> constructing of packets.
> 
> Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
> ---
>  app/pktgen-arp.c  |  2 +-
>  app/pktgen-cmds.c | 40 ++++++++++++++++++++--------------------
>  app/pktgen-ipv4.c |  2 +-
>  app/pktgen.c      | 39 +++++++++++++++++++++++++++------------
>  app/pktgen.h      |  4 ++--
>  app/t/pktgen.t.c  |  6 +++---
>  6 files changed, 54 insertions(+), 39 deletions(-)
> 
> diff --git a/app/pktgen-arp.c b/app/pktgen-arp.c
> index c378880..b7040d7 100644
> --- a/app/pktgen-arp.c
> +++ b/app/pktgen-arp.c
> @@ -190,7 +190,7 @@ pktgen_process_arp( struct rte_mbuf * m, uint32_t pid, uint32_t vlan )
>  
>  				rte_memcpy(&pkt->eth_dst_addr, &arp->sha, 6);
>  				for (i = 0; i < info->seqCnt; i++)
> -					pktgen_packet_ctor(info, i, -1);
> +					pktgen_packet_ctor(info, i, -1, NULL);
>  			}
>  
>  			// Swap the two MAC addresses
> diff --git a/app/pktgen-cmds.c b/app/pktgen-cmds.c
> index da040e5..a6abb41 100644
> --- a/app/pktgen-cmds.c
> +++ b/app/pktgen-cmds.c
> @@ -931,7 +931,7 @@ pktgen_set_proto(port_info_t * info, char type)
>  	if ( type == 'i' )
>  		info->seq_pkt[SINGLE_PKT].ethType = ETHER_TYPE_IPv4;
>  
> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>  }
>  
>  /**************************************************************************//**
> @@ -1067,7 +1067,7 @@ pktgen_set_pkt_type(port_info_t * info, const char * type)
>  										(type[3] == '6') ? ETHER_TYPE_IPv6 :
>  										/* TODO print error: unknown type */ ETHER_TYPE_IPv4;
>  
> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>  }
>  
>  /**************************************************************************//**
> @@ -1092,7 +1092,7 @@ pktgen_set_vlan(port_info_t * info, uint32_t onOff)
>  	}
>  	else
>  		pktgen_clr_port_flags(info, SEND_VLAN_ID);
> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>  }
>  
>  /**************************************************************************//**
> @@ -1112,7 +1112,7 @@ pktgen_set_vlanid(port_info_t * info, uint16_t vlanid)
>  {
>  	info->vlanid = vlanid;
>  	info->seq_pkt[SINGLE_PKT].vlanid = info->vlanid;
> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>  }
>  
>  /**************************************************************************//**
> @@ -1137,7 +1137,7 @@ pktgen_set_mpls(port_info_t * info, uint32_t onOff)
>  	}
>  	else
>  		pktgen_clr_port_flags(info, SEND_MPLS_LABEL);
> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>  }
>  
>  /**************************************************************************//**
> @@ -1157,7 +1157,7 @@ pktgen_set_mpls_entry(port_info_t * info, uint32_t mpls_entry)
>  {
>  	info->mpls_entry = mpls_entry;
>  	info->seq_pkt[SINGLE_PKT].mpls_entry = info->mpls_entry;
> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>  }
>  
>  /**************************************************************************//**
> @@ -1182,7 +1182,7 @@ pktgen_set_qinq(port_info_t * info, uint32_t onOff)
>  	}
>  	else
>  		pktgen_clr_port_flags(info, SEND_Q_IN_Q_IDS);
> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>  }
>  
>  /**************************************************************************//**
> @@ -1204,7 +1204,7 @@ pktgen_set_qinqids(port_info_t * info, uint16_t outerid, uint16_t innerid)
>  	info->seq_pkt[SINGLE_PKT].qinq_outerid = info->qinq_outerid;
>  	info->qinq_innerid = innerid;
>  	info->seq_pkt[SINGLE_PKT].qinq_innerid = info->qinq_innerid;
> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>  }
>  
>  /**************************************************************************//**
> @@ -1228,7 +1228,7 @@ pktgen_set_gre(port_info_t * info, uint32_t onOff)
>  	}
>  	else
>  		pktgen_clr_port_flags(info, SEND_GRE_IPv4_HEADER);
> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>  }
>  
>  /**************************************************************************//**
> @@ -1252,7 +1252,7 @@ pktgen_set_gre_eth(port_info_t * info, uint32_t onOff)
>  	}
>  	else
>  		pktgen_clr_port_flags(info, SEND_GRE_ETHER_HEADER);
> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>  }
>  
>  /**************************************************************************//**
> @@ -1272,7 +1272,7 @@ pktgen_set_gre_key(port_info_t * info, uint32_t gre_key)
>  {
>  	info->gre_key = gre_key;
>  	info->seq_pkt[SINGLE_PKT].gre_key = info->gre_key;
> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>  }
>  
>  /**************************************************************************//**
> @@ -1401,7 +1401,7 @@ void pktgen_port_defaults(uint32_t pid, uint8_t seq)
>  		memset(&pkt->eth_dst_addr, 0, sizeof (pkt->eth_dst_addr));
>  
>  
> -	pktgen_packet_ctor(info, seq, -1);
> +	pktgen_packet_ctor(info, seq, -1, NULL);
>  
>      pktgen.flags	|= PRINT_LABELS_FLAG;
>  }
> @@ -1423,7 +1423,7 @@ void pktgen_ping4(port_info_t * info)
>  	memcpy(&info->seq_pkt[PING_PKT],
>  		   &info->seq_pkt[SINGLE_PKT], sizeof(pkt_seq_t));
>  	info->seq_pkt[PING_PKT].ipProto = PG_IPPROTO_ICMP;
> -	pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO);
> +	pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO, NULL);
>  	pktgen_set_port_flags(info, SEND_PING4_REQUEST);
>  }
>  
> @@ -1445,7 +1445,7 @@ void pktgen_ping6(port_info_t * info)
>  	memcpy(&info->pkt[PING_PKT],
>  		   &info->pkt[SINGLE_PKT], sizeof(pkt_seq_t));
>  	info->pkt[PING_PKT].ipProto = PG_IPPROTO_ICMP;
> -	pktgen_packet_ctor(info, PING_PKT, ICMP6_ECHO);
> +	pktgen_packet_ctor(info, PING_PKT, ICMP6_ECHO, NULL);
>  	pktgen_set_port_flags(info, SEND_PING6_REQUEST);
>  }
>  #endif
> @@ -1645,7 +1645,7 @@ void pktgen_set_pkt_size(port_info_t * info, uint32_t size)
>  	else if ( (size - FCS_SIZE) > MAX_PKT_SIZE)
>  		size = MAX_PKT_SIZE + FCS_SIZE;
>  	info->seq_pkt[SINGLE_PKT].pktSize = (size - FCS_SIZE);
> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>  	pktgen_packet_rate(info);
>  }
>  
> @@ -1667,7 +1667,7 @@ void pktgen_set_port_value(port_info_t * info, char type, uint32_t portValue)
>  		info->seq_pkt[SINGLE_PKT].dport = (uint16_t)portValue;
>  	else
>  		info->seq_pkt[SINGLE_PKT].sport = (uint16_t)portValue;
> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>  }
>  
>  /**************************************************************************//**
> @@ -1711,7 +1711,7 @@ void pktgen_set_ipaddr(port_info_t * info, char type, cmdline_ipaddr_t * ip)
>  		info->seq_pkt[SINGLE_PKT].ip_src_addr = ntohl(ip->addr.ipv4.s_addr);
>  	} else
>  		info->seq_pkt[SINGLE_PKT].ip_dst_addr = ntohl(ip->addr.ipv4.s_addr);
> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>  }
>  
>  /**************************************************************************//**
> @@ -1729,7 +1729,7 @@ void pktgen_set_ipaddr(port_info_t * info, char type, cmdline_ipaddr_t * ip)
>  void pktgen_set_dst_mac(port_info_t * info, cmdline_etheraddr_t * mac)
>  {
>  	memcpy(&info->seq_pkt[SINGLE_PKT].eth_dst_addr, mac->mac, 6);
> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>  }
>  
>  /**************************************************************************//**
> @@ -2111,7 +2111,7 @@ void pktgen_set_seq(port_info_t * info, uint32_t seqnum,
>  		type = '4';
>  	pkt->ethType		= (type == '6')? ETHER_TYPE_IPv6 : ETHER_TYPE_IPv4;
>  	pkt->vlanid			= vlanid;
> -	pktgen_packet_ctor(info, seqnum, -1);
> +	pktgen_packet_ctor(info, seqnum, -1, NULL);
>  }
>  
>  /**************************************************************************//**
> @@ -2156,7 +2156,7 @@ void pktgen_compile_pkt(port_info_t * info, uint32_t seqnum,
>  						  (type == '6')? ETHER_TYPE_IPv6 :
>  						  (type == 'n')? ETHER_TYPE_VLAN : ETHER_TYPE_IPv4;
>  	pkt->vlanid			= vlanid;
> -	pktgen_packet_ctor(info, seqnum, -1);
> +	pktgen_packet_ctor(info, seqnum, -1, NULL);
>  }
>  
>  /**************************************************************************//**
> diff --git a/app/pktgen-ipv4.c b/app/pktgen-ipv4.c
> index 7813c36..a8b6be2 100644
> --- a/app/pktgen-ipv4.c
> +++ b/app/pktgen-ipv4.c
> @@ -138,7 +138,7 @@ pktgen_send_ping4( uint32_t pid, uint8_t seq_idx )
>          return;
>      }
>  	*ppkt = *spkt;		// Copy the sequence setup to the ping setup.
> -    pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO);
> +    pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO, NULL);
>  	rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t *)&ppkt->hdr, ppkt->pktSize);
>  
>      m->pkt_len  = ppkt->pktSize;
> diff --git a/app/pktgen.c b/app/pktgen.c
> index 2dcdbfd..ecd4560 100644
> --- a/app/pktgen.c
> +++ b/app/pktgen.c
> @@ -401,8 +401,8 @@ static __inline__ int pktgen_has_work(void) {
>  */
>  
>  void
> -pktgen_packet_ctor(port_info_t * info, int32_t seq_idx, int32_t type) {
> -	pkt_seq_t		  * pkt = &info->seq_pkt[seq_idx];
> +pktgen_packet_ctor(port_info_t * info, int32_t seq_idx, int32_t type, pkt_seq_t * seq_pkt) {
> +	pkt_seq_t		  * pkt = (seq_pkt == NULL) ? &info->seq_pkt[seq_idx] : &seq_pkt[seq_idx];
>  	struct ether_hdr  * eth = (struct ether_hdr *)&pkt->hdr.eth;
>  	uint16_t			tlen;
>  
> @@ -812,22 +812,35 @@ static __inline__ void
>  pktgen_setup_packets(port_info_t * info, struct rte_mempool * mp, uint16_t qid)
>  {
>  	struct rte_mbuf	* m, * mm;
> -	pkt_seq_t * pkt;
> +	pkt_seq_t * pkt, * seq_pkt = NULL;
> +	uint16_t seqIdx;
> +	char buff[RTE_MEMZONE_NAMESIZE];
>  
>  	pktgen_clr_q_flags(info, qid, CLEAR_FAST_ALLOC_FLAG);
>  
>  	if ( mp == info->q[qid].pcap_mp )
>  		return;
>  
> +	snprintf(buff, sizeof(buff), "tmp_seq_pkt_%d_%d", info->pid, qid);
> +	seq_pkt = (pkt_seq_t *)rte_zmalloc(buff,
> +				(sizeof(pkt_seq_t) * NUM_TOTAL_PKTS), RTE_CACHE_LINE_SIZE);
> +	if (seq_pkt == NULL)
> +		pktgen_log_panic("Unable to allocate %d pkt_seq_t headers",
> +						 NUM_TOTAL_PKTS);
> +	/* Copy global configuration to construct new packets locally */
> +	rte_memcpy((uint8_t *)seq_pkt, (uint8_t *)info->seq_pkt,
> +			   sizeof(pkt_seq_t) * NUM_TOTAL_PKTS);
> +	seqIdx = info->seqIdx;
> +
>  	mm	= NULL;
>  	pkt = NULL;
>  
>  	if ( mp == info->q[qid].tx_mp )
> -		pkt = &info->seq_pkt[SINGLE_PKT];
> +		pkt = &seq_pkt[SINGLE_PKT];
>  	else if ( mp == info->q[qid].range_mp )
> -		pkt = &info->seq_pkt[RANGE_PKT];
> +		pkt = &seq_pkt[RANGE_PKT];
>  	else if ( mp == info->q[qid].seq_mp )
> -		pkt = &info->seq_pkt[info->seqIdx];
> +		pkt = &seq_pkt[seqIdx];
>  
>  	// allocate each mbuf and put them on a list to be freed.
>  	for(;;) {
> @@ -840,7 +853,7 @@ pktgen_setup_packets(port_info_t * info, struct rte_mempool * mp, uint16_t qid)
>  		mm = m;
>  
>  		if ( mp == info->q[qid].tx_mp ) {
> -			pktgen_packet_ctor(info, SINGLE_PKT, -1);
> +			pktgen_packet_ctor(info, SINGLE_PKT, -1, seq_pkt);
>  
>  			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t *)&pkt->hdr, MAX_PKT_SIZE);
>  
> @@ -848,16 +861,16 @@ pktgen_setup_packets(port_info_t * info, struct rte_mempool * mp, uint16_t qid)
>  			m->data_len = pkt->pktSize;
>  		} else if ( mp == info->q[qid].range_mp ) {
>  			pktgen_range_ctor(&info->range, pkt);
> -			pktgen_packet_ctor(info, RANGE_PKT, -1);
> +			pktgen_packet_ctor(info, RANGE_PKT, -1, seq_pkt);
>  
>  			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t *)&pkt->hdr, MAX_PKT_SIZE);
>  
>  			m->pkt_len  = pkt->pktSize;
>  			m->data_len = pkt->pktSize;
>  		} else if ( mp == info->q[qid].seq_mp ) {
> -			pktgen_packet_ctor(info, info->seqIdx++, -1);
> -			if ( unlikely(info->seqIdx >= info->seqCnt) )
> -				info->seqIdx = 0;
> +			pktgen_packet_ctor(info, seqIdx++, -1, seq_pkt);
> +			if ( unlikely(seqIdx >= info->seqCnt) )
> +				seqIdx = 0;
>  
>  			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t *)&pkt->hdr, MAX_PKT_SIZE);
>  
> @@ -865,12 +878,14 @@ pktgen_setup_packets(port_info_t * info, struct rte_mempool * mp, uint16_t qid)
>  			m->data_len = pkt->pktSize;
>  
>  			// move to the next packet in the sequence.
> -			pkt = &info->seq_pkt[info->seqIdx];
> +			pkt = &seq_pkt[seqIdx];
>  		}
>  	}
>  
>  	if ( mm != NULL )
>  		rte_pktmbuf_free(mm);
> +
> +	rte_free(seq_pkt);
>  }
>  
>  /**************************************************************************//**
> diff --git a/app/pktgen.h b/app/pktgen.h
> index 2c5c98c..f3f76f2 100644
> --- a/app/pktgen.h
> +++ b/app/pktgen.h
> @@ -151,7 +151,7 @@
>  #include "pktgen-port-cfg.h"
>  #include "pktgen-capture.h"
>  #include "pktgen-log.h"
> -
> +#include "pktgen-seq.h"
>  
>  #define PKTGEN_VERSION			"2.9.2"
>  #define PKTGEN_APP_NAME			"Pktgen"
> @@ -386,7 +386,7 @@ extern pktgen_t		pktgen;
>  
>  extern void pktgen_page_display(__attribute__((unused)) struct rte_timer *tim, __attribute__((unused)) void *arg);
>  
> -extern void pktgen_packet_ctor(port_info_t * info, int32_t seq_idx, int32_t type);
> +extern void pktgen_packet_ctor(port_info_t * info, int32_t seq_idx, int32_t type, pkt_seq_t * seq_pkt);
>  extern void pktgen_packet_rate(port_info_t * info);
>  
>  extern void pktgen_send_mbuf(struct rte_mbuf *m, uint8_t pid, uint16_t qid);
> diff --git a/app/t/pktgen.t.c b/app/t/pktgen.t.c
> index 0eca4c4..77bf300 100644
> --- a/app/t/pktgen.t.c
> +++ b/app/t/pktgen.t.c
> @@ -77,7 +77,7 @@ void test_pktgen_packet_ctor_IPv4_UDP(void)
>  	};
>  
>  
> -	lives_ok( { pktgen_packet_ctor(&info, 0, 0); }, "pktgen_packet_ctor must generate IPv4/UDP");
> +	lives_ok( { pktgen_packet_ctor(&info, 0, 0, NULL); }, "pktgen_packet_ctor must generate IPv4/UDP");
>  
>  	note("... with Ethernet header");
>  	cmp_mem_lit_incr(data, (0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd), "    ... with correct dest MAC");
> @@ -133,9 +133,9 @@ void test_pktgen_packet_ctor_IPv4_GRE_Ether(void)
>  		.pktSize      = 102,		// Subtract 4 for FCS
>  	};
>  
> -	pktgen_packet_ctor(&info, 0, 0);
> +	pktgen_packet_ctor(&info, 0, 0, NULL);
>  
> -	lives_ok( { pktgen_packet_ctor(&info, 0, 0); }, "pktgen_packet_ctor must generate IPv4 GRE Ethernet frame");
> +	lives_ok( { pktgen_packet_ctor(&info, 0, 0, NULL); }, "pktgen_packet_ctor must generate IPv4 GRE Ethernet frame");
>  
>  	note("... with outer Ethernet header");
>  	cmp_mem_lit_incr(data, (0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd), "    ... with correct dest MAC");
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [dpdk-dev] [Pktgen] [PATCH] pktgen_setup_packets: fix race for packet header
  2015-09-16  9:09 ` Ilya Maximets
@ 2015-09-16 15:37   ` Wiles, Keith
  2015-09-17  5:55     ` Ilya Maximets
  0 siblings, 1 reply; 7+ messages in thread
From: Wiles, Keith @ 2015-09-16 15:37 UTC (permalink / raw)
  To: Ilya Maximets, dev; +Cc: Dyasly Sergey

Thanks the patch looks fine, but I have not had a lot of time to review it
detail. I hope to get to it next week after I return back home.

On 9/16/15, 2:09 AM, "Ilya Maximets" <i.maximets@samsung.com> wrote:

>Ping.
>
>On 09.09.2015 17:22, Ilya Maximets wrote:
>> While pktgen_setup_packets() all threads of one port uses same
>> info->seq_pkt. This leads to constructing packets in the same memory
>>region
>> (&pkt->hdr). As a result, pktgen_setup_packets generates random headers.
>> 
>> Fix that by making a local copy of info->seq_pkt and using it for
>> constructing of packets.
>> 
>> Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
>> ---
>>  app/pktgen-arp.c  |  2 +-
>>  app/pktgen-cmds.c | 40 ++++++++++++++++++++--------------------
>>  app/pktgen-ipv4.c |  2 +-
>>  app/pktgen.c      | 39 +++++++++++++++++++++++++++------------
>>  app/pktgen.h      |  4 ++--
>>  app/t/pktgen.t.c  |  6 +++---
>>  6 files changed, 54 insertions(+), 39 deletions(-)
>> 
>> diff --git a/app/pktgen-arp.c b/app/pktgen-arp.c
>> index c378880..b7040d7 100644
>> --- a/app/pktgen-arp.c
>> +++ b/app/pktgen-arp.c
>> @@ -190,7 +190,7 @@ pktgen_process_arp( struct rte_mbuf * m, uint32_t
>>pid, uint32_t vlan )
>>  
>>  				rte_memcpy(&pkt->eth_dst_addr, &arp->sha, 6);
>>  				for (i = 0; i < info->seqCnt; i++)
>> -					pktgen_packet_ctor(info, i, -1);
>> +					pktgen_packet_ctor(info, i, -1, NULL);
>>  			}
>>  
>>  			// Swap the two MAC addresses
>> diff --git a/app/pktgen-cmds.c b/app/pktgen-cmds.c
>> index da040e5..a6abb41 100644
>> --- a/app/pktgen-cmds.c
>> +++ b/app/pktgen-cmds.c
>> @@ -931,7 +931,7 @@ pktgen_set_proto(port_info_t * info, char type)
>>  	if ( type == 'i' )
>>  		info->seq_pkt[SINGLE_PKT].ethType = ETHER_TYPE_IPv4;
>>  
>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>  }
>>  
>>  
>>/************************************************************************
>>**//**
>> @@ -1067,7 +1067,7 @@ pktgen_set_pkt_type(port_info_t * info, const
>>char * type)
>>  										(type[3] == '6') ? ETHER_TYPE_IPv6 :
>>  										/* TODO print error: unknown type */ ETHER_TYPE_IPv4;
>>  
>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>  }
>>  
>>  
>>/************************************************************************
>>**//**
>> @@ -1092,7 +1092,7 @@ pktgen_set_vlan(port_info_t * info, uint32_t
>>onOff)
>>  	}
>>  	else
>>  		pktgen_clr_port_flags(info, SEND_VLAN_ID);
>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>  }
>>  
>>  
>>/************************************************************************
>>**//**
>> @@ -1112,7 +1112,7 @@ pktgen_set_vlanid(port_info_t * info, uint16_t
>>vlanid)
>>  {
>>  	info->vlanid = vlanid;
>>  	info->seq_pkt[SINGLE_PKT].vlanid = info->vlanid;
>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>  }
>>  
>>  
>>/************************************************************************
>>**//**
>> @@ -1137,7 +1137,7 @@ pktgen_set_mpls(port_info_t * info, uint32_t
>>onOff)
>>  	}
>>  	else
>>  		pktgen_clr_port_flags(info, SEND_MPLS_LABEL);
>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>  }
>>  
>>  
>>/************************************************************************
>>**//**
>> @@ -1157,7 +1157,7 @@ pktgen_set_mpls_entry(port_info_t * info,
>>uint32_t mpls_entry)
>>  {
>>  	info->mpls_entry = mpls_entry;
>>  	info->seq_pkt[SINGLE_PKT].mpls_entry = info->mpls_entry;
>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>  }
>>  
>>  
>>/************************************************************************
>>**//**
>> @@ -1182,7 +1182,7 @@ pktgen_set_qinq(port_info_t * info, uint32_t
>>onOff)
>>  	}
>>  	else
>>  		pktgen_clr_port_flags(info, SEND_Q_IN_Q_IDS);
>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>  }
>>  
>>  
>>/************************************************************************
>>**//**
>> @@ -1204,7 +1204,7 @@ pktgen_set_qinqids(port_info_t * info, uint16_t
>>outerid, uint16_t innerid)
>>  	info->seq_pkt[SINGLE_PKT].qinq_outerid = info->qinq_outerid;
>>  	info->qinq_innerid = innerid;
>>  	info->seq_pkt[SINGLE_PKT].qinq_innerid = info->qinq_innerid;
>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>  }
>>  
>>  
>>/************************************************************************
>>**//**
>> @@ -1228,7 +1228,7 @@ pktgen_set_gre(port_info_t * info, uint32_t onOff)
>>  	}
>>  	else
>>  		pktgen_clr_port_flags(info, SEND_GRE_IPv4_HEADER);
>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>  }
>>  
>>  
>>/************************************************************************
>>**//**
>> @@ -1252,7 +1252,7 @@ pktgen_set_gre_eth(port_info_t * info, uint32_t
>>onOff)
>>  	}
>>  	else
>>  		pktgen_clr_port_flags(info, SEND_GRE_ETHER_HEADER);
>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>  }
>>  
>>  
>>/************************************************************************
>>**//**
>> @@ -1272,7 +1272,7 @@ pktgen_set_gre_key(port_info_t * info, uint32_t
>>gre_key)
>>  {
>>  	info->gre_key = gre_key;
>>  	info->seq_pkt[SINGLE_PKT].gre_key = info->gre_key;
>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>  }
>>  
>>  
>>/************************************************************************
>>**//**
>> @@ -1401,7 +1401,7 @@ void pktgen_port_defaults(uint32_t pid, uint8_t
>>seq)
>>  		memset(&pkt->eth_dst_addr, 0, sizeof (pkt->eth_dst_addr));
>>  
>>  
>> -	pktgen_packet_ctor(info, seq, -1);
>> +	pktgen_packet_ctor(info, seq, -1, NULL);
>>  
>>      pktgen.flags	|= PRINT_LABELS_FLAG;
>>  }
>> @@ -1423,7 +1423,7 @@ void pktgen_ping4(port_info_t * info)
>>  	memcpy(&info->seq_pkt[PING_PKT],
>>  		   &info->seq_pkt[SINGLE_PKT], sizeof(pkt_seq_t));
>>  	info->seq_pkt[PING_PKT].ipProto = PG_IPPROTO_ICMP;
>> -	pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO);
>> +	pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO, NULL);
>>  	pktgen_set_port_flags(info, SEND_PING4_REQUEST);
>>  }
>>  
>> @@ -1445,7 +1445,7 @@ void pktgen_ping6(port_info_t * info)
>>  	memcpy(&info->pkt[PING_PKT],
>>  		   &info->pkt[SINGLE_PKT], sizeof(pkt_seq_t));
>>  	info->pkt[PING_PKT].ipProto = PG_IPPROTO_ICMP;
>> -	pktgen_packet_ctor(info, PING_PKT, ICMP6_ECHO);
>> +	pktgen_packet_ctor(info, PING_PKT, ICMP6_ECHO, NULL);
>>  	pktgen_set_port_flags(info, SEND_PING6_REQUEST);
>>  }
>>  #endif
>> @@ -1645,7 +1645,7 @@ void pktgen_set_pkt_size(port_info_t * info,
>>uint32_t size)
>>  	else if ( (size - FCS_SIZE) > MAX_PKT_SIZE)
>>  		size = MAX_PKT_SIZE + FCS_SIZE;
>>  	info->seq_pkt[SINGLE_PKT].pktSize = (size - FCS_SIZE);
>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>  	pktgen_packet_rate(info);
>>  }
>>  
>> @@ -1667,7 +1667,7 @@ void pktgen_set_port_value(port_info_t * info,
>>char type, uint32_t portValue)
>>  		info->seq_pkt[SINGLE_PKT].dport = (uint16_t)portValue;
>>  	else
>>  		info->seq_pkt[SINGLE_PKT].sport = (uint16_t)portValue;
>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>  }
>>  
>>  
>>/************************************************************************
>>**//**
>> @@ -1711,7 +1711,7 @@ void pktgen_set_ipaddr(port_info_t * info, char
>>type, cmdline_ipaddr_t * ip)
>>  		info->seq_pkt[SINGLE_PKT].ip_src_addr = ntohl(ip->addr.ipv4.s_addr);
>>  	} else
>>  		info->seq_pkt[SINGLE_PKT].ip_dst_addr = ntohl(ip->addr.ipv4.s_addr);
>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>  }
>>  
>>  
>>/************************************************************************
>>**//**
>> @@ -1729,7 +1729,7 @@ void pktgen_set_ipaddr(port_info_t * info, char
>>type, cmdline_ipaddr_t * ip)
>>  void pktgen_set_dst_mac(port_info_t * info, cmdline_etheraddr_t * mac)
>>  {
>>  	memcpy(&info->seq_pkt[SINGLE_PKT].eth_dst_addr, mac->mac, 6);
>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>  }
>>  
>>  
>>/************************************************************************
>>**//**
>> @@ -2111,7 +2111,7 @@ void pktgen_set_seq(port_info_t * info, uint32_t
>>seqnum,
>>  		type = '4';
>>  	pkt->ethType		= (type == '6')? ETHER_TYPE_IPv6 : ETHER_TYPE_IPv4;
>>  	pkt->vlanid			= vlanid;
>> -	pktgen_packet_ctor(info, seqnum, -1);
>> +	pktgen_packet_ctor(info, seqnum, -1, NULL);
>>  }
>>  
>>  
>>/************************************************************************
>>**//**
>> @@ -2156,7 +2156,7 @@ void pktgen_compile_pkt(port_info_t * info,
>>uint32_t seqnum,
>>  						  (type == '6')? ETHER_TYPE_IPv6 :
>>  						  (type == 'n')? ETHER_TYPE_VLAN : ETHER_TYPE_IPv4;
>>  	pkt->vlanid			= vlanid;
>> -	pktgen_packet_ctor(info, seqnum, -1);
>> +	pktgen_packet_ctor(info, seqnum, -1, NULL);
>>  }
>>  
>>  
>>/************************************************************************
>>**//**
>> diff --git a/app/pktgen-ipv4.c b/app/pktgen-ipv4.c
>> index 7813c36..a8b6be2 100644
>> --- a/app/pktgen-ipv4.c
>> +++ b/app/pktgen-ipv4.c
>> @@ -138,7 +138,7 @@ pktgen_send_ping4( uint32_t pid, uint8_t seq_idx )
>>          return;
>>      }
>>  	*ppkt = *spkt;		// Copy the sequence setup to the ping setup.
>> -    pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO);
>> +    pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO, NULL);
>>  	rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t
>>*)&ppkt->hdr, ppkt->pktSize);
>>  
>>      m->pkt_len  = ppkt->pktSize;
>> diff --git a/app/pktgen.c b/app/pktgen.c
>> index 2dcdbfd..ecd4560 100644
>> --- a/app/pktgen.c
>> +++ b/app/pktgen.c
>> @@ -401,8 +401,8 @@ static __inline__ int pktgen_has_work(void) {
>>  */
>>  
>>  void
>> -pktgen_packet_ctor(port_info_t * info, int32_t seq_idx, int32_t type) {
>> -	pkt_seq_t		  * pkt = &info->seq_pkt[seq_idx];
>> +pktgen_packet_ctor(port_info_t * info, int32_t seq_idx, int32_t type,
>>pkt_seq_t * seq_pkt) {
>> +	pkt_seq_t		  * pkt = (seq_pkt == NULL) ? &info->seq_pkt[seq_idx] :
>>&seq_pkt[seq_idx];
>>  	struct ether_hdr  * eth = (struct ether_hdr *)&pkt->hdr.eth;
>>  	uint16_t			tlen;
>>  
>> @@ -812,22 +812,35 @@ static __inline__ void
>>  pktgen_setup_packets(port_info_t * info, struct rte_mempool * mp,
>>uint16_t qid)
>>  {
>>  	struct rte_mbuf	* m, * mm;
>> -	pkt_seq_t * pkt;
>> +	pkt_seq_t * pkt, * seq_pkt = NULL;
>> +	uint16_t seqIdx;
>> +	char buff[RTE_MEMZONE_NAMESIZE];
>>  
>>  	pktgen_clr_q_flags(info, qid, CLEAR_FAST_ALLOC_FLAG);
>>  
>>  	if ( mp == info->q[qid].pcap_mp )
>>  		return;
>>  
>> +	snprintf(buff, sizeof(buff), "tmp_seq_pkt_%d_%d", info->pid, qid);
>> +	seq_pkt = (pkt_seq_t *)rte_zmalloc(buff,
>> +				(sizeof(pkt_seq_t) * NUM_TOTAL_PKTS), RTE_CACHE_LINE_SIZE);
>> +	if (seq_pkt == NULL)
>> +		pktgen_log_panic("Unable to allocate %d pkt_seq_t headers",
>> +						 NUM_TOTAL_PKTS);
>> +	/* Copy global configuration to construct new packets locally */
>> +	rte_memcpy((uint8_t *)seq_pkt, (uint8_t *)info->seq_pkt,
>> +			   sizeof(pkt_seq_t) * NUM_TOTAL_PKTS);
>> +	seqIdx = info->seqIdx;
>> +
>>  	mm	= NULL;
>>  	pkt = NULL;
>>  
>>  	if ( mp == info->q[qid].tx_mp )
>> -		pkt = &info->seq_pkt[SINGLE_PKT];
>> +		pkt = &seq_pkt[SINGLE_PKT];
>>  	else if ( mp == info->q[qid].range_mp )
>> -		pkt = &info->seq_pkt[RANGE_PKT];
>> +		pkt = &seq_pkt[RANGE_PKT];
>>  	else if ( mp == info->q[qid].seq_mp )
>> -		pkt = &info->seq_pkt[info->seqIdx];
>> +		pkt = &seq_pkt[seqIdx];
>>  
>>  	// allocate each mbuf and put them on a list to be freed.
>>  	for(;;) {
>> @@ -840,7 +853,7 @@ pktgen_setup_packets(port_info_t * info, struct
>>rte_mempool * mp, uint16_t qid)
>>  		mm = m;
>>  
>>  		if ( mp == info->q[qid].tx_mp ) {
>> -			pktgen_packet_ctor(info, SINGLE_PKT, -1);
>> +			pktgen_packet_ctor(info, SINGLE_PKT, -1, seq_pkt);
>>  
>>  			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t
>>*)&pkt->hdr, MAX_PKT_SIZE);
>>  
>> @@ -848,16 +861,16 @@ pktgen_setup_packets(port_info_t * info, struct
>>rte_mempool * mp, uint16_t qid)
>>  			m->data_len = pkt->pktSize;
>>  		} else if ( mp == info->q[qid].range_mp ) {
>>  			pktgen_range_ctor(&info->range, pkt);
>> -			pktgen_packet_ctor(info, RANGE_PKT, -1);
>> +			pktgen_packet_ctor(info, RANGE_PKT, -1, seq_pkt);
>>  
>>  			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t
>>*)&pkt->hdr, MAX_PKT_SIZE);
>>  
>>  			m->pkt_len  = pkt->pktSize;
>>  			m->data_len = pkt->pktSize;
>>  		} else if ( mp == info->q[qid].seq_mp ) {
>> -			pktgen_packet_ctor(info, info->seqIdx++, -1);
>> -			if ( unlikely(info->seqIdx >= info->seqCnt) )
>> -				info->seqIdx = 0;
>> +			pktgen_packet_ctor(info, seqIdx++, -1, seq_pkt);
>> +			if ( unlikely(seqIdx >= info->seqCnt) )
>> +				seqIdx = 0;
>>  
>>  			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t
>>*)&pkt->hdr, MAX_PKT_SIZE);
>>  
>> @@ -865,12 +878,14 @@ pktgen_setup_packets(port_info_t * info, struct
>>rte_mempool * mp, uint16_t qid)
>>  			m->data_len = pkt->pktSize;
>>  
>>  			// move to the next packet in the sequence.
>> -			pkt = &info->seq_pkt[info->seqIdx];
>> +			pkt = &seq_pkt[seqIdx];
>>  		}
>>  	}
>>  
>>  	if ( mm != NULL )
>>  		rte_pktmbuf_free(mm);
>> +
>> +	rte_free(seq_pkt);
>>  }
>>  
>>  
>>/************************************************************************
>>**//**
>> diff --git a/app/pktgen.h b/app/pktgen.h
>> index 2c5c98c..f3f76f2 100644
>> --- a/app/pktgen.h
>> +++ b/app/pktgen.h
>> @@ -151,7 +151,7 @@
>>  #include "pktgen-port-cfg.h"
>>  #include "pktgen-capture.h"
>>  #include "pktgen-log.h"
>> -
>> +#include "pktgen-seq.h"
>>  
>>  #define PKTGEN_VERSION			"2.9.2"
>>  #define PKTGEN_APP_NAME			"Pktgen"
>> @@ -386,7 +386,7 @@ extern pktgen_t		pktgen;
>>  
>>  extern void pktgen_page_display(__attribute__((unused)) struct
>>rte_timer *tim, __attribute__((unused)) void *arg);
>>  
>> -extern void pktgen_packet_ctor(port_info_t * info, int32_t seq_idx,
>>int32_t type);
>> +extern void pktgen_packet_ctor(port_info_t * info, int32_t seq_idx,
>>int32_t type, pkt_seq_t * seq_pkt);
>>  extern void pktgen_packet_rate(port_info_t * info);
>>  
>>  extern void pktgen_send_mbuf(struct rte_mbuf *m, uint8_t pid, uint16_t
>>qid);
>> diff --git a/app/t/pktgen.t.c b/app/t/pktgen.t.c
>> index 0eca4c4..77bf300 100644
>> --- a/app/t/pktgen.t.c
>> +++ b/app/t/pktgen.t.c
>> @@ -77,7 +77,7 @@ void test_pktgen_packet_ctor_IPv4_UDP(void)
>>  	};
>>  
>>  
>> -	lives_ok( { pktgen_packet_ctor(&info, 0, 0); }, "pktgen_packet_ctor
>>must generate IPv4/UDP");
>> +	lives_ok( { pktgen_packet_ctor(&info, 0, 0, NULL); },
>>"pktgen_packet_ctor must generate IPv4/UDP");
>>  
>>  	note("... with Ethernet header");
>>  	cmp_mem_lit_incr(data, (0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd), "    ...
>>with correct dest MAC");
>> @@ -133,9 +133,9 @@ void test_pktgen_packet_ctor_IPv4_GRE_Ether(void)
>>  		.pktSize      = 102,		// Subtract 4 for FCS
>>  	};
>>  
>> -	pktgen_packet_ctor(&info, 0, 0);
>> +	pktgen_packet_ctor(&info, 0, 0, NULL);
>>  
>> -	lives_ok( { pktgen_packet_ctor(&info, 0, 0); }, "pktgen_packet_ctor
>>must generate IPv4 GRE Ethernet frame");
>> +	lives_ok( { pktgen_packet_ctor(&info, 0, 0, NULL); },
>>"pktgen_packet_ctor must generate IPv4 GRE Ethernet frame");
>>  
>>  	note("... with outer Ethernet header");
>>  	cmp_mem_lit_incr(data, (0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd), "    ...
>>with correct dest MAC");
>> 
>


‹ 
Regards,
++Keith
Intel Corporation

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [dpdk-dev] [Pktgen] [PATCH] pktgen_setup_packets: fix race for packet header
  2015-09-16 15:37   ` Wiles, Keith
@ 2015-09-17  5:55     ` Ilya Maximets
  2015-10-02  9:23       ` Ilya Maximets
  0 siblings, 1 reply; 7+ messages in thread
From: Ilya Maximets @ 2015-09-17  5:55 UTC (permalink / raw)
  To: Wiles, Keith, dev; +Cc: Dyasly Sergey

Ok. Thank you. I'll wait.

On 16.09.2015 18:37, Wiles, Keith wrote:
> Thanks the patch looks fine, but I have not had a lot of time to review it
> detail. I hope to get to it next week after I return back home.
> 
> On 9/16/15, 2:09 AM, "Ilya Maximets" <i.maximets@samsung.com> wrote:
> 
>> Ping.
>>
>> On 09.09.2015 17:22, Ilya Maximets wrote:
>>> While pktgen_setup_packets() all threads of one port uses same
>>> info->seq_pkt. This leads to constructing packets in the same memory
>>> region
>>> (&pkt->hdr). As a result, pktgen_setup_packets generates random headers.
>>>
>>> Fix that by making a local copy of info->seq_pkt and using it for
>>> constructing of packets.
>>>
>>> Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
>>> ---
>>>  app/pktgen-arp.c  |  2 +-
>>>  app/pktgen-cmds.c | 40 ++++++++++++++++++++--------------------
>>>  app/pktgen-ipv4.c |  2 +-
>>>  app/pktgen.c      | 39 +++++++++++++++++++++++++++------------
>>>  app/pktgen.h      |  4 ++--
>>>  app/t/pktgen.t.c  |  6 +++---
>>>  6 files changed, 54 insertions(+), 39 deletions(-)
>>>
>>> diff --git a/app/pktgen-arp.c b/app/pktgen-arp.c
>>> index c378880..b7040d7 100644
>>> --- a/app/pktgen-arp.c
>>> +++ b/app/pktgen-arp.c
>>> @@ -190,7 +190,7 @@ pktgen_process_arp( struct rte_mbuf * m, uint32_t
>>> pid, uint32_t vlan )
>>>  
>>>  				rte_memcpy(&pkt->eth_dst_addr, &arp->sha, 6);
>>>  				for (i = 0; i < info->seqCnt; i++)
>>> -					pktgen_packet_ctor(info, i, -1);
>>> +					pktgen_packet_ctor(info, i, -1, NULL);
>>>  			}
>>>  
>>>  			// Swap the two MAC addresses
>>> diff --git a/app/pktgen-cmds.c b/app/pktgen-cmds.c
>>> index da040e5..a6abb41 100644
>>> --- a/app/pktgen-cmds.c
>>> +++ b/app/pktgen-cmds.c
>>> @@ -931,7 +931,7 @@ pktgen_set_proto(port_info_t * info, char type)
>>>  	if ( type == 'i' )
>>>  		info->seq_pkt[SINGLE_PKT].ethType = ETHER_TYPE_IPv4;
>>>  
>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>  }
>>>  
>>>  
>>> /************************************************************************
>>> **//**
>>> @@ -1067,7 +1067,7 @@ pktgen_set_pkt_type(port_info_t * info, const
>>> char * type)
>>>  										(type[3] == '6') ? ETHER_TYPE_IPv6 :
>>>  										/* TODO print error: unknown type */ ETHER_TYPE_IPv4;
>>>  
>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>  }
>>>  
>>>  
>>> /************************************************************************
>>> **//**
>>> @@ -1092,7 +1092,7 @@ pktgen_set_vlan(port_info_t * info, uint32_t
>>> onOff)
>>>  	}
>>>  	else
>>>  		pktgen_clr_port_flags(info, SEND_VLAN_ID);
>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>  }
>>>  
>>>  
>>> /************************************************************************
>>> **//**
>>> @@ -1112,7 +1112,7 @@ pktgen_set_vlanid(port_info_t * info, uint16_t
>>> vlanid)
>>>  {
>>>  	info->vlanid = vlanid;
>>>  	info->seq_pkt[SINGLE_PKT].vlanid = info->vlanid;
>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>  }
>>>  
>>>  
>>> /************************************************************************
>>> **//**
>>> @@ -1137,7 +1137,7 @@ pktgen_set_mpls(port_info_t * info, uint32_t
>>> onOff)
>>>  	}
>>>  	else
>>>  		pktgen_clr_port_flags(info, SEND_MPLS_LABEL);
>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>  }
>>>  
>>>  
>>> /************************************************************************
>>> **//**
>>> @@ -1157,7 +1157,7 @@ pktgen_set_mpls_entry(port_info_t * info,
>>> uint32_t mpls_entry)
>>>  {
>>>  	info->mpls_entry = mpls_entry;
>>>  	info->seq_pkt[SINGLE_PKT].mpls_entry = info->mpls_entry;
>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>  }
>>>  
>>>  
>>> /************************************************************************
>>> **//**
>>> @@ -1182,7 +1182,7 @@ pktgen_set_qinq(port_info_t * info, uint32_t
>>> onOff)
>>>  	}
>>>  	else
>>>  		pktgen_clr_port_flags(info, SEND_Q_IN_Q_IDS);
>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>  }
>>>  
>>>  
>>> /************************************************************************
>>> **//**
>>> @@ -1204,7 +1204,7 @@ pktgen_set_qinqids(port_info_t * info, uint16_t
>>> outerid, uint16_t innerid)
>>>  	info->seq_pkt[SINGLE_PKT].qinq_outerid = info->qinq_outerid;
>>>  	info->qinq_innerid = innerid;
>>>  	info->seq_pkt[SINGLE_PKT].qinq_innerid = info->qinq_innerid;
>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>  }
>>>  
>>>  
>>> /************************************************************************
>>> **//**
>>> @@ -1228,7 +1228,7 @@ pktgen_set_gre(port_info_t * info, uint32_t onOff)
>>>  	}
>>>  	else
>>>  		pktgen_clr_port_flags(info, SEND_GRE_IPv4_HEADER);
>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>  }
>>>  
>>>  
>>> /************************************************************************
>>> **//**
>>> @@ -1252,7 +1252,7 @@ pktgen_set_gre_eth(port_info_t * info, uint32_t
>>> onOff)
>>>  	}
>>>  	else
>>>  		pktgen_clr_port_flags(info, SEND_GRE_ETHER_HEADER);
>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>  }
>>>  
>>>  
>>> /************************************************************************
>>> **//**
>>> @@ -1272,7 +1272,7 @@ pktgen_set_gre_key(port_info_t * info, uint32_t
>>> gre_key)
>>>  {
>>>  	info->gre_key = gre_key;
>>>  	info->seq_pkt[SINGLE_PKT].gre_key = info->gre_key;
>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>  }
>>>  
>>>  
>>> /************************************************************************
>>> **//**
>>> @@ -1401,7 +1401,7 @@ void pktgen_port_defaults(uint32_t pid, uint8_t
>>> seq)
>>>  		memset(&pkt->eth_dst_addr, 0, sizeof (pkt->eth_dst_addr));
>>>  
>>>  
>>> -	pktgen_packet_ctor(info, seq, -1);
>>> +	pktgen_packet_ctor(info, seq, -1, NULL);
>>>  
>>>      pktgen.flags	|= PRINT_LABELS_FLAG;
>>>  }
>>> @@ -1423,7 +1423,7 @@ void pktgen_ping4(port_info_t * info)
>>>  	memcpy(&info->seq_pkt[PING_PKT],
>>>  		   &info->seq_pkt[SINGLE_PKT], sizeof(pkt_seq_t));
>>>  	info->seq_pkt[PING_PKT].ipProto = PG_IPPROTO_ICMP;
>>> -	pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO);
>>> +	pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO, NULL);
>>>  	pktgen_set_port_flags(info, SEND_PING4_REQUEST);
>>>  }
>>>  
>>> @@ -1445,7 +1445,7 @@ void pktgen_ping6(port_info_t * info)
>>>  	memcpy(&info->pkt[PING_PKT],
>>>  		   &info->pkt[SINGLE_PKT], sizeof(pkt_seq_t));
>>>  	info->pkt[PING_PKT].ipProto = PG_IPPROTO_ICMP;
>>> -	pktgen_packet_ctor(info, PING_PKT, ICMP6_ECHO);
>>> +	pktgen_packet_ctor(info, PING_PKT, ICMP6_ECHO, NULL);
>>>  	pktgen_set_port_flags(info, SEND_PING6_REQUEST);
>>>  }
>>>  #endif
>>> @@ -1645,7 +1645,7 @@ void pktgen_set_pkt_size(port_info_t * info,
>>> uint32_t size)
>>>  	else if ( (size - FCS_SIZE) > MAX_PKT_SIZE)
>>>  		size = MAX_PKT_SIZE + FCS_SIZE;
>>>  	info->seq_pkt[SINGLE_PKT].pktSize = (size - FCS_SIZE);
>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>  	pktgen_packet_rate(info);
>>>  }
>>>  
>>> @@ -1667,7 +1667,7 @@ void pktgen_set_port_value(port_info_t * info,
>>> char type, uint32_t portValue)
>>>  		info->seq_pkt[SINGLE_PKT].dport = (uint16_t)portValue;
>>>  	else
>>>  		info->seq_pkt[SINGLE_PKT].sport = (uint16_t)portValue;
>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>  }
>>>  
>>>  
>>> /************************************************************************
>>> **//**
>>> @@ -1711,7 +1711,7 @@ void pktgen_set_ipaddr(port_info_t * info, char
>>> type, cmdline_ipaddr_t * ip)
>>>  		info->seq_pkt[SINGLE_PKT].ip_src_addr = ntohl(ip->addr.ipv4.s_addr);
>>>  	} else
>>>  		info->seq_pkt[SINGLE_PKT].ip_dst_addr = ntohl(ip->addr.ipv4.s_addr);
>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>  }
>>>  
>>>  
>>> /************************************************************************
>>> **//**
>>> @@ -1729,7 +1729,7 @@ void pktgen_set_ipaddr(port_info_t * info, char
>>> type, cmdline_ipaddr_t * ip)
>>>  void pktgen_set_dst_mac(port_info_t * info, cmdline_etheraddr_t * mac)
>>>  {
>>>  	memcpy(&info->seq_pkt[SINGLE_PKT].eth_dst_addr, mac->mac, 6);
>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>  }
>>>  
>>>  
>>> /************************************************************************
>>> **//**
>>> @@ -2111,7 +2111,7 @@ void pktgen_set_seq(port_info_t * info, uint32_t
>>> seqnum,
>>>  		type = '4';
>>>  	pkt->ethType		= (type == '6')? ETHER_TYPE_IPv6 : ETHER_TYPE_IPv4;
>>>  	pkt->vlanid			= vlanid;
>>> -	pktgen_packet_ctor(info, seqnum, -1);
>>> +	pktgen_packet_ctor(info, seqnum, -1, NULL);
>>>  }
>>>  
>>>  
>>> /************************************************************************
>>> **//**
>>> @@ -2156,7 +2156,7 @@ void pktgen_compile_pkt(port_info_t * info,
>>> uint32_t seqnum,
>>>  						  (type == '6')? ETHER_TYPE_IPv6 :
>>>  						  (type == 'n')? ETHER_TYPE_VLAN : ETHER_TYPE_IPv4;
>>>  	pkt->vlanid			= vlanid;
>>> -	pktgen_packet_ctor(info, seqnum, -1);
>>> +	pktgen_packet_ctor(info, seqnum, -1, NULL);
>>>  }
>>>  
>>>  
>>> /************************************************************************
>>> **//**
>>> diff --git a/app/pktgen-ipv4.c b/app/pktgen-ipv4.c
>>> index 7813c36..a8b6be2 100644
>>> --- a/app/pktgen-ipv4.c
>>> +++ b/app/pktgen-ipv4.c
>>> @@ -138,7 +138,7 @@ pktgen_send_ping4( uint32_t pid, uint8_t seq_idx )
>>>          return;
>>>      }
>>>  	*ppkt = *spkt;		// Copy the sequence setup to the ping setup.
>>> -    pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO);
>>> +    pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO, NULL);
>>>  	rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t
>>> *)&ppkt->hdr, ppkt->pktSize);
>>>  
>>>      m->pkt_len  = ppkt->pktSize;
>>> diff --git a/app/pktgen.c b/app/pktgen.c
>>> index 2dcdbfd..ecd4560 100644
>>> --- a/app/pktgen.c
>>> +++ b/app/pktgen.c
>>> @@ -401,8 +401,8 @@ static __inline__ int pktgen_has_work(void) {
>>>  */
>>>  
>>>  void
>>> -pktgen_packet_ctor(port_info_t * info, int32_t seq_idx, int32_t type) {
>>> -	pkt_seq_t		  * pkt = &info->seq_pkt[seq_idx];
>>> +pktgen_packet_ctor(port_info_t * info, int32_t seq_idx, int32_t type,
>>> pkt_seq_t * seq_pkt) {
>>> +	pkt_seq_t		  * pkt = (seq_pkt == NULL) ? &info->seq_pkt[seq_idx] :
>>> &seq_pkt[seq_idx];
>>>  	struct ether_hdr  * eth = (struct ether_hdr *)&pkt->hdr.eth;
>>>  	uint16_t			tlen;
>>>  
>>> @@ -812,22 +812,35 @@ static __inline__ void
>>>  pktgen_setup_packets(port_info_t * info, struct rte_mempool * mp,
>>> uint16_t qid)
>>>  {
>>>  	struct rte_mbuf	* m, * mm;
>>> -	pkt_seq_t * pkt;
>>> +	pkt_seq_t * pkt, * seq_pkt = NULL;
>>> +	uint16_t seqIdx;
>>> +	char buff[RTE_MEMZONE_NAMESIZE];
>>>  
>>>  	pktgen_clr_q_flags(info, qid, CLEAR_FAST_ALLOC_FLAG);
>>>  
>>>  	if ( mp == info->q[qid].pcap_mp )
>>>  		return;
>>>  
>>> +	snprintf(buff, sizeof(buff), "tmp_seq_pkt_%d_%d", info->pid, qid);
>>> +	seq_pkt = (pkt_seq_t *)rte_zmalloc(buff,
>>> +				(sizeof(pkt_seq_t) * NUM_TOTAL_PKTS), RTE_CACHE_LINE_SIZE);
>>> +	if (seq_pkt == NULL)
>>> +		pktgen_log_panic("Unable to allocate %d pkt_seq_t headers",
>>> +						 NUM_TOTAL_PKTS);
>>> +	/* Copy global configuration to construct new packets locally */
>>> +	rte_memcpy((uint8_t *)seq_pkt, (uint8_t *)info->seq_pkt,
>>> +			   sizeof(pkt_seq_t) * NUM_TOTAL_PKTS);
>>> +	seqIdx = info->seqIdx;
>>> +
>>>  	mm	= NULL;
>>>  	pkt = NULL;
>>>  
>>>  	if ( mp == info->q[qid].tx_mp )
>>> -		pkt = &info->seq_pkt[SINGLE_PKT];
>>> +		pkt = &seq_pkt[SINGLE_PKT];
>>>  	else if ( mp == info->q[qid].range_mp )
>>> -		pkt = &info->seq_pkt[RANGE_PKT];
>>> +		pkt = &seq_pkt[RANGE_PKT];
>>>  	else if ( mp == info->q[qid].seq_mp )
>>> -		pkt = &info->seq_pkt[info->seqIdx];
>>> +		pkt = &seq_pkt[seqIdx];
>>>  
>>>  	// allocate each mbuf and put them on a list to be freed.
>>>  	for(;;) {
>>> @@ -840,7 +853,7 @@ pktgen_setup_packets(port_info_t * info, struct
>>> rte_mempool * mp, uint16_t qid)
>>>  		mm = m;
>>>  
>>>  		if ( mp == info->q[qid].tx_mp ) {
>>> -			pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>> +			pktgen_packet_ctor(info, SINGLE_PKT, -1, seq_pkt);
>>>  
>>>  			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t
>>> *)&pkt->hdr, MAX_PKT_SIZE);
>>>  
>>> @@ -848,16 +861,16 @@ pktgen_setup_packets(port_info_t * info, struct
>>> rte_mempool * mp, uint16_t qid)
>>>  			m->data_len = pkt->pktSize;
>>>  		} else if ( mp == info->q[qid].range_mp ) {
>>>  			pktgen_range_ctor(&info->range, pkt);
>>> -			pktgen_packet_ctor(info, RANGE_PKT, -1);
>>> +			pktgen_packet_ctor(info, RANGE_PKT, -1, seq_pkt);
>>>  
>>>  			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t
>>> *)&pkt->hdr, MAX_PKT_SIZE);
>>>  
>>>  			m->pkt_len  = pkt->pktSize;
>>>  			m->data_len = pkt->pktSize;
>>>  		} else if ( mp == info->q[qid].seq_mp ) {
>>> -			pktgen_packet_ctor(info, info->seqIdx++, -1);
>>> -			if ( unlikely(info->seqIdx >= info->seqCnt) )
>>> -				info->seqIdx = 0;
>>> +			pktgen_packet_ctor(info, seqIdx++, -1, seq_pkt);
>>> +			if ( unlikely(seqIdx >= info->seqCnt) )
>>> +				seqIdx = 0;
>>>  
>>>  			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t
>>> *)&pkt->hdr, MAX_PKT_SIZE);
>>>  
>>> @@ -865,12 +878,14 @@ pktgen_setup_packets(port_info_t * info, struct
>>> rte_mempool * mp, uint16_t qid)
>>>  			m->data_len = pkt->pktSize;
>>>  
>>>  			// move to the next packet in the sequence.
>>> -			pkt = &info->seq_pkt[info->seqIdx];
>>> +			pkt = &seq_pkt[seqIdx];
>>>  		}
>>>  	}
>>>  
>>>  	if ( mm != NULL )
>>>  		rte_pktmbuf_free(mm);
>>> +
>>> +	rte_free(seq_pkt);
>>>  }
>>>  
>>>  
>>> /************************************************************************
>>> **//**
>>> diff --git a/app/pktgen.h b/app/pktgen.h
>>> index 2c5c98c..f3f76f2 100644
>>> --- a/app/pktgen.h
>>> +++ b/app/pktgen.h
>>> @@ -151,7 +151,7 @@
>>>  #include "pktgen-port-cfg.h"
>>>  #include "pktgen-capture.h"
>>>  #include "pktgen-log.h"
>>> -
>>> +#include "pktgen-seq.h"
>>>  
>>>  #define PKTGEN_VERSION			"2.9.2"
>>>  #define PKTGEN_APP_NAME			"Pktgen"
>>> @@ -386,7 +386,7 @@ extern pktgen_t		pktgen;
>>>  
>>>  extern void pktgen_page_display(__attribute__((unused)) struct
>>> rte_timer *tim, __attribute__((unused)) void *arg);
>>>  
>>> -extern void pktgen_packet_ctor(port_info_t * info, int32_t seq_idx,
>>> int32_t type);
>>> +extern void pktgen_packet_ctor(port_info_t * info, int32_t seq_idx,
>>> int32_t type, pkt_seq_t * seq_pkt);
>>>  extern void pktgen_packet_rate(port_info_t * info);
>>>  
>>>  extern void pktgen_send_mbuf(struct rte_mbuf *m, uint8_t pid, uint16_t
>>> qid);
>>> diff --git a/app/t/pktgen.t.c b/app/t/pktgen.t.c
>>> index 0eca4c4..77bf300 100644
>>> --- a/app/t/pktgen.t.c
>>> +++ b/app/t/pktgen.t.c
>>> @@ -77,7 +77,7 @@ void test_pktgen_packet_ctor_IPv4_UDP(void)
>>>  	};
>>>  
>>>  
>>> -	lives_ok( { pktgen_packet_ctor(&info, 0, 0); }, "pktgen_packet_ctor
>>> must generate IPv4/UDP");
>>> +	lives_ok( { pktgen_packet_ctor(&info, 0, 0, NULL); },
>>> "pktgen_packet_ctor must generate IPv4/UDP");
>>>  
>>>  	note("... with Ethernet header");
>>>  	cmp_mem_lit_incr(data, (0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd), "    ...
>>> with correct dest MAC");
>>> @@ -133,9 +133,9 @@ void test_pktgen_packet_ctor_IPv4_GRE_Ether(void)
>>>  		.pktSize      = 102,		// Subtract 4 for FCS
>>>  	};
>>>  
>>> -	pktgen_packet_ctor(&info, 0, 0);
>>> +	pktgen_packet_ctor(&info, 0, 0, NULL);
>>>  
>>> -	lives_ok( { pktgen_packet_ctor(&info, 0, 0); }, "pktgen_packet_ctor
>>> must generate IPv4 GRE Ethernet frame");
>>> +	lives_ok( { pktgen_packet_ctor(&info, 0, 0, NULL); },
>>> "pktgen_packet_ctor must generate IPv4 GRE Ethernet frame");
>>>  
>>>  	note("... with outer Ethernet header");
>>>  	cmp_mem_lit_incr(data, (0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd), "    ...
>>> with correct dest MAC");
>>>
>>
> 
> 
> ‹ 
> Regards,
> ++Keith
> Intel Corporation
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [dpdk-dev] [Pktgen] [PATCH] pktgen_setup_packets: fix race for packet header
  2015-09-17  5:55     ` Ilya Maximets
@ 2015-10-02  9:23       ` Ilya Maximets
  2015-10-02 11:25         ` Wiles, Keith
  0 siblings, 1 reply; 7+ messages in thread
From: Ilya Maximets @ 2015-10-02  9:23 UTC (permalink / raw)
  To: Wiles, Keith, dev; +Cc: Dyasly Sergey

Ping.

On 17.09.2015 08:55, Ilya Maximets wrote:
> Ok. Thank you. I'll wait.
> 
> On 16.09.2015 18:37, Wiles, Keith wrote:
>> Thanks the patch looks fine, but I have not had a lot of time to review it
>> detail. I hope to get to it next week after I return back home.
>>
>> On 9/16/15, 2:09 AM, "Ilya Maximets" <i.maximets@samsung.com> wrote:
>>
>>> Ping.
>>>
>>> On 09.09.2015 17:22, Ilya Maximets wrote:
>>>> While pktgen_setup_packets() all threads of one port uses same
>>>> info->seq_pkt. This leads to constructing packets in the same memory
>>>> region
>>>> (&pkt->hdr). As a result, pktgen_setup_packets generates random headers.
>>>>
>>>> Fix that by making a local copy of info->seq_pkt and using it for
>>>> constructing of packets.
>>>>
>>>> Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
>>>> ---
>>>>  app/pktgen-arp.c  |  2 +-
>>>>  app/pktgen-cmds.c | 40 ++++++++++++++++++++--------------------
>>>>  app/pktgen-ipv4.c |  2 +-
>>>>  app/pktgen.c      | 39 +++++++++++++++++++++++++++------------
>>>>  app/pktgen.h      |  4 ++--
>>>>  app/t/pktgen.t.c  |  6 +++---
>>>>  6 files changed, 54 insertions(+), 39 deletions(-)
>>>>
>>>> diff --git a/app/pktgen-arp.c b/app/pktgen-arp.c
>>>> index c378880..b7040d7 100644
>>>> --- a/app/pktgen-arp.c
>>>> +++ b/app/pktgen-arp.c
>>>> @@ -190,7 +190,7 @@ pktgen_process_arp( struct rte_mbuf * m, uint32_t
>>>> pid, uint32_t vlan )
>>>>  
>>>>  				rte_memcpy(&pkt->eth_dst_addr, &arp->sha, 6);
>>>>  				for (i = 0; i < info->seqCnt; i++)
>>>> -					pktgen_packet_ctor(info, i, -1);
>>>> +					pktgen_packet_ctor(info, i, -1, NULL);
>>>>  			}
>>>>  
>>>>  			// Swap the two MAC addresses
>>>> diff --git a/app/pktgen-cmds.c b/app/pktgen-cmds.c
>>>> index da040e5..a6abb41 100644
>>>> --- a/app/pktgen-cmds.c
>>>> +++ b/app/pktgen-cmds.c
>>>> @@ -931,7 +931,7 @@ pktgen_set_proto(port_info_t * info, char type)
>>>>  	if ( type == 'i' )
>>>>  		info->seq_pkt[SINGLE_PKT].ethType = ETHER_TYPE_IPv4;
>>>>  
>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>  }
>>>>  
>>>>  
>>>> /************************************************************************
>>>> **//**
>>>> @@ -1067,7 +1067,7 @@ pktgen_set_pkt_type(port_info_t * info, const
>>>> char * type)
>>>>  										(type[3] == '6') ? ETHER_TYPE_IPv6 :
>>>>  										/* TODO print error: unknown type */ ETHER_TYPE_IPv4;
>>>>  
>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>  }
>>>>  
>>>>  
>>>> /************************************************************************
>>>> **//**
>>>> @@ -1092,7 +1092,7 @@ pktgen_set_vlan(port_info_t * info, uint32_t
>>>> onOff)
>>>>  	}
>>>>  	else
>>>>  		pktgen_clr_port_flags(info, SEND_VLAN_ID);
>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>  }
>>>>  
>>>>  
>>>> /************************************************************************
>>>> **//**
>>>> @@ -1112,7 +1112,7 @@ pktgen_set_vlanid(port_info_t * info, uint16_t
>>>> vlanid)
>>>>  {
>>>>  	info->vlanid = vlanid;
>>>>  	info->seq_pkt[SINGLE_PKT].vlanid = info->vlanid;
>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>  }
>>>>  
>>>>  
>>>> /************************************************************************
>>>> **//**
>>>> @@ -1137,7 +1137,7 @@ pktgen_set_mpls(port_info_t * info, uint32_t
>>>> onOff)
>>>>  	}
>>>>  	else
>>>>  		pktgen_clr_port_flags(info, SEND_MPLS_LABEL);
>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>  }
>>>>  
>>>>  
>>>> /************************************************************************
>>>> **//**
>>>> @@ -1157,7 +1157,7 @@ pktgen_set_mpls_entry(port_info_t * info,
>>>> uint32_t mpls_entry)
>>>>  {
>>>>  	info->mpls_entry = mpls_entry;
>>>>  	info->seq_pkt[SINGLE_PKT].mpls_entry = info->mpls_entry;
>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>  }
>>>>  
>>>>  
>>>> /************************************************************************
>>>> **//**
>>>> @@ -1182,7 +1182,7 @@ pktgen_set_qinq(port_info_t * info, uint32_t
>>>> onOff)
>>>>  	}
>>>>  	else
>>>>  		pktgen_clr_port_flags(info, SEND_Q_IN_Q_IDS);
>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>  }
>>>>  
>>>>  
>>>> /************************************************************************
>>>> **//**
>>>> @@ -1204,7 +1204,7 @@ pktgen_set_qinqids(port_info_t * info, uint16_t
>>>> outerid, uint16_t innerid)
>>>>  	info->seq_pkt[SINGLE_PKT].qinq_outerid = info->qinq_outerid;
>>>>  	info->qinq_innerid = innerid;
>>>>  	info->seq_pkt[SINGLE_PKT].qinq_innerid = info->qinq_innerid;
>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>  }
>>>>  
>>>>  
>>>> /************************************************************************
>>>> **//**
>>>> @@ -1228,7 +1228,7 @@ pktgen_set_gre(port_info_t * info, uint32_t onOff)
>>>>  	}
>>>>  	else
>>>>  		pktgen_clr_port_flags(info, SEND_GRE_IPv4_HEADER);
>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>  }
>>>>  
>>>>  
>>>> /************************************************************************
>>>> **//**
>>>> @@ -1252,7 +1252,7 @@ pktgen_set_gre_eth(port_info_t * info, uint32_t
>>>> onOff)
>>>>  	}
>>>>  	else
>>>>  		pktgen_clr_port_flags(info, SEND_GRE_ETHER_HEADER);
>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>  }
>>>>  
>>>>  
>>>> /************************************************************************
>>>> **//**
>>>> @@ -1272,7 +1272,7 @@ pktgen_set_gre_key(port_info_t * info, uint32_t
>>>> gre_key)
>>>>  {
>>>>  	info->gre_key = gre_key;
>>>>  	info->seq_pkt[SINGLE_PKT].gre_key = info->gre_key;
>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>  }
>>>>  
>>>>  
>>>> /************************************************************************
>>>> **//**
>>>> @@ -1401,7 +1401,7 @@ void pktgen_port_defaults(uint32_t pid, uint8_t
>>>> seq)
>>>>  		memset(&pkt->eth_dst_addr, 0, sizeof (pkt->eth_dst_addr));
>>>>  
>>>>  
>>>> -	pktgen_packet_ctor(info, seq, -1);
>>>> +	pktgen_packet_ctor(info, seq, -1, NULL);
>>>>  
>>>>      pktgen.flags	|= PRINT_LABELS_FLAG;
>>>>  }
>>>> @@ -1423,7 +1423,7 @@ void pktgen_ping4(port_info_t * info)
>>>>  	memcpy(&info->seq_pkt[PING_PKT],
>>>>  		   &info->seq_pkt[SINGLE_PKT], sizeof(pkt_seq_t));
>>>>  	info->seq_pkt[PING_PKT].ipProto = PG_IPPROTO_ICMP;
>>>> -	pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO);
>>>> +	pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO, NULL);
>>>>  	pktgen_set_port_flags(info, SEND_PING4_REQUEST);
>>>>  }
>>>>  
>>>> @@ -1445,7 +1445,7 @@ void pktgen_ping6(port_info_t * info)
>>>>  	memcpy(&info->pkt[PING_PKT],
>>>>  		   &info->pkt[SINGLE_PKT], sizeof(pkt_seq_t));
>>>>  	info->pkt[PING_PKT].ipProto = PG_IPPROTO_ICMP;
>>>> -	pktgen_packet_ctor(info, PING_PKT, ICMP6_ECHO);
>>>> +	pktgen_packet_ctor(info, PING_PKT, ICMP6_ECHO, NULL);
>>>>  	pktgen_set_port_flags(info, SEND_PING6_REQUEST);
>>>>  }
>>>>  #endif
>>>> @@ -1645,7 +1645,7 @@ void pktgen_set_pkt_size(port_info_t * info,
>>>> uint32_t size)
>>>>  	else if ( (size - FCS_SIZE) > MAX_PKT_SIZE)
>>>>  		size = MAX_PKT_SIZE + FCS_SIZE;
>>>>  	info->seq_pkt[SINGLE_PKT].pktSize = (size - FCS_SIZE);
>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>  	pktgen_packet_rate(info);
>>>>  }
>>>>  
>>>> @@ -1667,7 +1667,7 @@ void pktgen_set_port_value(port_info_t * info,
>>>> char type, uint32_t portValue)
>>>>  		info->seq_pkt[SINGLE_PKT].dport = (uint16_t)portValue;
>>>>  	else
>>>>  		info->seq_pkt[SINGLE_PKT].sport = (uint16_t)portValue;
>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>  }
>>>>  
>>>>  
>>>> /************************************************************************
>>>> **//**
>>>> @@ -1711,7 +1711,7 @@ void pktgen_set_ipaddr(port_info_t * info, char
>>>> type, cmdline_ipaddr_t * ip)
>>>>  		info->seq_pkt[SINGLE_PKT].ip_src_addr = ntohl(ip->addr.ipv4.s_addr);
>>>>  	} else
>>>>  		info->seq_pkt[SINGLE_PKT].ip_dst_addr = ntohl(ip->addr.ipv4.s_addr);
>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>  }
>>>>  
>>>>  
>>>> /************************************************************************
>>>> **//**
>>>> @@ -1729,7 +1729,7 @@ void pktgen_set_ipaddr(port_info_t * info, char
>>>> type, cmdline_ipaddr_t * ip)
>>>>  void pktgen_set_dst_mac(port_info_t * info, cmdline_etheraddr_t * mac)
>>>>  {
>>>>  	memcpy(&info->seq_pkt[SINGLE_PKT].eth_dst_addr, mac->mac, 6);
>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>  }
>>>>  
>>>>  
>>>> /************************************************************************
>>>> **//**
>>>> @@ -2111,7 +2111,7 @@ void pktgen_set_seq(port_info_t * info, uint32_t
>>>> seqnum,
>>>>  		type = '4';
>>>>  	pkt->ethType		= (type == '6')? ETHER_TYPE_IPv6 : ETHER_TYPE_IPv4;
>>>>  	pkt->vlanid			= vlanid;
>>>> -	pktgen_packet_ctor(info, seqnum, -1);
>>>> +	pktgen_packet_ctor(info, seqnum, -1, NULL);
>>>>  }
>>>>  
>>>>  
>>>> /************************************************************************
>>>> **//**
>>>> @@ -2156,7 +2156,7 @@ void pktgen_compile_pkt(port_info_t * info,
>>>> uint32_t seqnum,
>>>>  						  (type == '6')? ETHER_TYPE_IPv6 :
>>>>  						  (type == 'n')? ETHER_TYPE_VLAN : ETHER_TYPE_IPv4;
>>>>  	pkt->vlanid			= vlanid;
>>>> -	pktgen_packet_ctor(info, seqnum, -1);
>>>> +	pktgen_packet_ctor(info, seqnum, -1, NULL);
>>>>  }
>>>>  
>>>>  
>>>> /************************************************************************
>>>> **//**
>>>> diff --git a/app/pktgen-ipv4.c b/app/pktgen-ipv4.c
>>>> index 7813c36..a8b6be2 100644
>>>> --- a/app/pktgen-ipv4.c
>>>> +++ b/app/pktgen-ipv4.c
>>>> @@ -138,7 +138,7 @@ pktgen_send_ping4( uint32_t pid, uint8_t seq_idx )
>>>>          return;
>>>>      }
>>>>  	*ppkt = *spkt;		// Copy the sequence setup to the ping setup.
>>>> -    pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO);
>>>> +    pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO, NULL);
>>>>  	rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t
>>>> *)&ppkt->hdr, ppkt->pktSize);
>>>>  
>>>>      m->pkt_len  = ppkt->pktSize;
>>>> diff --git a/app/pktgen.c b/app/pktgen.c
>>>> index 2dcdbfd..ecd4560 100644
>>>> --- a/app/pktgen.c
>>>> +++ b/app/pktgen.c
>>>> @@ -401,8 +401,8 @@ static __inline__ int pktgen_has_work(void) {
>>>>  */
>>>>  
>>>>  void
>>>> -pktgen_packet_ctor(port_info_t * info, int32_t seq_idx, int32_t type) {
>>>> -	pkt_seq_t		  * pkt = &info->seq_pkt[seq_idx];
>>>> +pktgen_packet_ctor(port_info_t * info, int32_t seq_idx, int32_t type,
>>>> pkt_seq_t * seq_pkt) {
>>>> +	pkt_seq_t		  * pkt = (seq_pkt == NULL) ? &info->seq_pkt[seq_idx] :
>>>> &seq_pkt[seq_idx];
>>>>  	struct ether_hdr  * eth = (struct ether_hdr *)&pkt->hdr.eth;
>>>>  	uint16_t			tlen;
>>>>  
>>>> @@ -812,22 +812,35 @@ static __inline__ void
>>>>  pktgen_setup_packets(port_info_t * info, struct rte_mempool * mp,
>>>> uint16_t qid)
>>>>  {
>>>>  	struct rte_mbuf	* m, * mm;
>>>> -	pkt_seq_t * pkt;
>>>> +	pkt_seq_t * pkt, * seq_pkt = NULL;
>>>> +	uint16_t seqIdx;
>>>> +	char buff[RTE_MEMZONE_NAMESIZE];
>>>>  
>>>>  	pktgen_clr_q_flags(info, qid, CLEAR_FAST_ALLOC_FLAG);
>>>>  
>>>>  	if ( mp == info->q[qid].pcap_mp )
>>>>  		return;
>>>>  
>>>> +	snprintf(buff, sizeof(buff), "tmp_seq_pkt_%d_%d", info->pid, qid);
>>>> +	seq_pkt = (pkt_seq_t *)rte_zmalloc(buff,
>>>> +				(sizeof(pkt_seq_t) * NUM_TOTAL_PKTS), RTE_CACHE_LINE_SIZE);
>>>> +	if (seq_pkt == NULL)
>>>> +		pktgen_log_panic("Unable to allocate %d pkt_seq_t headers",
>>>> +						 NUM_TOTAL_PKTS);
>>>> +	/* Copy global configuration to construct new packets locally */
>>>> +	rte_memcpy((uint8_t *)seq_pkt, (uint8_t *)info->seq_pkt,
>>>> +			   sizeof(pkt_seq_t) * NUM_TOTAL_PKTS);
>>>> +	seqIdx = info->seqIdx;
>>>> +
>>>>  	mm	= NULL;
>>>>  	pkt = NULL;
>>>>  
>>>>  	if ( mp == info->q[qid].tx_mp )
>>>> -		pkt = &info->seq_pkt[SINGLE_PKT];
>>>> +		pkt = &seq_pkt[SINGLE_PKT];
>>>>  	else if ( mp == info->q[qid].range_mp )
>>>> -		pkt = &info->seq_pkt[RANGE_PKT];
>>>> +		pkt = &seq_pkt[RANGE_PKT];
>>>>  	else if ( mp == info->q[qid].seq_mp )
>>>> -		pkt = &info->seq_pkt[info->seqIdx];
>>>> +		pkt = &seq_pkt[seqIdx];
>>>>  
>>>>  	// allocate each mbuf and put them on a list to be freed.
>>>>  	for(;;) {
>>>> @@ -840,7 +853,7 @@ pktgen_setup_packets(port_info_t * info, struct
>>>> rte_mempool * mp, uint16_t qid)
>>>>  		mm = m;
>>>>  
>>>>  		if ( mp == info->q[qid].tx_mp ) {
>>>> -			pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>> +			pktgen_packet_ctor(info, SINGLE_PKT, -1, seq_pkt);
>>>>  
>>>>  			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t
>>>> *)&pkt->hdr, MAX_PKT_SIZE);
>>>>  
>>>> @@ -848,16 +861,16 @@ pktgen_setup_packets(port_info_t * info, struct
>>>> rte_mempool * mp, uint16_t qid)
>>>>  			m->data_len = pkt->pktSize;
>>>>  		} else if ( mp == info->q[qid].range_mp ) {
>>>>  			pktgen_range_ctor(&info->range, pkt);
>>>> -			pktgen_packet_ctor(info, RANGE_PKT, -1);
>>>> +			pktgen_packet_ctor(info, RANGE_PKT, -1, seq_pkt);
>>>>  
>>>>  			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t
>>>> *)&pkt->hdr, MAX_PKT_SIZE);
>>>>  
>>>>  			m->pkt_len  = pkt->pktSize;
>>>>  			m->data_len = pkt->pktSize;
>>>>  		} else if ( mp == info->q[qid].seq_mp ) {
>>>> -			pktgen_packet_ctor(info, info->seqIdx++, -1);
>>>> -			if ( unlikely(info->seqIdx >= info->seqCnt) )
>>>> -				info->seqIdx = 0;
>>>> +			pktgen_packet_ctor(info, seqIdx++, -1, seq_pkt);
>>>> +			if ( unlikely(seqIdx >= info->seqCnt) )
>>>> +				seqIdx = 0;
>>>>  
>>>>  			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t
>>>> *)&pkt->hdr, MAX_PKT_SIZE);
>>>>  
>>>> @@ -865,12 +878,14 @@ pktgen_setup_packets(port_info_t * info, struct
>>>> rte_mempool * mp, uint16_t qid)
>>>>  			m->data_len = pkt->pktSize;
>>>>  
>>>>  			// move to the next packet in the sequence.
>>>> -			pkt = &info->seq_pkt[info->seqIdx];
>>>> +			pkt = &seq_pkt[seqIdx];
>>>>  		}
>>>>  	}
>>>>  
>>>>  	if ( mm != NULL )
>>>>  		rte_pktmbuf_free(mm);
>>>> +
>>>> +	rte_free(seq_pkt);
>>>>  }
>>>>  
>>>>  
>>>> /************************************************************************
>>>> **//**
>>>> diff --git a/app/pktgen.h b/app/pktgen.h
>>>> index 2c5c98c..f3f76f2 100644
>>>> --- a/app/pktgen.h
>>>> +++ b/app/pktgen.h
>>>> @@ -151,7 +151,7 @@
>>>>  #include "pktgen-port-cfg.h"
>>>>  #include "pktgen-capture.h"
>>>>  #include "pktgen-log.h"
>>>> -
>>>> +#include "pktgen-seq.h"
>>>>  
>>>>  #define PKTGEN_VERSION			"2.9.2"
>>>>  #define PKTGEN_APP_NAME			"Pktgen"
>>>> @@ -386,7 +386,7 @@ extern pktgen_t		pktgen;
>>>>  
>>>>  extern void pktgen_page_display(__attribute__((unused)) struct
>>>> rte_timer *tim, __attribute__((unused)) void *arg);
>>>>  
>>>> -extern void pktgen_packet_ctor(port_info_t * info, int32_t seq_idx,
>>>> int32_t type);
>>>> +extern void pktgen_packet_ctor(port_info_t * info, int32_t seq_idx,
>>>> int32_t type, pkt_seq_t * seq_pkt);
>>>>  extern void pktgen_packet_rate(port_info_t * info);
>>>>  
>>>>  extern void pktgen_send_mbuf(struct rte_mbuf *m, uint8_t pid, uint16_t
>>>> qid);
>>>> diff --git a/app/t/pktgen.t.c b/app/t/pktgen.t.c
>>>> index 0eca4c4..77bf300 100644
>>>> --- a/app/t/pktgen.t.c
>>>> +++ b/app/t/pktgen.t.c
>>>> @@ -77,7 +77,7 @@ void test_pktgen_packet_ctor_IPv4_UDP(void)
>>>>  	};
>>>>  
>>>>  
>>>> -	lives_ok( { pktgen_packet_ctor(&info, 0, 0); }, "pktgen_packet_ctor
>>>> must generate IPv4/UDP");
>>>> +	lives_ok( { pktgen_packet_ctor(&info, 0, 0, NULL); },
>>>> "pktgen_packet_ctor must generate IPv4/UDP");
>>>>  
>>>>  	note("... with Ethernet header");
>>>>  	cmp_mem_lit_incr(data, (0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd), "    ...
>>>> with correct dest MAC");
>>>> @@ -133,9 +133,9 @@ void test_pktgen_packet_ctor_IPv4_GRE_Ether(void)
>>>>  		.pktSize      = 102,		// Subtract 4 for FCS
>>>>  	};
>>>>  
>>>> -	pktgen_packet_ctor(&info, 0, 0);
>>>> +	pktgen_packet_ctor(&info, 0, 0, NULL);
>>>>  
>>>> -	lives_ok( { pktgen_packet_ctor(&info, 0, 0); }, "pktgen_packet_ctor
>>>> must generate IPv4 GRE Ethernet frame");
>>>> +	lives_ok( { pktgen_packet_ctor(&info, 0, 0, NULL); },
>>>> "pktgen_packet_ctor must generate IPv4 GRE Ethernet frame");
>>>>  
>>>>  	note("... with outer Ethernet header");
>>>>  	cmp_mem_lit_incr(data, (0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd), "    ...
>>>> with correct dest MAC");
>>>>
>>>
>>
>>
>> ‹ 
>> Regards,
>> ++Keith
>> Intel Corporation
>>
>>
>>
>>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [dpdk-dev] [Pktgen] [PATCH] pktgen_setup_packets: fix race for packet header
  2015-10-02  9:23       ` Ilya Maximets
@ 2015-10-02 11:25         ` Wiles, Keith
  2015-10-12 14:09           ` Ilya Maximets
  0 siblings, 1 reply; 7+ messages in thread
From: Wiles, Keith @ 2015-10-02 11:25 UTC (permalink / raw)
  To: Ilya Maximets, dev; +Cc: Dyasly Sergey

I looked at the code and everything looks good. I will try to merge the
code next week as I am traveling again :-(

Thanks for the patch, I am glad you found this problem as I believe
someone else reported something odd in that area, but was not able to give
me many details.
— 
Regards,
++Keith Wiles

Intel Corporation




On 10/2/15, 10:23 AM, "Ilya Maximets" <i.maximets@samsung.com> wrote:

>Ping.
>
>On 17.09.2015 08:55, Ilya Maximets wrote:
>> Ok. Thank you. I'll wait.
>> 
>> On 16.09.2015 18:37, Wiles, Keith wrote:
>>> Thanks the patch looks fine, but I have not had a lot of time to
>>>review it
>>> detail. I hope to get to it next week after I return back home.
>>>
>>> On 9/16/15, 2:09 AM, "Ilya Maximets" <i.maximets@samsung.com> wrote:
>>>
>>>> Ping.
>>>>
>>>> On 09.09.2015 17:22, Ilya Maximets wrote:
>>>>> While pktgen_setup_packets() all threads of one port uses same
>>>>> info->seq_pkt. This leads to constructing packets in the same memory
>>>>> region
>>>>> (&pkt->hdr). As a result, pktgen_setup_packets generates random
>>>>>headers.
>>>>>
>>>>> Fix that by making a local copy of info->seq_pkt and using it for
>>>>> constructing of packets.
>>>>>
>>>>> Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
>>>>> ---
>>>>>  app/pktgen-arp.c  |  2 +-
>>>>>  app/pktgen-cmds.c | 40 ++++++++++++++++++++--------------------
>>>>>  app/pktgen-ipv4.c |  2 +-
>>>>>  app/pktgen.c      | 39 +++++++++++++++++++++++++++------------
>>>>>  app/pktgen.h      |  4 ++--
>>>>>  app/t/pktgen.t.c  |  6 +++---
>>>>>  6 files changed, 54 insertions(+), 39 deletions(-)
>>>>>
>>>>> diff --git a/app/pktgen-arp.c b/app/pktgen-arp.c
>>>>> index c378880..b7040d7 100644
>>>>> --- a/app/pktgen-arp.c
>>>>> +++ b/app/pktgen-arp.c
>>>>> @@ -190,7 +190,7 @@ pktgen_process_arp( struct rte_mbuf * m, uint32_t
>>>>> pid, uint32_t vlan )
>>>>>  
>>>>>  				rte_memcpy(&pkt->eth_dst_addr, &arp->sha, 6);
>>>>>  				for (i = 0; i < info->seqCnt; i++)
>>>>> -					pktgen_packet_ctor(info, i, -1);
>>>>> +					pktgen_packet_ctor(info, i, -1, NULL);
>>>>>  			}
>>>>>  
>>>>>  			// Swap the two MAC addresses
>>>>> diff --git a/app/pktgen-cmds.c b/app/pktgen-cmds.c
>>>>> index da040e5..a6abb41 100644
>>>>> --- a/app/pktgen-cmds.c
>>>>> +++ b/app/pktgen-cmds.c
>>>>> @@ -931,7 +931,7 @@ pktgen_set_proto(port_info_t * info, char type)
>>>>>  	if ( type == 'i' )
>>>>>  		info->seq_pkt[SINGLE_PKT].ethType = ETHER_TYPE_IPv4;
>>>>>  
>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>  }
>>>>>  
>>>>>  
>>>>> 
>>>>>/*********************************************************************
>>>>>***
>>>>> **//**
>>>>> @@ -1067,7 +1067,7 @@ pktgen_set_pkt_type(port_info_t * info, const
>>>>> char * type)
>>>>>  										(type[3] == '6') ? ETHER_TYPE_IPv6 :
>>>>>  										/* TODO print error: unknown type */ ETHER_TYPE_IPv4;
>>>>>  
>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>  }
>>>>>  
>>>>>  
>>>>> 
>>>>>/*********************************************************************
>>>>>***
>>>>> **//**
>>>>> @@ -1092,7 +1092,7 @@ pktgen_set_vlan(port_info_t * info, uint32_t
>>>>> onOff)
>>>>>  	}
>>>>>  	else
>>>>>  		pktgen_clr_port_flags(info, SEND_VLAN_ID);
>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>  }
>>>>>  
>>>>>  
>>>>> 
>>>>>/*********************************************************************
>>>>>***
>>>>> **//**
>>>>> @@ -1112,7 +1112,7 @@ pktgen_set_vlanid(port_info_t * info, uint16_t
>>>>> vlanid)
>>>>>  {
>>>>>  	info->vlanid = vlanid;
>>>>>  	info->seq_pkt[SINGLE_PKT].vlanid = info->vlanid;
>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>  }
>>>>>  
>>>>>  
>>>>> 
>>>>>/*********************************************************************
>>>>>***
>>>>> **//**
>>>>> @@ -1137,7 +1137,7 @@ pktgen_set_mpls(port_info_t * info, uint32_t
>>>>> onOff)
>>>>>  	}
>>>>>  	else
>>>>>  		pktgen_clr_port_flags(info, SEND_MPLS_LABEL);
>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>  }
>>>>>  
>>>>>  
>>>>> 
>>>>>/*********************************************************************
>>>>>***
>>>>> **//**
>>>>> @@ -1157,7 +1157,7 @@ pktgen_set_mpls_entry(port_info_t * info,
>>>>> uint32_t mpls_entry)
>>>>>  {
>>>>>  	info->mpls_entry = mpls_entry;
>>>>>  	info->seq_pkt[SINGLE_PKT].mpls_entry = info->mpls_entry;
>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>  }
>>>>>  
>>>>>  
>>>>> 
>>>>>/*********************************************************************
>>>>>***
>>>>> **//**
>>>>> @@ -1182,7 +1182,7 @@ pktgen_set_qinq(port_info_t * info, uint32_t
>>>>> onOff)
>>>>>  	}
>>>>>  	else
>>>>>  		pktgen_clr_port_flags(info, SEND_Q_IN_Q_IDS);
>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>  }
>>>>>  
>>>>>  
>>>>> 
>>>>>/*********************************************************************
>>>>>***
>>>>> **//**
>>>>> @@ -1204,7 +1204,7 @@ pktgen_set_qinqids(port_info_t * info, uint16_t
>>>>> outerid, uint16_t innerid)
>>>>>  	info->seq_pkt[SINGLE_PKT].qinq_outerid = info->qinq_outerid;
>>>>>  	info->qinq_innerid = innerid;
>>>>>  	info->seq_pkt[SINGLE_PKT].qinq_innerid = info->qinq_innerid;
>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>  }
>>>>>  
>>>>>  
>>>>> 
>>>>>/*********************************************************************
>>>>>***
>>>>> **//**
>>>>> @@ -1228,7 +1228,7 @@ pktgen_set_gre(port_info_t * info, uint32_t
>>>>>onOff)
>>>>>  	}
>>>>>  	else
>>>>>  		pktgen_clr_port_flags(info, SEND_GRE_IPv4_HEADER);
>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>  }
>>>>>  
>>>>>  
>>>>> 
>>>>>/*********************************************************************
>>>>>***
>>>>> **//**
>>>>> @@ -1252,7 +1252,7 @@ pktgen_set_gre_eth(port_info_t * info, uint32_t
>>>>> onOff)
>>>>>  	}
>>>>>  	else
>>>>>  		pktgen_clr_port_flags(info, SEND_GRE_ETHER_HEADER);
>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>  }
>>>>>  
>>>>>  
>>>>> 
>>>>>/*********************************************************************
>>>>>***
>>>>> **//**
>>>>> @@ -1272,7 +1272,7 @@ pktgen_set_gre_key(port_info_t * info, uint32_t
>>>>> gre_key)
>>>>>  {
>>>>>  	info->gre_key = gre_key;
>>>>>  	info->seq_pkt[SINGLE_PKT].gre_key = info->gre_key;
>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>  }
>>>>>  
>>>>>  
>>>>> 
>>>>>/*********************************************************************
>>>>>***
>>>>> **//**
>>>>> @@ -1401,7 +1401,7 @@ void pktgen_port_defaults(uint32_t pid, uint8_t
>>>>> seq)
>>>>>  		memset(&pkt->eth_dst_addr, 0, sizeof (pkt->eth_dst_addr));
>>>>>  
>>>>>  
>>>>> -	pktgen_packet_ctor(info, seq, -1);
>>>>> +	pktgen_packet_ctor(info, seq, -1, NULL);
>>>>>  
>>>>>      pktgen.flags	|= PRINT_LABELS_FLAG;
>>>>>  }
>>>>> @@ -1423,7 +1423,7 @@ void pktgen_ping4(port_info_t * info)
>>>>>  	memcpy(&info->seq_pkt[PING_PKT],
>>>>>  		   &info->seq_pkt[SINGLE_PKT], sizeof(pkt_seq_t));
>>>>>  	info->seq_pkt[PING_PKT].ipProto = PG_IPPROTO_ICMP;
>>>>> -	pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO);
>>>>> +	pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO, NULL);
>>>>>  	pktgen_set_port_flags(info, SEND_PING4_REQUEST);
>>>>>  }
>>>>>  
>>>>> @@ -1445,7 +1445,7 @@ void pktgen_ping6(port_info_t * info)
>>>>>  	memcpy(&info->pkt[PING_PKT],
>>>>>  		   &info->pkt[SINGLE_PKT], sizeof(pkt_seq_t));
>>>>>  	info->pkt[PING_PKT].ipProto = PG_IPPROTO_ICMP;
>>>>> -	pktgen_packet_ctor(info, PING_PKT, ICMP6_ECHO);
>>>>> +	pktgen_packet_ctor(info, PING_PKT, ICMP6_ECHO, NULL);
>>>>>  	pktgen_set_port_flags(info, SEND_PING6_REQUEST);
>>>>>  }
>>>>>  #endif
>>>>> @@ -1645,7 +1645,7 @@ void pktgen_set_pkt_size(port_info_t * info,
>>>>> uint32_t size)
>>>>>  	else if ( (size - FCS_SIZE) > MAX_PKT_SIZE)
>>>>>  		size = MAX_PKT_SIZE + FCS_SIZE;
>>>>>  	info->seq_pkt[SINGLE_PKT].pktSize = (size - FCS_SIZE);
>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>  	pktgen_packet_rate(info);
>>>>>  }
>>>>>  
>>>>> @@ -1667,7 +1667,7 @@ void pktgen_set_port_value(port_info_t * info,
>>>>> char type, uint32_t portValue)
>>>>>  		info->seq_pkt[SINGLE_PKT].dport = (uint16_t)portValue;
>>>>>  	else
>>>>>  		info->seq_pkt[SINGLE_PKT].sport = (uint16_t)portValue;
>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>  }
>>>>>  
>>>>>  
>>>>> 
>>>>>/*********************************************************************
>>>>>***
>>>>> **//**
>>>>> @@ -1711,7 +1711,7 @@ void pktgen_set_ipaddr(port_info_t * info, char
>>>>> type, cmdline_ipaddr_t * ip)
>>>>>  		info->seq_pkt[SINGLE_PKT].ip_src_addr =
>>>>>ntohl(ip->addr.ipv4.s_addr);
>>>>>  	} else
>>>>>  		info->seq_pkt[SINGLE_PKT].ip_dst_addr =
>>>>>ntohl(ip->addr.ipv4.s_addr);
>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>  }
>>>>>  
>>>>>  
>>>>> 
>>>>>/*********************************************************************
>>>>>***
>>>>> **//**
>>>>> @@ -1729,7 +1729,7 @@ void pktgen_set_ipaddr(port_info_t * info, char
>>>>> type, cmdline_ipaddr_t * ip)
>>>>>  void pktgen_set_dst_mac(port_info_t * info, cmdline_etheraddr_t *
>>>>>mac)
>>>>>  {
>>>>>  	memcpy(&info->seq_pkt[SINGLE_PKT].eth_dst_addr, mac->mac, 6);
>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>  }
>>>>>  
>>>>>  
>>>>> 
>>>>>/*********************************************************************
>>>>>***
>>>>> **//**
>>>>> @@ -2111,7 +2111,7 @@ void pktgen_set_seq(port_info_t * info,
>>>>>uint32_t
>>>>> seqnum,
>>>>>  		type = '4';
>>>>>  	pkt->ethType		= (type == '6')? ETHER_TYPE_IPv6 : ETHER_TYPE_IPv4;
>>>>>  	pkt->vlanid			= vlanid;
>>>>> -	pktgen_packet_ctor(info, seqnum, -1);
>>>>> +	pktgen_packet_ctor(info, seqnum, -1, NULL);
>>>>>  }
>>>>>  
>>>>>  
>>>>> 
>>>>>/*********************************************************************
>>>>>***
>>>>> **//**
>>>>> @@ -2156,7 +2156,7 @@ void pktgen_compile_pkt(port_info_t * info,
>>>>> uint32_t seqnum,
>>>>>  						  (type == '6')? ETHER_TYPE_IPv6 :
>>>>>  						  (type == 'n')? ETHER_TYPE_VLAN : ETHER_TYPE_IPv4;
>>>>>  	pkt->vlanid			= vlanid;
>>>>> -	pktgen_packet_ctor(info, seqnum, -1);
>>>>> +	pktgen_packet_ctor(info, seqnum, -1, NULL);
>>>>>  }
>>>>>  
>>>>>  
>>>>> 
>>>>>/*********************************************************************
>>>>>***
>>>>> **//**
>>>>> diff --git a/app/pktgen-ipv4.c b/app/pktgen-ipv4.c
>>>>> index 7813c36..a8b6be2 100644
>>>>> --- a/app/pktgen-ipv4.c
>>>>> +++ b/app/pktgen-ipv4.c
>>>>> @@ -138,7 +138,7 @@ pktgen_send_ping4( uint32_t pid, uint8_t seq_idx
>>>>>)
>>>>>          return;
>>>>>      }
>>>>>  	*ppkt = *spkt;		// Copy the sequence setup to the ping setup.
>>>>> -    pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO);
>>>>> +    pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO, NULL);
>>>>>  	rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t
>>>>> *)&ppkt->hdr, ppkt->pktSize);
>>>>>  
>>>>>      m->pkt_len  = ppkt->pktSize;
>>>>> diff --git a/app/pktgen.c b/app/pktgen.c
>>>>> index 2dcdbfd..ecd4560 100644
>>>>> --- a/app/pktgen.c
>>>>> +++ b/app/pktgen.c
>>>>> @@ -401,8 +401,8 @@ static __inline__ int pktgen_has_work(void) {
>>>>>  */
>>>>>  
>>>>>  void
>>>>> -pktgen_packet_ctor(port_info_t * info, int32_t seq_idx, int32_t
>>>>>type) {
>>>>> -	pkt_seq_t		  * pkt = &info->seq_pkt[seq_idx];
>>>>> +pktgen_packet_ctor(port_info_t * info, int32_t seq_idx, int32_t
>>>>>type,
>>>>> pkt_seq_t * seq_pkt) {
>>>>> +	pkt_seq_t		  * pkt = (seq_pkt == NULL) ? &info->seq_pkt[seq_idx] :
>>>>> &seq_pkt[seq_idx];
>>>>>  	struct ether_hdr  * eth = (struct ether_hdr *)&pkt->hdr.eth;
>>>>>  	uint16_t			tlen;
>>>>>  
>>>>> @@ -812,22 +812,35 @@ static __inline__ void
>>>>>  pktgen_setup_packets(port_info_t * info, struct rte_mempool * mp,
>>>>> uint16_t qid)
>>>>>  {
>>>>>  	struct rte_mbuf	* m, * mm;
>>>>> -	pkt_seq_t * pkt;
>>>>> +	pkt_seq_t * pkt, * seq_pkt = NULL;
>>>>> +	uint16_t seqIdx;
>>>>> +	char buff[RTE_MEMZONE_NAMESIZE];
>>>>>  
>>>>>  	pktgen_clr_q_flags(info, qid, CLEAR_FAST_ALLOC_FLAG);
>>>>>  
>>>>>  	if ( mp == info->q[qid].pcap_mp )
>>>>>  		return;
>>>>>  
>>>>> +	snprintf(buff, sizeof(buff), "tmp_seq_pkt_%d_%d", info->pid, qid);
>>>>> +	seq_pkt = (pkt_seq_t *)rte_zmalloc(buff,
>>>>> +				(sizeof(pkt_seq_t) * NUM_TOTAL_PKTS), RTE_CACHE_LINE_SIZE);
>>>>> +	if (seq_pkt == NULL)
>>>>> +		pktgen_log_panic("Unable to allocate %d pkt_seq_t headers",
>>>>> +						 NUM_TOTAL_PKTS);
>>>>> +	/* Copy global configuration to construct new packets locally */
>>>>> +	rte_memcpy((uint8_t *)seq_pkt, (uint8_t *)info->seq_pkt,
>>>>> +			   sizeof(pkt_seq_t) * NUM_TOTAL_PKTS);
>>>>> +	seqIdx = info->seqIdx;
>>>>> +
>>>>>  	mm	= NULL;
>>>>>  	pkt = NULL;
>>>>>  
>>>>>  	if ( mp == info->q[qid].tx_mp )
>>>>> -		pkt = &info->seq_pkt[SINGLE_PKT];
>>>>> +		pkt = &seq_pkt[SINGLE_PKT];
>>>>>  	else if ( mp == info->q[qid].range_mp )
>>>>> -		pkt = &info->seq_pkt[RANGE_PKT];
>>>>> +		pkt = &seq_pkt[RANGE_PKT];
>>>>>  	else if ( mp == info->q[qid].seq_mp )
>>>>> -		pkt = &info->seq_pkt[info->seqIdx];
>>>>> +		pkt = &seq_pkt[seqIdx];
>>>>>  
>>>>>  	// allocate each mbuf and put them on a list to be freed.
>>>>>  	for(;;) {
>>>>> @@ -840,7 +853,7 @@ pktgen_setup_packets(port_info_t * info, struct
>>>>> rte_mempool * mp, uint16_t qid)
>>>>>  		mm = m;
>>>>>  
>>>>>  		if ( mp == info->q[qid].tx_mp ) {
>>>>> -			pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>> +			pktgen_packet_ctor(info, SINGLE_PKT, -1, seq_pkt);
>>>>>  
>>>>>  			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t
>>>>> *)&pkt->hdr, MAX_PKT_SIZE);
>>>>>  
>>>>> @@ -848,16 +861,16 @@ pktgen_setup_packets(port_info_t * info, struct
>>>>> rte_mempool * mp, uint16_t qid)
>>>>>  			m->data_len = pkt->pktSize;
>>>>>  		} else if ( mp == info->q[qid].range_mp ) {
>>>>>  			pktgen_range_ctor(&info->range, pkt);
>>>>> -			pktgen_packet_ctor(info, RANGE_PKT, -1);
>>>>> +			pktgen_packet_ctor(info, RANGE_PKT, -1, seq_pkt);
>>>>>  
>>>>>  			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t
>>>>> *)&pkt->hdr, MAX_PKT_SIZE);
>>>>>  
>>>>>  			m->pkt_len  = pkt->pktSize;
>>>>>  			m->data_len = pkt->pktSize;
>>>>>  		} else if ( mp == info->q[qid].seq_mp ) {
>>>>> -			pktgen_packet_ctor(info, info->seqIdx++, -1);
>>>>> -			if ( unlikely(info->seqIdx >= info->seqCnt) )
>>>>> -				info->seqIdx = 0;
>>>>> +			pktgen_packet_ctor(info, seqIdx++, -1, seq_pkt);
>>>>> +			if ( unlikely(seqIdx >= info->seqCnt) )
>>>>> +				seqIdx = 0;
>>>>>  
>>>>>  			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t
>>>>> *)&pkt->hdr, MAX_PKT_SIZE);
>>>>>  
>>>>> @@ -865,12 +878,14 @@ pktgen_setup_packets(port_info_t * info, struct
>>>>> rte_mempool * mp, uint16_t qid)
>>>>>  			m->data_len = pkt->pktSize;
>>>>>  
>>>>>  			// move to the next packet in the sequence.
>>>>> -			pkt = &info->seq_pkt[info->seqIdx];
>>>>> +			pkt = &seq_pkt[seqIdx];
>>>>>  		}
>>>>>  	}
>>>>>  
>>>>>  	if ( mm != NULL )
>>>>>  		rte_pktmbuf_free(mm);
>>>>> +
>>>>> +	rte_free(seq_pkt);
>>>>>  }
>>>>>  
>>>>>  
>>>>> 
>>>>>/*********************************************************************
>>>>>***
>>>>> **//**
>>>>> diff --git a/app/pktgen.h b/app/pktgen.h
>>>>> index 2c5c98c..f3f76f2 100644
>>>>> --- a/app/pktgen.h
>>>>> +++ b/app/pktgen.h
>>>>> @@ -151,7 +151,7 @@
>>>>>  #include "pktgen-port-cfg.h"
>>>>>  #include "pktgen-capture.h"
>>>>>  #include "pktgen-log.h"
>>>>> -
>>>>> +#include "pktgen-seq.h"
>>>>>  
>>>>>  #define PKTGEN_VERSION			"2.9.2"
>>>>>  #define PKTGEN_APP_NAME			"Pktgen"
>>>>> @@ -386,7 +386,7 @@ extern pktgen_t		pktgen;
>>>>>  
>>>>>  extern void pktgen_page_display(__attribute__((unused)) struct
>>>>> rte_timer *tim, __attribute__((unused)) void *arg);
>>>>>  
>>>>> -extern void pktgen_packet_ctor(port_info_t * info, int32_t seq_idx,
>>>>> int32_t type);
>>>>> +extern void pktgen_packet_ctor(port_info_t * info, int32_t seq_idx,
>>>>> int32_t type, pkt_seq_t * seq_pkt);
>>>>>  extern void pktgen_packet_rate(port_info_t * info);
>>>>>  
>>>>>  extern void pktgen_send_mbuf(struct rte_mbuf *m, uint8_t pid,
>>>>>uint16_t
>>>>> qid);
>>>>> diff --git a/app/t/pktgen.t.c b/app/t/pktgen.t.c
>>>>> index 0eca4c4..77bf300 100644
>>>>> --- a/app/t/pktgen.t.c
>>>>> +++ b/app/t/pktgen.t.c
>>>>> @@ -77,7 +77,7 @@ void test_pktgen_packet_ctor_IPv4_UDP(void)
>>>>>  	};
>>>>>  
>>>>>  
>>>>> -	lives_ok( { pktgen_packet_ctor(&info, 0, 0); }, "pktgen_packet_ctor
>>>>> must generate IPv4/UDP");
>>>>> +	lives_ok( { pktgen_packet_ctor(&info, 0, 0, NULL); },
>>>>> "pktgen_packet_ctor must generate IPv4/UDP");
>>>>>  
>>>>>  	note("... with Ethernet header");
>>>>>  	cmp_mem_lit_incr(data, (0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd), "
>>>>>...
>>>>> with correct dest MAC");
>>>>> @@ -133,9 +133,9 @@ void test_pktgen_packet_ctor_IPv4_GRE_Ether(void)
>>>>>  		.pktSize      = 102,		// Subtract 4 for FCS
>>>>>  	};
>>>>>  
>>>>> -	pktgen_packet_ctor(&info, 0, 0);
>>>>> +	pktgen_packet_ctor(&info, 0, 0, NULL);
>>>>>  
>>>>> -	lives_ok( { pktgen_packet_ctor(&info, 0, 0); }, "pktgen_packet_ctor
>>>>> must generate IPv4 GRE Ethernet frame");
>>>>> +	lives_ok( { pktgen_packet_ctor(&info, 0, 0, NULL); },
>>>>> "pktgen_packet_ctor must generate IPv4 GRE Ethernet frame");
>>>>>  
>>>>>  	note("... with outer Ethernet header");
>>>>>  	cmp_mem_lit_incr(data, (0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd), "
>>>>>...
>>>>> with correct dest MAC");
>>>>>
>>>>
>>>
>>>
>>> ‹ 
>>> Regards,
>>> ++Keith
>>> Intel Corporation
>>>
>>>
>>>
>>>


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [dpdk-dev] [Pktgen] [PATCH] pktgen_setup_packets: fix race for packet header
  2015-10-02 11:25         ` Wiles, Keith
@ 2015-10-12 14:09           ` Ilya Maximets
  0 siblings, 0 replies; 7+ messages in thread
From: Ilya Maximets @ 2015-10-12 14:09 UTC (permalink / raw)
  To: Wiles, Keith, dev; +Cc: Dyasly Sergey

Sorry for pinging, but have you tried to merge this patch?

Best regards, Ilya Maximets.

On 02.10.2015 14:25, Wiles, Keith wrote:
> I looked at the code and everything looks good. I will try to merge the
> code next week as I am traveling again :-(
> 
> Thanks for the patch, I am glad you found this problem as I believe
> someone else reported something odd in that area, but was not able to give
> me many details.
> — 
> Regards,
> ++Keith Wiles
> 
> Intel Corporation
> 
> 
> 
> 
> On 10/2/15, 10:23 AM, "Ilya Maximets" <i.maximets@samsung.com> wrote:
> 
>> Ping.
>>
>> On 17.09.2015 08:55, Ilya Maximets wrote:
>>> Ok. Thank you. I'll wait.
>>>
>>> On 16.09.2015 18:37, Wiles, Keith wrote:
>>>> Thanks the patch looks fine, but I have not had a lot of time to
>>>> review it
>>>> detail. I hope to get to it next week after I return back home.
>>>>
>>>> On 9/16/15, 2:09 AM, "Ilya Maximets" <i.maximets@samsung.com> wrote:
>>>>
>>>>> Ping.
>>>>>
>>>>> On 09.09.2015 17:22, Ilya Maximets wrote:
>>>>>> While pktgen_setup_packets() all threads of one port uses same
>>>>>> info->seq_pkt. This leads to constructing packets in the same memory
>>>>>> region
>>>>>> (&pkt->hdr). As a result, pktgen_setup_packets generates random
>>>>>> headers.
>>>>>>
>>>>>> Fix that by making a local copy of info->seq_pkt and using it for
>>>>>> constructing of packets.
>>>>>>
>>>>>> Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
>>>>>> ---
>>>>>>  app/pktgen-arp.c  |  2 +-
>>>>>>  app/pktgen-cmds.c | 40 ++++++++++++++++++++--------------------
>>>>>>  app/pktgen-ipv4.c |  2 +-
>>>>>>  app/pktgen.c      | 39 +++++++++++++++++++++++++++------------
>>>>>>  app/pktgen.h      |  4 ++--
>>>>>>  app/t/pktgen.t.c  |  6 +++---
>>>>>>  6 files changed, 54 insertions(+), 39 deletions(-)
>>>>>>
>>>>>> diff --git a/app/pktgen-arp.c b/app/pktgen-arp.c
>>>>>> index c378880..b7040d7 100644
>>>>>> --- a/app/pktgen-arp.c
>>>>>> +++ b/app/pktgen-arp.c
>>>>>> @@ -190,7 +190,7 @@ pktgen_process_arp( struct rte_mbuf * m, uint32_t
>>>>>> pid, uint32_t vlan )
>>>>>>  
>>>>>>  				rte_memcpy(&pkt->eth_dst_addr, &arp->sha, 6);
>>>>>>  				for (i = 0; i < info->seqCnt; i++)
>>>>>> -					pktgen_packet_ctor(info, i, -1);
>>>>>> +					pktgen_packet_ctor(info, i, -1, NULL);
>>>>>>  			}
>>>>>>  
>>>>>>  			// Swap the two MAC addresses
>>>>>> diff --git a/app/pktgen-cmds.c b/app/pktgen-cmds.c
>>>>>> index da040e5..a6abb41 100644
>>>>>> --- a/app/pktgen-cmds.c
>>>>>> +++ b/app/pktgen-cmds.c
>>>>>> @@ -931,7 +931,7 @@ pktgen_set_proto(port_info_t * info, char type)
>>>>>>  	if ( type == 'i' )
>>>>>>  		info->seq_pkt[SINGLE_PKT].ethType = ETHER_TYPE_IPv4;
>>>>>>  
>>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>>  }
>>>>>>  
>>>>>>  
>>>>>>
>>>>>> /*********************************************************************
>>>>>> ***
>>>>>> **//**
>>>>>> @@ -1067,7 +1067,7 @@ pktgen_set_pkt_type(port_info_t * info, const
>>>>>> char * type)
>>>>>>  										(type[3] == '6') ? ETHER_TYPE_IPv6 :
>>>>>>  										/* TODO print error: unknown type */ ETHER_TYPE_IPv4;
>>>>>>  
>>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>>  }
>>>>>>  
>>>>>>  
>>>>>>
>>>>>> /*********************************************************************
>>>>>> ***
>>>>>> **//**
>>>>>> @@ -1092,7 +1092,7 @@ pktgen_set_vlan(port_info_t * info, uint32_t
>>>>>> onOff)
>>>>>>  	}
>>>>>>  	else
>>>>>>  		pktgen_clr_port_flags(info, SEND_VLAN_ID);
>>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>>  }
>>>>>>  
>>>>>>  
>>>>>>
>>>>>> /*********************************************************************
>>>>>> ***
>>>>>> **//**
>>>>>> @@ -1112,7 +1112,7 @@ pktgen_set_vlanid(port_info_t * info, uint16_t
>>>>>> vlanid)
>>>>>>  {
>>>>>>  	info->vlanid = vlanid;
>>>>>>  	info->seq_pkt[SINGLE_PKT].vlanid = info->vlanid;
>>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>>  }
>>>>>>  
>>>>>>  
>>>>>>
>>>>>> /*********************************************************************
>>>>>> ***
>>>>>> **//**
>>>>>> @@ -1137,7 +1137,7 @@ pktgen_set_mpls(port_info_t * info, uint32_t
>>>>>> onOff)
>>>>>>  	}
>>>>>>  	else
>>>>>>  		pktgen_clr_port_flags(info, SEND_MPLS_LABEL);
>>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>>  }
>>>>>>  
>>>>>>  
>>>>>>
>>>>>> /*********************************************************************
>>>>>> ***
>>>>>> **//**
>>>>>> @@ -1157,7 +1157,7 @@ pktgen_set_mpls_entry(port_info_t * info,
>>>>>> uint32_t mpls_entry)
>>>>>>  {
>>>>>>  	info->mpls_entry = mpls_entry;
>>>>>>  	info->seq_pkt[SINGLE_PKT].mpls_entry = info->mpls_entry;
>>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>>  }
>>>>>>  
>>>>>>  
>>>>>>
>>>>>> /*********************************************************************
>>>>>> ***
>>>>>> **//**
>>>>>> @@ -1182,7 +1182,7 @@ pktgen_set_qinq(port_info_t * info, uint32_t
>>>>>> onOff)
>>>>>>  	}
>>>>>>  	else
>>>>>>  		pktgen_clr_port_flags(info, SEND_Q_IN_Q_IDS);
>>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>>  }
>>>>>>  
>>>>>>  
>>>>>>
>>>>>> /*********************************************************************
>>>>>> ***
>>>>>> **//**
>>>>>> @@ -1204,7 +1204,7 @@ pktgen_set_qinqids(port_info_t * info, uint16_t
>>>>>> outerid, uint16_t innerid)
>>>>>>  	info->seq_pkt[SINGLE_PKT].qinq_outerid = info->qinq_outerid;
>>>>>>  	info->qinq_innerid = innerid;
>>>>>>  	info->seq_pkt[SINGLE_PKT].qinq_innerid = info->qinq_innerid;
>>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>>  }
>>>>>>  
>>>>>>  
>>>>>>
>>>>>> /*********************************************************************
>>>>>> ***
>>>>>> **//**
>>>>>> @@ -1228,7 +1228,7 @@ pktgen_set_gre(port_info_t * info, uint32_t
>>>>>> onOff)
>>>>>>  	}
>>>>>>  	else
>>>>>>  		pktgen_clr_port_flags(info, SEND_GRE_IPv4_HEADER);
>>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>>  }
>>>>>>  
>>>>>>  
>>>>>>
>>>>>> /*********************************************************************
>>>>>> ***
>>>>>> **//**
>>>>>> @@ -1252,7 +1252,7 @@ pktgen_set_gre_eth(port_info_t * info, uint32_t
>>>>>> onOff)
>>>>>>  	}
>>>>>>  	else
>>>>>>  		pktgen_clr_port_flags(info, SEND_GRE_ETHER_HEADER);
>>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>>  }
>>>>>>  
>>>>>>  
>>>>>>
>>>>>> /*********************************************************************
>>>>>> ***
>>>>>> **//**
>>>>>> @@ -1272,7 +1272,7 @@ pktgen_set_gre_key(port_info_t * info, uint32_t
>>>>>> gre_key)
>>>>>>  {
>>>>>>  	info->gre_key = gre_key;
>>>>>>  	info->seq_pkt[SINGLE_PKT].gre_key = info->gre_key;
>>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>>  }
>>>>>>  
>>>>>>  
>>>>>>
>>>>>> /*********************************************************************
>>>>>> ***
>>>>>> **//**
>>>>>> @@ -1401,7 +1401,7 @@ void pktgen_port_defaults(uint32_t pid, uint8_t
>>>>>> seq)
>>>>>>  		memset(&pkt->eth_dst_addr, 0, sizeof (pkt->eth_dst_addr));
>>>>>>  
>>>>>>  
>>>>>> -	pktgen_packet_ctor(info, seq, -1);
>>>>>> +	pktgen_packet_ctor(info, seq, -1, NULL);
>>>>>>  
>>>>>>      pktgen.flags	|= PRINT_LABELS_FLAG;
>>>>>>  }
>>>>>> @@ -1423,7 +1423,7 @@ void pktgen_ping4(port_info_t * info)
>>>>>>  	memcpy(&info->seq_pkt[PING_PKT],
>>>>>>  		   &info->seq_pkt[SINGLE_PKT], sizeof(pkt_seq_t));
>>>>>>  	info->seq_pkt[PING_PKT].ipProto = PG_IPPROTO_ICMP;
>>>>>> -	pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO);
>>>>>> +	pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO, NULL);
>>>>>>  	pktgen_set_port_flags(info, SEND_PING4_REQUEST);
>>>>>>  }
>>>>>>  
>>>>>> @@ -1445,7 +1445,7 @@ void pktgen_ping6(port_info_t * info)
>>>>>>  	memcpy(&info->pkt[PING_PKT],
>>>>>>  		   &info->pkt[SINGLE_PKT], sizeof(pkt_seq_t));
>>>>>>  	info->pkt[PING_PKT].ipProto = PG_IPPROTO_ICMP;
>>>>>> -	pktgen_packet_ctor(info, PING_PKT, ICMP6_ECHO);
>>>>>> +	pktgen_packet_ctor(info, PING_PKT, ICMP6_ECHO, NULL);
>>>>>>  	pktgen_set_port_flags(info, SEND_PING6_REQUEST);
>>>>>>  }
>>>>>>  #endif
>>>>>> @@ -1645,7 +1645,7 @@ void pktgen_set_pkt_size(port_info_t * info,
>>>>>> uint32_t size)
>>>>>>  	else if ( (size - FCS_SIZE) > MAX_PKT_SIZE)
>>>>>>  		size = MAX_PKT_SIZE + FCS_SIZE;
>>>>>>  	info->seq_pkt[SINGLE_PKT].pktSize = (size - FCS_SIZE);
>>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>>  	pktgen_packet_rate(info);
>>>>>>  }
>>>>>>  
>>>>>> @@ -1667,7 +1667,7 @@ void pktgen_set_port_value(port_info_t * info,
>>>>>> char type, uint32_t portValue)
>>>>>>  		info->seq_pkt[SINGLE_PKT].dport = (uint16_t)portValue;
>>>>>>  	else
>>>>>>  		info->seq_pkt[SINGLE_PKT].sport = (uint16_t)portValue;
>>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>>  }
>>>>>>  
>>>>>>  
>>>>>>
>>>>>> /*********************************************************************
>>>>>> ***
>>>>>> **//**
>>>>>> @@ -1711,7 +1711,7 @@ void pktgen_set_ipaddr(port_info_t * info, char
>>>>>> type, cmdline_ipaddr_t * ip)
>>>>>>  		info->seq_pkt[SINGLE_PKT].ip_src_addr =
>>>>>> ntohl(ip->addr.ipv4.s_addr);
>>>>>>  	} else
>>>>>>  		info->seq_pkt[SINGLE_PKT].ip_dst_addr =
>>>>>> ntohl(ip->addr.ipv4.s_addr);
>>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>>  }
>>>>>>  
>>>>>>  
>>>>>>
>>>>>> /*********************************************************************
>>>>>> ***
>>>>>> **//**
>>>>>> @@ -1729,7 +1729,7 @@ void pktgen_set_ipaddr(port_info_t * info, char
>>>>>> type, cmdline_ipaddr_t * ip)
>>>>>>  void pktgen_set_dst_mac(port_info_t * info, cmdline_etheraddr_t *
>>>>>> mac)
>>>>>>  {
>>>>>>  	memcpy(&info->seq_pkt[SINGLE_PKT].eth_dst_addr, mac->mac, 6);
>>>>>> -	pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>>> +	pktgen_packet_ctor(info, SINGLE_PKT, -1, NULL);
>>>>>>  }
>>>>>>  
>>>>>>  
>>>>>>
>>>>>> /*********************************************************************
>>>>>> ***
>>>>>> **//**
>>>>>> @@ -2111,7 +2111,7 @@ void pktgen_set_seq(port_info_t * info,
>>>>>> uint32_t
>>>>>> seqnum,
>>>>>>  		type = '4';
>>>>>>  	pkt->ethType		= (type == '6')? ETHER_TYPE_IPv6 : ETHER_TYPE_IPv4;
>>>>>>  	pkt->vlanid			= vlanid;
>>>>>> -	pktgen_packet_ctor(info, seqnum, -1);
>>>>>> +	pktgen_packet_ctor(info, seqnum, -1, NULL);
>>>>>>  }
>>>>>>  
>>>>>>  
>>>>>>
>>>>>> /*********************************************************************
>>>>>> ***
>>>>>> **//**
>>>>>> @@ -2156,7 +2156,7 @@ void pktgen_compile_pkt(port_info_t * info,
>>>>>> uint32_t seqnum,
>>>>>>  						  (type == '6')? ETHER_TYPE_IPv6 :
>>>>>>  						  (type == 'n')? ETHER_TYPE_VLAN : ETHER_TYPE_IPv4;
>>>>>>  	pkt->vlanid			= vlanid;
>>>>>> -	pktgen_packet_ctor(info, seqnum, -1);
>>>>>> +	pktgen_packet_ctor(info, seqnum, -1, NULL);
>>>>>>  }
>>>>>>  
>>>>>>  
>>>>>>
>>>>>> /*********************************************************************
>>>>>> ***
>>>>>> **//**
>>>>>> diff --git a/app/pktgen-ipv4.c b/app/pktgen-ipv4.c
>>>>>> index 7813c36..a8b6be2 100644
>>>>>> --- a/app/pktgen-ipv4.c
>>>>>> +++ b/app/pktgen-ipv4.c
>>>>>> @@ -138,7 +138,7 @@ pktgen_send_ping4( uint32_t pid, uint8_t seq_idx
>>>>>> )
>>>>>>          return;
>>>>>>      }
>>>>>>  	*ppkt = *spkt;		// Copy the sequence setup to the ping setup.
>>>>>> -    pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO);
>>>>>> +    pktgen_packet_ctor(info, PING_PKT, ICMP4_ECHO, NULL);
>>>>>>  	rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t
>>>>>> *)&ppkt->hdr, ppkt->pktSize);
>>>>>>  
>>>>>>      m->pkt_len  = ppkt->pktSize;
>>>>>> diff --git a/app/pktgen.c b/app/pktgen.c
>>>>>> index 2dcdbfd..ecd4560 100644
>>>>>> --- a/app/pktgen.c
>>>>>> +++ b/app/pktgen.c
>>>>>> @@ -401,8 +401,8 @@ static __inline__ int pktgen_has_work(void) {
>>>>>>  */
>>>>>>  
>>>>>>  void
>>>>>> -pktgen_packet_ctor(port_info_t * info, int32_t seq_idx, int32_t
>>>>>> type) {
>>>>>> -	pkt_seq_t		  * pkt = &info->seq_pkt[seq_idx];
>>>>>> +pktgen_packet_ctor(port_info_t * info, int32_t seq_idx, int32_t
>>>>>> type,
>>>>>> pkt_seq_t * seq_pkt) {
>>>>>> +	pkt_seq_t		  * pkt = (seq_pkt == NULL) ? &info->seq_pkt[seq_idx] :
>>>>>> &seq_pkt[seq_idx];
>>>>>>  	struct ether_hdr  * eth = (struct ether_hdr *)&pkt->hdr.eth;
>>>>>>  	uint16_t			tlen;
>>>>>>  
>>>>>> @@ -812,22 +812,35 @@ static __inline__ void
>>>>>>  pktgen_setup_packets(port_info_t * info, struct rte_mempool * mp,
>>>>>> uint16_t qid)
>>>>>>  {
>>>>>>  	struct rte_mbuf	* m, * mm;
>>>>>> -	pkt_seq_t * pkt;
>>>>>> +	pkt_seq_t * pkt, * seq_pkt = NULL;
>>>>>> +	uint16_t seqIdx;
>>>>>> +	char buff[RTE_MEMZONE_NAMESIZE];
>>>>>>  
>>>>>>  	pktgen_clr_q_flags(info, qid, CLEAR_FAST_ALLOC_FLAG);
>>>>>>  
>>>>>>  	if ( mp == info->q[qid].pcap_mp )
>>>>>>  		return;
>>>>>>  
>>>>>> +	snprintf(buff, sizeof(buff), "tmp_seq_pkt_%d_%d", info->pid, qid);
>>>>>> +	seq_pkt = (pkt_seq_t *)rte_zmalloc(buff,
>>>>>> +				(sizeof(pkt_seq_t) * NUM_TOTAL_PKTS), RTE_CACHE_LINE_SIZE);
>>>>>> +	if (seq_pkt == NULL)
>>>>>> +		pktgen_log_panic("Unable to allocate %d pkt_seq_t headers",
>>>>>> +						 NUM_TOTAL_PKTS);
>>>>>> +	/* Copy global configuration to construct new packets locally */
>>>>>> +	rte_memcpy((uint8_t *)seq_pkt, (uint8_t *)info->seq_pkt,
>>>>>> +			   sizeof(pkt_seq_t) * NUM_TOTAL_PKTS);
>>>>>> +	seqIdx = info->seqIdx;
>>>>>> +
>>>>>>  	mm	= NULL;
>>>>>>  	pkt = NULL;
>>>>>>  
>>>>>>  	if ( mp == info->q[qid].tx_mp )
>>>>>> -		pkt = &info->seq_pkt[SINGLE_PKT];
>>>>>> +		pkt = &seq_pkt[SINGLE_PKT];
>>>>>>  	else if ( mp == info->q[qid].range_mp )
>>>>>> -		pkt = &info->seq_pkt[RANGE_PKT];
>>>>>> +		pkt = &seq_pkt[RANGE_PKT];
>>>>>>  	else if ( mp == info->q[qid].seq_mp )
>>>>>> -		pkt = &info->seq_pkt[info->seqIdx];
>>>>>> +		pkt = &seq_pkt[seqIdx];
>>>>>>  
>>>>>>  	// allocate each mbuf and put them on a list to be freed.
>>>>>>  	for(;;) {
>>>>>> @@ -840,7 +853,7 @@ pktgen_setup_packets(port_info_t * info, struct
>>>>>> rte_mempool * mp, uint16_t qid)
>>>>>>  		mm = m;
>>>>>>  
>>>>>>  		if ( mp == info->q[qid].tx_mp ) {
>>>>>> -			pktgen_packet_ctor(info, SINGLE_PKT, -1);
>>>>>> +			pktgen_packet_ctor(info, SINGLE_PKT, -1, seq_pkt);
>>>>>>  
>>>>>>  			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t
>>>>>> *)&pkt->hdr, MAX_PKT_SIZE);
>>>>>>  
>>>>>> @@ -848,16 +861,16 @@ pktgen_setup_packets(port_info_t * info, struct
>>>>>> rte_mempool * mp, uint16_t qid)
>>>>>>  			m->data_len = pkt->pktSize;
>>>>>>  		} else if ( mp == info->q[qid].range_mp ) {
>>>>>>  			pktgen_range_ctor(&info->range, pkt);
>>>>>> -			pktgen_packet_ctor(info, RANGE_PKT, -1);
>>>>>> +			pktgen_packet_ctor(info, RANGE_PKT, -1, seq_pkt);
>>>>>>  
>>>>>>  			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t
>>>>>> *)&pkt->hdr, MAX_PKT_SIZE);
>>>>>>  
>>>>>>  			m->pkt_len  = pkt->pktSize;
>>>>>>  			m->data_len = pkt->pktSize;
>>>>>>  		} else if ( mp == info->q[qid].seq_mp ) {
>>>>>> -			pktgen_packet_ctor(info, info->seqIdx++, -1);
>>>>>> -			if ( unlikely(info->seqIdx >= info->seqCnt) )
>>>>>> -				info->seqIdx = 0;
>>>>>> +			pktgen_packet_ctor(info, seqIdx++, -1, seq_pkt);
>>>>>> +			if ( unlikely(seqIdx >= info->seqCnt) )
>>>>>> +				seqIdx = 0;
>>>>>>  
>>>>>>  			rte_memcpy((uint8_t *)m->buf_addr + m->data_off, (uint8_t
>>>>>> *)&pkt->hdr, MAX_PKT_SIZE);
>>>>>>  
>>>>>> @@ -865,12 +878,14 @@ pktgen_setup_packets(port_info_t * info, struct
>>>>>> rte_mempool * mp, uint16_t qid)
>>>>>>  			m->data_len = pkt->pktSize;
>>>>>>  
>>>>>>  			// move to the next packet in the sequence.
>>>>>> -			pkt = &info->seq_pkt[info->seqIdx];
>>>>>> +			pkt = &seq_pkt[seqIdx];
>>>>>>  		}
>>>>>>  	}
>>>>>>  
>>>>>>  	if ( mm != NULL )
>>>>>>  		rte_pktmbuf_free(mm);
>>>>>> +
>>>>>> +	rte_free(seq_pkt);
>>>>>>  }
>>>>>>  
>>>>>>  
>>>>>>
>>>>>> /*********************************************************************
>>>>>> ***
>>>>>> **//**
>>>>>> diff --git a/app/pktgen.h b/app/pktgen.h
>>>>>> index 2c5c98c..f3f76f2 100644
>>>>>> --- a/app/pktgen.h
>>>>>> +++ b/app/pktgen.h
>>>>>> @@ -151,7 +151,7 @@
>>>>>>  #include "pktgen-port-cfg.h"
>>>>>>  #include "pktgen-capture.h"
>>>>>>  #include "pktgen-log.h"
>>>>>> -
>>>>>> +#include "pktgen-seq.h"
>>>>>>  
>>>>>>  #define PKTGEN_VERSION			"2.9.2"
>>>>>>  #define PKTGEN_APP_NAME			"Pktgen"
>>>>>> @@ -386,7 +386,7 @@ extern pktgen_t		pktgen;
>>>>>>  
>>>>>>  extern void pktgen_page_display(__attribute__((unused)) struct
>>>>>> rte_timer *tim, __attribute__((unused)) void *arg);
>>>>>>  
>>>>>> -extern void pktgen_packet_ctor(port_info_t * info, int32_t seq_idx,
>>>>>> int32_t type);
>>>>>> +extern void pktgen_packet_ctor(port_info_t * info, int32_t seq_idx,
>>>>>> int32_t type, pkt_seq_t * seq_pkt);
>>>>>>  extern void pktgen_packet_rate(port_info_t * info);
>>>>>>  
>>>>>>  extern void pktgen_send_mbuf(struct rte_mbuf *m, uint8_t pid,
>>>>>> uint16_t
>>>>>> qid);
>>>>>> diff --git a/app/t/pktgen.t.c b/app/t/pktgen.t.c
>>>>>> index 0eca4c4..77bf300 100644
>>>>>> --- a/app/t/pktgen.t.c
>>>>>> +++ b/app/t/pktgen.t.c
>>>>>> @@ -77,7 +77,7 @@ void test_pktgen_packet_ctor_IPv4_UDP(void)
>>>>>>  	};
>>>>>>  
>>>>>>  
>>>>>> -	lives_ok( { pktgen_packet_ctor(&info, 0, 0); }, "pktgen_packet_ctor
>>>>>> must generate IPv4/UDP");
>>>>>> +	lives_ok( { pktgen_packet_ctor(&info, 0, 0, NULL); },
>>>>>> "pktgen_packet_ctor must generate IPv4/UDP");
>>>>>>  
>>>>>>  	note("... with Ethernet header");
>>>>>>  	cmp_mem_lit_incr(data, (0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd), "
>>>>>> ...
>>>>>> with correct dest MAC");
>>>>>> @@ -133,9 +133,9 @@ void test_pktgen_packet_ctor_IPv4_GRE_Ether(void)
>>>>>>  		.pktSize      = 102,		// Subtract 4 for FCS
>>>>>>  	};
>>>>>>  
>>>>>> -	pktgen_packet_ctor(&info, 0, 0);
>>>>>> +	pktgen_packet_ctor(&info, 0, 0, NULL);
>>>>>>  
>>>>>> -	lives_ok( { pktgen_packet_ctor(&info, 0, 0); }, "pktgen_packet_ctor
>>>>>> must generate IPv4 GRE Ethernet frame");
>>>>>> +	lives_ok( { pktgen_packet_ctor(&info, 0, 0, NULL); },
>>>>>> "pktgen_packet_ctor must generate IPv4 GRE Ethernet frame");
>>>>>>  
>>>>>>  	note("... with outer Ethernet header");
>>>>>>  	cmp_mem_lit_incr(data, (0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd), "
>>>>>> ...
>>>>>> with correct dest MAC");
>>>>>>
>>>>>
>>>>
>>>>
>>>> ‹ 
>>>> Regards,
>>>> ++Keith
>>>> Intel Corporation
>>>>
>>>>
>>>>
>>>>
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2015-10-12 14:09 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-09 14:22 [dpdk-dev] [Pktgen] [PATCH] pktgen_setup_packets: fix race for packet header Ilya Maximets
2015-09-16  9:09 ` Ilya Maximets
2015-09-16 15:37   ` Wiles, Keith
2015-09-17  5:55     ` Ilya Maximets
2015-10-02  9:23       ` Ilya Maximets
2015-10-02 11:25         ` Wiles, Keith
2015-10-12 14:09           ` Ilya Maximets

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).