From patchwork Thu Jul 25 12:04:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 57095 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 F41C31C33B; Thu, 25 Jul 2019 14:04:33 +0200 (CEST) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by dpdk.org (Postfix) with ESMTP id E1CB21C30F; Thu, 25 Jul 2019 14:04:30 +0200 (CEST) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5995EC05E760; Thu, 25 Jul 2019 12:04:30 +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 4BFCB60852; Thu, 25 Jul 2019 12:04:29 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: ferruh.yigit@intel.com, stable@dpdk.org Date: Thu, 25 Jul 2019 14:04:18 +0200 Message-Id: <1564056260-18125-2-git-send-email-david.marchand@redhat.com> In-Reply-To: <1564056260-18125-1-git-send-email-david.marchand@redhat.com> References: <1563969270-29669-1-git-send-email-david.marchand@redhat.com> <1564056260-18125-1-git-send-email-david.marchand@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Thu, 25 Jul 2019 12:04:30 +0000 (UTC) Subject: [dpdk-dev] [PATCH v2 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 @@ eth_pcap_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) 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 @@ eth_pcap_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) 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 Thu Jul 25 12:04:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 57096 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 E18051C343; Thu, 25 Jul 2019 14:04:37 +0200 (CEST) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by dpdk.org (Postfix) with ESMTP id 9707A1C335; Thu, 25 Jul 2019 14:04:32 +0200 (CEST) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E01FC821D1; Thu, 25 Jul 2019 12:04:31 +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 D2A9160852; Thu, 25 Jul 2019 12:04:30 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: ferruh.yigit@intel.com, stable@dpdk.org Date: Thu, 25 Jul 2019 14:04:19 +0200 Message-Id: <1564056260-18125-3-git-send-email-david.marchand@redhat.com> In-Reply-To: <1564056260-18125-1-git-send-email-david.marchand@redhat.com> References: <1563969270-29669-1-git-send-email-david.marchand@redhat.com> <1564056260-18125-1-git-send-email-david.marchand@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 25 Jul 2019 12:04:31 +0000 (UTC) Subject: [dpdk-dev] [PATCH v2 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 Acked-by: Ferruh Yigit --- Changelog since v1: - restored the original behavior if pcap_sendpacket returns an error --- drivers/net/pcap/rte_eth_pcap.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c index 470867d..bfc0756 100644 --- a/drivers/net/pcap/rte_eth_pcap.c +++ b/drivers/net/pcap/rte_eth_pcap.c @@ -354,7 +354,8 @@ eth_pcap_tx_dumper(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) mbuf->pkt_len, RTE_ETHER_MAX_JUMBO_FRAME_LEN); - break; + rte_pktmbuf_free(mbuf); + continue; } } @@ -373,7 +374,7 @@ eth_pcap_tx_dumper(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) dumper_q->tx_stat.bytes += tx_bytes; dumper_q->tx_stat.err_pkts += nb_pkts - num_tx; - return num_tx; + return nb_pkts; } /* @@ -439,7 +440,8 @@ eth_pcap_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) mbuf->pkt_len, RTE_ETHER_MAX_JUMBO_FRAME_LEN); - break; + rte_pktmbuf_free(mbuf); + continue; } } @@ -452,9 +454,9 @@ eth_pcap_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) tx_queue->tx_stat.pkts += num_tx; tx_queue->tx_stat.bytes += tx_bytes; - tx_queue->tx_stat.err_pkts += nb_pkts - num_tx; + tx_queue->tx_stat.err_pkts += i - num_tx; - return num_tx; + return i; } /* From patchwork Thu Jul 25 12:04:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 57097 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 B09241C348; Thu, 25 Jul 2019 14:04:40 +0200 (CEST) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by dpdk.org (Postfix) with ESMTP id 0B5991C33C; Thu, 25 Jul 2019 14:04:34 +0200 (CEST) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 79D8C80F81; Thu, 25 Jul 2019 12:04:33 +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 5F95A60852; Thu, 25 Jul 2019 12:04:32 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: ferruh.yigit@intel.com, stable@dpdk.org Date: Thu, 25 Jul 2019 14:04:20 +0200 Message-Id: <1564056260-18125-4-git-send-email-david.marchand@redhat.com> In-Reply-To: <1564056260-18125-1-git-send-email-david.marchand@redhat.com> References: <1563969270-29669-1-git-send-email-david.marchand@redhat.com> <1564056260-18125-1-git-send-email-david.marchand@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Thu, 25 Jul 2019 12:04:33 +0000 (UTC) Subject: [dpdk-dev] [PATCH v2 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() when necessary (if the mbuf is contiguous, rte_pktmbuf_read() just points at the buffer address). With this change, we won't support mono segment mbuf larger than 16k. Fixes: 6db141c91e1f ("pcap: support jumbo frames") Cc: stable@dpdk.org Signed-off-by: David Marchand --- Changelog since v1: - rely on rte_pktmbuf_read to handle both mono and multi segments cases --- drivers/net/pcap/rte_eth_pcap.c | 93 ++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 57 deletions(-) diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c index bfc0756..7a5fb6a 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 @@ eth_pcap_rx_jumbo(struct rte_mempool *mb_pool, struct rte_mbuf *mbuf, 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,8 @@ eth_pcap_tx_dumper(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) uint32_t tx_bytes = 0; struct pcap_pkthdr header; pcap_dumper_t *dumper; + unsigned char temp_data[RTE_ETH_PCAP_SNAPLEN]; + size_t len; pp = rte_eth_devices[dumper_q->port_id].process_private; dumper = pp->tx_dumper[dumper_q->queue_id]; @@ -336,31 +322,27 @@ eth_pcap_tx_dumper(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) * dumper */ for (i = 0; i < nb_pkts; i++) { mbuf = bufs[i]; + len = rte_pktmbuf_pkt_len(mbuf); + if (unlikely(!rte_pktmbuf_is_contiguous(mbuf) && + len > sizeof(temp_data))) { + PMD_LOG(ERR, "Dropping multi segment PCAP packet. Size (%zd) > max size (%zd).", + len, sizeof(temp_data)); + rte_pktmbuf_free(mbuf); + continue; + } + calculate_timestamp(&header.ts); - header.len = mbuf->pkt_len; + header.len = len; header.caplen = header.len; - - if (likely(mbuf->nb_segs == 1)) { - pcap_dump((u_char *)dumper, &header, - rte_pktmbuf_mtod(mbuf, void*)); - } 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; - } - } + /* rte_pktmbuf_read() returns a pointer to the data directly + * in the mbuf (when the mbuf is contiguous) or, otherwise, + * a pointer to temp_data after copying into it. + */ + pcap_dump((u_char *)dumper, &header, + rte_pktmbuf_read(mbuf, 0, len, temp_data)); num_tx++; - tx_bytes += mbuf->pkt_len; + tx_bytes += len; rte_pktmbuf_free(mbuf); } @@ -415,6 +397,8 @@ eth_pcap_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) uint16_t num_tx = 0; uint32_t tx_bytes = 0; pcap_t *pcap; + unsigned char temp_data[RTE_ETH_PCAP_SNAPLEN]; + size_t len; pp = rte_eth_devices[tx_queue->port_id].process_private; pcap = pp->tx_pcap[tx_queue->queue_id]; @@ -424,31 +408,26 @@ eth_pcap_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) 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); - } 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; - } + len = rte_pktmbuf_pkt_len(mbuf); + if (unlikely(!rte_pktmbuf_is_contiguous(mbuf) && + len > sizeof(temp_data))) { + PMD_LOG(ERR, "Dropping multi segment PCAP packet. Size (%zd) > max size (%zd).", + len, sizeof(temp_data)); + rte_pktmbuf_free(mbuf); + continue; } + /* rte_pktmbuf_read() returns a pointer to the data directly + * in the mbuf (when the mbuf is contiguous) or, otherwise, + * a pointer to temp_data after copying into it. + */ + ret = pcap_sendpacket(pcap, + rte_pktmbuf_read(mbuf, 0, len, temp_data), + len); if (unlikely(ret != 0)) break; num_tx++; - tx_bytes += mbuf->pkt_len; + tx_bytes += len; rte_pktmbuf_free(mbuf); }