From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.1 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 31BF6C76191 for ; Mon, 15 Jul 2019 14:38:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0B57420651 for ; Mon, 15 Jul 2019 14:38:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1563201509; bh=pOh74XmprEXzahv3tjYYNZazeCAex4Qx0g/nsj1RoA4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=FS+Ii+NsXZybUfT4eNfbpsxCTh0jHbGtO5fritA2AludWcpzPektVmrKSHczh4S7E qWHSi9kHaDy2JXE8F+rN84CzLndcNir0wIDknQ8mzpYdH0ezIkLylE9vtWWT3WnmDj YapBeLAdLs3puyaJ0l6iSUMyhFdcUeXx5KImbOm8= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2404774AbfGOOi1 (ORCPT ); Mon, 15 Jul 2019 10:38:27 -0400 Received: from mail.kernel.org ([198.145.29.99]:35162 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2403846AbfGOOiX (ORCPT ); Mon, 15 Jul 2019 10:38:23 -0400 Received: from sasha-vm.mshome.net (unknown [73.61.17.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 3ABF120651; Mon, 15 Jul 2019 14:38:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1563201502; bh=pOh74XmprEXzahv3tjYYNZazeCAex4Qx0g/nsj1RoA4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ookLiO+r5sypbgAQFDFeGMtioNS8zUIpaK5/SVlrRGjTH4KJ0r1qS/TCs67A6XX/P kI0D6ExOpzaFlBbaGtfvuCQ+eX+fAo6p+Ca/DM5x+zkze64Cwn0APk9VqLnNRcXDuE lGk2dyx7IH2jzlOuDOsInaGflioBy9P9MAM1JYb0= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Robert Hancock , "David S . Miller" , Sasha Levin , netdev@vger.kernel.org Subject: [PATCH AUTOSEL 4.9 29/73] net: axienet: Fix race condition causing TX hang Date: Mon, 15 Jul 2019 10:35:45 -0400 Message-Id: <20190715143629.10893-29-sashal@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190715143629.10893-1-sashal@kernel.org> References: <20190715143629.10893-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Robert Hancock [ Upstream commit 7de44285c1f69ccfbe8be1d6a16fcd956681fee6 ] It is possible that the interrupt handler fires and frees up space in the TX ring in between checking for sufficient TX ring space and stopping the TX queue in axienet_start_xmit. If this happens, the queue wake from the interrupt handler will occur before the queue is stopped, causing a lost wakeup and the adapter's transmit hanging. To avoid this, after stopping the queue, check again whether there is sufficient space in the TX ring. If so, wake up the queue again. Signed-off-by: Robert Hancock Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- .../net/ethernet/xilinx/xilinx_axienet_main.c | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index a8afc92cbfca..5f21ddff9e0f 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -612,6 +612,10 @@ static void axienet_start_xmit_done(struct net_device *ndev) ndev->stats.tx_packets += packets; ndev->stats.tx_bytes += size; + + /* Matches barrier in axienet_start_xmit */ + smp_mb(); + netif_wake_queue(ndev); } @@ -666,9 +670,19 @@ static int axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; if (axienet_check_tx_bd_space(lp, num_frag)) { - if (!netif_queue_stopped(ndev)) - netif_stop_queue(ndev); - return NETDEV_TX_BUSY; + if (netif_queue_stopped(ndev)) + return NETDEV_TX_BUSY; + + netif_stop_queue(ndev); + + /* Matches barrier in axienet_start_xmit_done */ + smp_mb(); + + /* Space might have just been freed - check again */ + if (axienet_check_tx_bd_space(lp, num_frag)) + return NETDEV_TX_BUSY; + + netif_wake_queue(ndev); } if (skb->ip_summed == CHECKSUM_PARTIAL) { -- 2.20.1