From patchwork Wed Nov 23 09:57:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felix Fietkau X-Patchwork-Id: 13053348 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D984DC4332F for ; Wed, 23 Nov 2022 10:00:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=wMWVOW02YSLR9FV0X0qrQoJCYcFkbk4buNSzKUApmIc=; b=pYq4vot/fhZyFY zuEAp+PHgzZFmWtbKyO40cxwPCQ9Khj8gT+iBjdpNajx+KbtwQ/Eyobpk4cWHSbuZeI/27queMnwV sgKgvx0NiSXASR6ESYzsEo+y9fJRCge5LFzYX/s57Qmyy3hkhzVd+Bgh6hmprTsTc2DSr2zBGkbEg 12x8L7K+v9kCBCRE71WlT7pkgk7AmpYLfUUnYu1DBHSWA+ixxtPKeTQkCBKv7OwTMVPhvOiK/ebMU xTXJSfBoIwR6YBp11wXhhdCms/C+NaniYEssqqyNOdD5Wwaf8fkTvZM4JRafwq6cnq2iD7XTS89e5 SJ8Mo7Lhtqs3+VNKjVuQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oxmX5-00G9nF-1I; Wed, 23 Nov 2022 09:59:07 +0000 Received: from nbd.name ([46.4.11.11]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oxmWE-00G9Mh-6M; Wed, 23 Nov 2022 09:58:16 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nbd.name; s=20160729; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=TqAxL1ZNrPmWijqt9CG1x9FAOLdXO4JArQexSu8S6G0=; b=k2R54x1quzswJYr6SR1Uzq2CdC hRMZ/Ky1sWe/E2svBQUKe2pZivsAp3DbmHrcbxCmoSqS1KawTUmo2WYXGEdtHxc6uHZ6yVo2g8IEC VjwuLbM/QvlUZcJ/tWyp1GO8ZuJrN1YXaldjsQC65dQnqZ9jIdzhwRhmE/yGqbozah3k=; Received: from p200300daa7225c0894d890dd9e4669b3.dip0.t-ipconnect.de ([2003:da:a722:5c08:94d8:90dd:9e46:69b3] helo=Maecks.lan) by ds12 with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (Exim 4.94.2) (envelope-from ) id 1oxmVw-003vzk-T3; Wed, 23 Nov 2022 10:57:56 +0100 From: Felix Fietkau To: netdev@vger.kernel.org, John Crispin , Sean Wang , Mark Lee , Lorenzo Bianconi , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Matthias Brugger Cc: linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/5] net: ethernet: mtk_eth_soc: work around issue with sending small fragments Date: Wed, 23 Nov 2022 10:57:52 +0100 Message-Id: <20221123095754.36821-3-nbd@nbd.name> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221123095754.36821-1-nbd@nbd.name> References: <20221123095754.36821-1-nbd@nbd.name> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221123_015814_311197_594F0576 X-CRM114-Status: GOOD ( 15.04 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org When frames are sent with very small fragments, the DMA engine appears to lock up and transmit attempts time out. Fix this by detecting the presence of small fragments and use skb_gso_segment + skb_linearize to deal with them Signed-off-by: Felix Fietkau --- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 36 +++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index 4c9972a94451..e63d2c034ca3 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -1441,12 +1441,28 @@ static void mtk_wake_queue(struct mtk_eth *eth) } } +static bool mtk_skb_has_small_frag(struct sk_buff *skb) +{ + int min_size = 16; + int i; + + if (skb_headlen(skb) < min_size) + return true; + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) + if (skb_frag_size(&skb_shinfo(skb)->frags[i]) < min_size) + return true; + + return false; +} + static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct mtk_mac *mac = netdev_priv(dev); struct mtk_eth *eth = mac->hw; struct mtk_tx_ring *ring = ð->tx_ring; struct net_device_stats *stats = &dev->stats; + struct sk_buff *segs, *next; bool gso = false; int tx_num; @@ -1468,6 +1484,17 @@ static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_BUSY; } + if (skb_is_gso(skb) && mtk_skb_has_small_frag(skb)) { + segs = skb_gso_segment(skb, dev->features & ~NETIF_F_ALL_TSO); + if (IS_ERR(segs)) + goto drop; + + if (segs) { + consume_skb(skb); + skb = segs; + } + } + /* TSO: fill MSS info in tcp checksum field */ if (skb_is_gso(skb)) { if (skb_cow_head(skb, 0)) { @@ -1483,8 +1510,13 @@ static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) } } - if (mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) - goto drop; + skb_list_walk_safe(skb, skb, next) { + if ((mtk_skb_has_small_frag(skb) && skb_linearize(skb)) || + mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) { + stats->tx_dropped++; + dev_kfree_skb_any(skb); + } + } if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) netif_tx_stop_all_queues(dev);