Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp7085949rwb; Tue, 15 Nov 2022 07:31:34 -0800 (PST) X-Google-Smtp-Source: AA0mqf5OyHYOex+fZEQc+PTt3WluaboskypPkdb600e40i7w8n8E5+n3Vg9t/734Th2MyhRPguil X-Received: by 2002:a17:90a:f083:b0:212:f264:4ee6 with SMTP id cn3-20020a17090af08300b00212f2644ee6mr2766341pjb.189.1668526293784; Tue, 15 Nov 2022 07:31:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668526293; cv=none; d=google.com; s=arc-20160816; b=LiGIHxPq0VwTZTcrmsRo25OA9tcZ5LVhhgfvOROTB9silDeJ+I5Kdh+EpCcGmqLrDG YgjAr8BxGMDVzlJKM0dyt28w8tL9pTEJ2R2X0nUtZ3Pxi1bD4Bu7PxvTCa9Bu3nQo8fr QXa8N/bZCg0rC0revGXpXYA+1FSTkp5GCqc9xkV58JCYTBXX4Yz1+qdzI9jeV259S8OB B141I77C/yA35rC81leUNtse6Bu5eegmt4Zjar5qaDZ65VX0S7pqjb4C2ENm8usfA86l daQtshWer5Wsg0I2EkyX1sgtroqhoqlbU8eXuGDaGxFqUcs9U+xVLCixGBIZO8rgyesG owow== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from; bh=sY1pJG92TUkDgdSZ+sUiKL891FAFfyGwgIFH6fhI9/Q=; b=CICnAsppNg/z8MdfIifaq/mzuqn8kGTA7iNDOvPjJkPeWglU3gAmyX4IQczPZB9N1M mvRjTQP5Kmu+EaazHImLJ5bqhrRmt1D6r3PhHliBB/M1kl8uy8nkITxH0vxNEtrIyauw WBqzQZfsZX8xGsvImfVIeTbHQQl/DRTjErWtN/rfor/qFHz4w5OxhmHsSC04d7h6wvyU Kl3vEc7M/Ns37qOLGWjML2D+ELi12WvNBP1q0t6ECVECB3jJWy/rBQ4l+GVuun8xIC20 ZPvafBJ8BM1bjwTmZBqM1djN4mQyoXCmI/rNLmSCMCYoR3CltdkRvFsNihaB6GtN2RT4 6FCg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b3-20020a636703000000b00476d24ebb09si692786pgc.23.2022.11.15.07.31.05; Tue, 15 Nov 2022 07:31:33 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232301AbiKOOvf (ORCPT + 89 others); Tue, 15 Nov 2022 09:51:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36402 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230106AbiKOOv1 (ORCPT ); Tue, 15 Nov 2022 09:51:27 -0500 Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 25E2622500; Tue, 15 Nov 2022 06:51:26 -0800 (PST) Received: from dggpeml500025.china.huawei.com (unknown [172.30.72.56]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4NBTdL51DqzmVt7; Tue, 15 Nov 2022 22:51:02 +0800 (CST) Received: from dggpeml500006.china.huawei.com (7.185.36.76) by dggpeml500025.china.huawei.com (7.185.36.35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Tue, 15 Nov 2022 22:51:23 +0800 Received: from localhost.localdomain (10.175.112.70) by dggpeml500006.china.huawei.com (7.185.36.76) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Tue, 15 Nov 2022 22:51:23 +0800 From: Zhang Changzhong To: , , , , , CC: , , Subject: [PATCH net v2 3/3] net: nixge: fix tx queue handling Date: Tue, 15 Nov 2022 23:10:24 +0800 Message-ID: <1668525024-38409-4-git-send-email-zhangchangzhong@huawei.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1668525024-38409-1-git-send-email-zhangchangzhong@huawei.com> References: <1668525024-38409-1-git-send-email-zhangchangzhong@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.175.112.70] X-ClientProxiedBy: dggems701-chm.china.huawei.com (10.3.19.178) To dggpeml500006.china.huawei.com (7.185.36.76) X-CFilter-Loop: Reflected X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Currently the driver check for available space at the beginning of nixge_start_xmit(), and when there is not enough space for this packet, it returns NETDEV_TX_OK, which casues packet loss and memory leak. Instead the queue should be stopped after the packet is added to the BD when there may not be enough space for next packet. In addition, the queue should be wakeup only if there is enough space for a packet with max frags. Fixes: 492caffa8a1a ("net: ethernet: nixge: Add support for National Instruments XGE netdev") Signed-off-by: Zhang Changzhong --- drivers/net/ethernet/ni/nixge.c | 54 +++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/ni/nixge.c b/drivers/net/ethernet/ni/nixge.c index 91b7ebc..3776a03 100644 --- a/drivers/net/ethernet/ni/nixge.c +++ b/drivers/net/ethernet/ni/nixge.c @@ -457,6 +457,17 @@ static void nixge_tx_skb_unmap(struct nixge_priv *priv, } } +static int nixge_check_tx_bd_space(struct nixge_priv *priv, + int num_frag) +{ + struct nixge_hw_dma_bd *cur_p; + + cur_p = &priv->tx_bd_v[(priv->tx_bd_tail + num_frag) % TX_BD_NUM]; + if (cur_p->status & XAXIDMA_BD_STS_ALL_MASK) + return NETDEV_TX_BUSY; + return 0; +} + static void nixge_start_xmit_done(struct net_device *ndev) { struct nixge_priv *priv = netdev_priv(ndev); @@ -488,19 +499,13 @@ static void nixge_start_xmit_done(struct net_device *ndev) ndev->stats.tx_packets += packets; ndev->stats.tx_bytes += size; - if (packets) - netif_wake_queue(ndev); -} - -static int nixge_check_tx_bd_space(struct nixge_priv *priv, - int num_frag) -{ - struct nixge_hw_dma_bd *cur_p; + if (packets) { + /* Matches barrier in nixge_start_xmit */ + smp_mb(); - cur_p = &priv->tx_bd_v[(priv->tx_bd_tail + num_frag) % TX_BD_NUM]; - if (cur_p->status & XAXIDMA_BD_STS_ALL_MASK) - return NETDEV_TX_BUSY; - return 0; + if (!nixge_check_tx_bd_space(priv, MAX_SKB_FRAGS + 1)) + netif_wake_queue(ndev); + } } static netdev_tx_t nixge_start_xmit(struct sk_buff *skb, @@ -518,10 +523,15 @@ static netdev_tx_t nixge_start_xmit(struct sk_buff *skb, cur_p = &priv->tx_bd_v[priv->tx_bd_tail]; tx_skb = &priv->tx_skb[priv->tx_bd_tail]; - if (nixge_check_tx_bd_space(priv, num_frag + 1)) { - if (!netif_queue_stopped(ndev)) - netif_stop_queue(ndev); - return NETDEV_TX_OK; + if (unlikely(nixge_check_tx_bd_space(priv, num_frag + 1))) { + /* Should not happen as last start_xmit call should have + * checked for sufficient space and queue should only be + * woken when sufficient space is available. + */ + netif_stop_queue(ndev); + if (net_ratelimit()) + netdev_err(ndev, "BUG! TX Ring full when queue awake!\n"); + return NETDEV_TX_BUSY; } cur_phys = dma_map_single(ndev->dev.parent, skb->data, @@ -572,6 +582,18 @@ static netdev_tx_t nixge_start_xmit(struct sk_buff *skb, ++priv->tx_bd_tail; priv->tx_bd_tail %= TX_BD_NUM; + /* Stop queue if next transmit may not have space */ + if (nixge_check_tx_bd_space(priv, MAX_SKB_FRAGS + 1)) { + netif_stop_queue(ndev); + + /* Matches barrier in nixge_start_xmit_done */ + smp_mb(); + + /* Space might have just been freed - check again */ + if (!nixge_check_tx_bd_space(priv, MAX_SKB_FRAGS + 1)) + netif_wake_queue(ndev); + } + return NETDEV_TX_OK; frag_err: for (; ii > 0; ii--) { -- 2.9.5