From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id A4743A046B for ; Wed, 24 Jul 2019 13:55:04 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 9A91F1C1E4; Wed, 24 Jul 2019 13:54:51 +0200 (CEST) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by dpdk.org (Postfix) with ESMTP id 6A63B1C1D3; Wed, 24 Jul 2019 13:54:46 +0200 (CEST) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DA8787FDEC; Wed, 24 Jul 2019 11:54:45 +0000 (UTC) Received: from dmarchan.remote.csb (ovpn-204-235.brq.redhat.com [10.40.204.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id AB45E601B7; Wed, 24 Jul 2019 11:54:44 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: ferruh.yigit@intel.com, stable@dpdk.org Date: Wed, 24 Jul 2019 13:54:30 +0200 Message-Id: <1563969270-29669-4-git-send-email-david.marchand@redhat.com> In-Reply-To: <1563969270-29669-1-git-send-email-david.marchand@redhat.com> References: <1563969270-29669-1-git-send-email-david.marchand@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Wed, 24 Jul 2019 11:54:45 +0000 (UTC) Subject: [dpdk-dev] [PATCH 3/3] net/pcap: fix concurrent multiseg packet transmits X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Two cores can send multi segment packets on two different pcap ports. Because of this, we can't have one single buffer to linearize packets. Use rte_pktmbuf_read() to copy the packet into a buffer on the stack and remove eth_pcap_gather_data(). Fixes: 6db141c91e1f ("pcap: support jumbo frames") Cc: stable@dpdk.org Signed-off-by: David Marchand --- drivers/net/pcap/rte_eth_pcap.c | 90 +++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 58 deletions(-) diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c index 5e5aab7..7398b1b 100644 --- a/drivers/net/pcap/rte_eth_pcap.c +++ b/drivers/net/pcap/rte_eth_pcap.c @@ -46,7 +46,6 @@ #define RTE_PMD_PCAP_MAX_QUEUES 16 static char errbuf[PCAP_ERRBUF_SIZE]; -static unsigned char tx_pcap_data[RTE_ETH_PCAP_SNAPLEN]; static struct timeval start_time; static uint64_t start_cycles; static uint64_t hz; @@ -180,21 +179,6 @@ struct pmd_devargs_all { return mbuf->nb_segs; } -/* Copy data from mbuf chain to a buffer suitable for writing to a PCAP file. */ -static void -eth_pcap_gather_data(unsigned char *data, struct rte_mbuf *mbuf) -{ - uint16_t data_len = 0; - - while (mbuf) { - rte_memcpy(data + data_len, rte_pktmbuf_mtod(mbuf, void *), - mbuf->data_len); - - data_len += mbuf->data_len; - mbuf = mbuf->next; - } -} - static uint16_t eth_pcap_rx_infinite(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) { @@ -325,6 +309,9 @@ struct pmd_devargs_all { uint32_t tx_bytes = 0; struct pcap_pkthdr header; pcap_dumper_t *dumper; + unsigned char _data[RTE_ETH_PCAP_SNAPLEN]; + const unsigned char *data; + size_t len; pp = rte_eth_devices[dumper_q->port_id].process_private; dumper = pp->tx_dumper[dumper_q->queue_id]; @@ -336,31 +323,25 @@ struct pmd_devargs_all { * dumper */ for (i = 0; i < nb_pkts; i++) { mbuf = bufs[i]; - calculate_timestamp(&header.ts); - header.len = mbuf->pkt_len; - header.caplen = header.len; - - if (likely(mbuf->nb_segs == 1)) { - pcap_dump((u_char *)dumper, &header, - rte_pktmbuf_mtod(mbuf, void*)); + len = rte_pktmbuf_pkt_len(mbuf); + if (likely(rte_pktmbuf_is_contiguous(mbuf))) { + data = rte_pktmbuf_mtod(mbuf, unsigned char *); + } else if (len <= sizeof(_data)) { + data = rte_pktmbuf_read(mbuf, 0, len, _data); } else { - if (mbuf->pkt_len <= RTE_ETHER_MAX_JUMBO_FRAME_LEN) { - eth_pcap_gather_data(tx_pcap_data, mbuf); - pcap_dump((u_char *)dumper, &header, - tx_pcap_data); - } else { - PMD_LOG(ERR, - "Dropping PCAP packet. Size (%d) > max jumbo size (%d).", - mbuf->pkt_len, - RTE_ETHER_MAX_JUMBO_FRAME_LEN); - - rte_pktmbuf_free(mbuf); - continue; - } + PMD_LOG(ERR, "Dropping PCAP packet. Size (%zd) > max size (%zd).", + len, sizeof(_data)); + rte_pktmbuf_free(mbuf); + continue; } + calculate_timestamp(&header.ts); + header.len = len; + header.caplen = header.len; + pcap_dump((u_char *)dumper, &header, data); + num_tx++; - tx_bytes += mbuf->pkt_len; + tx_bytes += len; rte_pktmbuf_free(mbuf); } @@ -408,13 +389,15 @@ struct pmd_devargs_all { eth_pcap_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) { unsigned int i; - int ret; struct rte_mbuf *mbuf; struct pmd_process_private *pp; struct pcap_tx_queue *tx_queue = queue; uint16_t num_tx = 0; uint32_t tx_bytes = 0; pcap_t *pcap; + unsigned char _data[RTE_ETH_PCAP_SNAPLEN]; + const unsigned char *data; + size_t len; pp = rte_eth_devices[tx_queue->port_id].process_private; pcap = pp->tx_pcap[tx_queue->queue_id]; @@ -424,30 +407,21 @@ struct pmd_devargs_all { for (i = 0; i < nb_pkts; i++) { mbuf = bufs[i]; - - if (likely(mbuf->nb_segs == 1)) { - ret = pcap_sendpacket(pcap, - rte_pktmbuf_mtod(mbuf, u_char *), - mbuf->pkt_len); + len = rte_pktmbuf_pkt_len(mbuf); + if (likely(rte_pktmbuf_is_contiguous(mbuf))) { + data = rte_pktmbuf_mtod(mbuf, unsigned char *); + } else if (len <= sizeof(_data)) { + data = rte_pktmbuf_read(mbuf, 0, len, _data); } else { - if (mbuf->pkt_len <= RTE_ETHER_MAX_JUMBO_FRAME_LEN) { - eth_pcap_gather_data(tx_pcap_data, mbuf); - ret = pcap_sendpacket(pcap, - tx_pcap_data, mbuf->pkt_len); - } else { - PMD_LOG(ERR, - "Dropping PCAP packet. Size (%d) > max jumbo size (%d).", - mbuf->pkt_len, - RTE_ETHER_MAX_JUMBO_FRAME_LEN); - - rte_pktmbuf_free(mbuf); - continue; - } + PMD_LOG(ERR, "Dropping PCAP packet. Size (%zd) > max size (%zd).", + len, sizeof(_data)); + rte_pktmbuf_free(mbuf); + continue; } - if (ret == 0) { + if (pcap_sendpacket(pcap, data, len) == 0) { num_tx++; - tx_bytes += mbuf->pkt_len; + tx_bytes += len; } rte_pktmbuf_free(mbuf); } -- 1.8.3.1