From patchwork Wed Jul 24 11:54:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 57013 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 2685D1C1D0; Wed, 24 Jul 2019 13:54:46 +0200 (CEST) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by dpdk.org (Postfix) with ESMTP id 536871C1CC; Wed, 24 Jul 2019 13:54:43 +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 8E18B302246D; Wed, 24 Jul 2019 11:54:42 +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 4F1F5601B7; Wed, 24 Jul 2019 11:54:41 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: ferruh.yigit@intel.com, stable@dpdk.org Date: Wed, 24 Jul 2019 13:54:28 +0200 Message-Id: <1563969270-29669-2-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.49]); Wed, 24 Jul 2019 11:54:42 +0000 (UTC) Subject: [dpdk-dev] [PATCH 1/3] net/pcap: fix Rx with small buffers 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" If the pkt pool contains only buffers smaller than the default headroom, then the driver will compute an invalid buffer size (negative value cast to an uint16_t). Rely on the mbuf api to check how much space is available in the mbuf. Fixes: 6eb0ae218a98 ("pcap: fix mbuf allocation") Cc: stable@dpdk.org Signed-off-by: David Marchand Acked-by: Ferruh Yigit --- drivers/net/pcap/rte_eth_pcap.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c index 322c18f..470867d 100644 --- a/drivers/net/pcap/rte_eth_pcap.c +++ b/drivers/net/pcap/rte_eth_pcap.c @@ -242,7 +242,6 @@ struct pmd_devargs_all { struct rte_mbuf *mbuf; struct pcap_rx_queue *pcap_q = queue; uint16_t num_rx = 0; - uint16_t buf_size; uint32_t rx_bytes = 0; pcap_t *pcap; @@ -265,11 +264,7 @@ struct pmd_devargs_all { if (unlikely(mbuf == NULL)) break; - /* Now get the space available for data in the mbuf */ - buf_size = rte_pktmbuf_data_room_size(pcap_q->mb_pool) - - RTE_PKTMBUF_HEADROOM; - - if (header.caplen <= buf_size) { + if (header.caplen <= rte_pktmbuf_tailroom(mbuf)) { /* pcap packet will fit in the mbuf, can copy it */ rte_memcpy(rte_pktmbuf_mtod(mbuf, void *), packet, header.caplen); From patchwork Wed Jul 24 11:54:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 57014 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id CFE991C1D9; Wed, 24 Jul 2019 13:54:48 +0200 (CEST) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by dpdk.org (Postfix) with ESMTP id C24DE1C1CE; Wed, 24 Jul 2019 13:54:44 +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 1DDEA3060485; Wed, 24 Jul 2019 11:54:44 +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 0B2C2601B7; Wed, 24 Jul 2019 11:54:42 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: ferruh.yigit@intel.com, stable@dpdk.org Date: Wed, 24 Jul 2019 13:54:29 +0200 Message-Id: <1563969270-29669-3-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.47]); Wed, 24 Jul 2019 11:54:44 +0000 (UTC) Subject: [dpdk-dev] [PATCH 2/3] net/pcap: fix transmit return count in error conditions 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" When a packet cannot be transmitted, the driver is supposed to free this packet and report it as handled. This is to prevent the application from retrying to send the same packet and ending up in a liveloop since the driver will never manage to send it. Fixes: 49a0a2ffd5db ("net/pcap: fix possible mbuf double freeing") Fixes: 6db141c91e1f ("pcap: support jumbo frames") CC: stable@dpdk.org Signed-off-by: David Marchand --- drivers/net/pcap/rte_eth_pcap.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c index 470867d..5e5aab7 100644 --- a/drivers/net/pcap/rte_eth_pcap.c +++ b/drivers/net/pcap/rte_eth_pcap.c @@ -354,7 +354,8 @@ struct pmd_devargs_all { mbuf->pkt_len, RTE_ETHER_MAX_JUMBO_FRAME_LEN); - break; + rte_pktmbuf_free(mbuf); + continue; } } @@ -373,7 +374,7 @@ struct pmd_devargs_all { dumper_q->tx_stat.bytes += tx_bytes; dumper_q->tx_stat.err_pkts += nb_pkts - num_tx; - return num_tx; + return nb_pkts; } /* @@ -439,14 +440,15 @@ struct pmd_devargs_all { mbuf->pkt_len, RTE_ETHER_MAX_JUMBO_FRAME_LEN); - break; + rte_pktmbuf_free(mbuf); + continue; } } - if (unlikely(ret != 0)) - break; - num_tx++; - tx_bytes += mbuf->pkt_len; + if (ret == 0) { + num_tx++; + tx_bytes += mbuf->pkt_len; + } rte_pktmbuf_free(mbuf); } @@ -454,7 +456,7 @@ struct pmd_devargs_all { tx_queue->tx_stat.bytes += tx_bytes; tx_queue->tx_stat.err_pkts += nb_pkts - num_tx; - return num_tx; + return nb_pkts; } /* From patchwork Wed Jul 24 11:54:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 57015 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org 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 Acked-by: Ferruh Yigit --- 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); }