From patchwork Fri Aug 20 13:39:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tudor Cornea X-Patchwork-Id: 97163 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 79D94A0C4D; Fri, 20 Aug 2021 15:40:11 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 39FCF4013F; Fri, 20 Aug 2021 15:40:11 +0200 (CEST) Received: from mail-wr1-f43.google.com (mail-wr1-f43.google.com [209.85.221.43]) by mails.dpdk.org (Postfix) with ESMTP id 7F6F64003E for ; Fri, 20 Aug 2021 15:40:10 +0200 (CEST) Received: by mail-wr1-f43.google.com with SMTP id q6so14352208wrv.6 for ; Fri, 20 Aug 2021 06:40:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=hPXQlYur07B1u5mEk+PZu2Ru/hZPKnO8BuqFj3N7iww=; b=fENfLiMpHu5MY51DIZkj/WUNSYK9/qyKJqfEU3rNGYvlRjgKcvl58gTZ9kQEsJKs+g ANujS/S5kjD8534lXaFyC2eRYXrNbM6yzetKEl0g24zU10t6642K/uPhkkPBVWBydagH gWkLyUEwYnCMHPwx9pKfsgzycBXlVse+N+c7siAAaDpvWOI5YrUUIhFTqWOs75CMW3fs KO1TU1pd3Y/yJktu9FwZxURGPVjsKOL7f20gyLPI5trQnmBC3/FrEKYwTaw4Aq+iEnlP OeKCBX+2ysmniIZXYWCrspiHY+sgaEPW2R40cPdbufRLp68ORJ7VSa1nA2WPoDE8WFT8 8pmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=hPXQlYur07B1u5mEk+PZu2Ru/hZPKnO8BuqFj3N7iww=; b=D7f9EobVdIVXG6W/RMag8LKAHlbteMIueEaJdU6RwOzR1iXMoWisJPQclvnndKb5YJ 5XczULoo2p9Z0y6zIQov5fu1g7PG1L/AEYIx1tsyCpSjPyK2buiHSV8H3PWhNGNwDpCQ BqFflcglvqlVbm1EjjYuiMRcSXeY7lAIeNjHVL9weI379bFsCmlXXuQI3urpmZInQHSW RFglnxnYICDmC/Td9LIx5SxVl3207JorSVFN1hyp21zjGWqjx6QxASclnlXJ6Tr/h2fL UhoLU88i01IqhaLVPdsK1zuKlh2neCtm/nkcjcXmds4UXp+fLiNuVY4rqTzPlOewiXLk gUpA== X-Gm-Message-State: AOAM531HdOkFBWKhnREHLQs/E9/ADVoXokBQL9HJUnfxY2lB0w+yBePj pvJLZVb4mSskBilerIHYoLo= X-Google-Smtp-Source: ABdhPJzZN3/CEFo2l4BBOvvKXNmwiOVsfT5Qygh3FOUIAvpHAPwHUN3QlViot3q9HOWBFqptFOUH7A== X-Received: by 2002:a05:6000:14f:: with SMTP id r15mr10547072wrx.18.1629466810277; Fri, 20 Aug 2021 06:40:10 -0700 (PDT) Received: from tucornea-dev-machine.localdomain ([193.226.172.42]) by smtp.gmail.com with ESMTPSA id g35sm11742895wmp.9.2021.08.20.06.40.09 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 20 Aug 2021 06:40:09 -0700 (PDT) From: Tudor Cornea To: linville@tuxdriver.com Cc: thomas@monjalon.net, dev@dpdk.org, Tudor Cornea , Mihai Pogonaru Date: Fri, 20 Aug 2021 16:39:21 +0300 Message-Id: <1629466761-127333-1-git-send-email-tudor.cornea@gmail.com> X-Mailer: git-send-email 2.7.4 Subject: [dpdk-dev] [PATCH] net/af_packet: fix ignoring full ring on tx X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" The poll call can return POLLERR which is ignored, or it can return POLLOUT, even if there are no free frames in the mmap-ed area. We can account for both of these cases by re-checking if the next frame is empty before writing into it. We also now eliminate the timestamp status from the frame status. Signed-off-by: Mihai Pogonaru Signed-off-by: Tudor Cornea --- drivers/net/af_packet/rte_eth_af_packet.c | 47 +++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c index b73b211..3845df5 100644 --- a/drivers/net/af_packet/rte_eth_af_packet.c +++ b/drivers/net/af_packet/rte_eth_af_packet.c @@ -167,6 +167,12 @@ eth_af_packet_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) return num_rx; } +static inline __u32 tx_ring_status_remove_ts(volatile __u32 *tp_status) +{ + return *tp_status & + ~(TP_STATUS_TS_SOFTWARE | TP_STATUS_TS_RAW_HARDWARE); +} + /* * Callback to handle sending packets through a real NIC. */ @@ -211,9 +217,41 @@ eth_af_packet_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) } } + /* + * We must eliminate the timestamp status from the packet + * status. This should only matter if timestamping is enabled + * on the socket, but there is a BUG in the kernel which is + * fixed in newer releases. + + * For interfaces of type 'veth', the sent skb is forwarded + * to the peer and back into the network stack which timestamps + * it on the RX path if timestamping is enabled globally + * (which happens if any socket enables timestamping). + + * When the skb is destructed, tpacket_destruct_skb() is called + * and it calls __packet_set_timestamp() which doesn't check + * the flags on the socket and returns the timestamp if it is + * set in the skb (and for veth it is, as mentioned above). + */ + /* point at the next incoming frame */ - if ((ppd->tp_status != TP_STATUS_AVAILABLE) && - (poll(&pfd, 1, -1) < 0)) + if ((tx_ring_status_remove_ts(&ppd->tp_status) + != TP_STATUS_AVAILABLE) && (poll(&pfd, 1, -1) < 0)) + break; + + /* + * Poll can return POLLERR if the interface is down or POLLOUT, + * even if there are no extra buffers available. + * This happens, because packet_poll() calls datagram_poll() + * which checks the space left in the socket buffer and in the + * case of packet_mmap the default socket buffer length + * doesn't match the requested size for the tx_ring so there + * is always space left in socket buffer, which doesn't seem + * to be correlated to the requested size for the tx_ring + * in packet_mmap. + */ + if (tx_ring_status_remove_ts(&ppd->tp_status) + != TP_STATUS_AVAILABLE) break; /* copy the tx frame data */ @@ -242,6 +280,11 @@ eth_af_packet_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) rte_pktmbuf_free(mbuf); } + /* + * We might have to ignore a few more errnos here since the packets + * remain in the mmap-ed queue and will be sent later, presumably. + */ + /* kick-off transmits */ if (sendto(pkt_q->sockfd, NULL, 0, MSG_DONTWAIT, NULL, 0) == -1 && errno != ENOBUFS && errno != EAGAIN) {