Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp2527365imm; Mon, 24 Sep 2018 05:58:58 -0700 (PDT) X-Google-Smtp-Source: ACcGV63ZytmTtArhwQ80equDNn4rEZn1gCm0omrDNJYQyrzl62TcX7u6VkGnEadzHUyIf3vP0iz/ X-Received: by 2002:a65:6295:: with SMTP id f21-v6mr4771306pgv.167.1537793938796; Mon, 24 Sep 2018 05:58:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1537793938; cv=none; d=google.com; s=arc-20160816; b=pcBROoZ8JyoCOG9w6fwAu82fh8B7WGbGMzV4nKdqyamhbW7bYYzKTtnkk2hyZMh1D4 lUaBLT17VMXCSRyXPlwFuiGcz7EMuX8IdXsxysUoecaDqEsKjr0sesQ6AUHyewTLkSAK FZBMTm4nYim2p6BibPQi1gV0xNhYJd9uu3nAUrdJzHsguId7bjBxQ9opFlZVcgme8LtY 3DfGnbEzv1+fjXtZV7k/9g5aYZtno8SWCwAgS8DWhU16xASif84mmHSbNKxT8eW/RPz5 257Z6sATWldUyjNWYTUEY4ckv/6BJJsOvCZ23yRm3HDJhid/htpPYcrCPFFn5XNQX9/K DUQw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from; bh=cLqoj9S3FYUG8bwg//OZrD6WhPUcyBWiuh4MrsbWIls=; b=CsAbNyFZlfeGe7W3SEeNdZur2vE8eJ6zZt4USRtkVv2PUicSl7PATqUVNsnCyaFpdb E1VouyGoXsMgI+chQ0AQRXIQ8b7DgExdo0hljAP2LmNRIohOUxafexV4aiXfK6y57Tw8 jMu+Hkjb3it96m8nVpYJrRJO0rbSKOANXgVfCaxxhOIFpUje7Y6omrujlTJLv6YEWj3S SgpFL1/xrBBWFEqKmqXDrOhtX8DvdidqmmxbX1F/6HaxUWRzQofrkrpwd6SqD9X0jDYA Dum95xnQ4oOCkauB3jiTOtoGnvNGYi1XTM3aYSts92CR2cDXJKzg4W0+5h6WRyykt1Nn p2Fw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n10-v6si15246019pgr.291.2018.09.24.05.58.43; Mon, 24 Sep 2018 05:58:58 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729742AbeIXSNc (ORCPT + 99 others); Mon, 24 Sep 2018 14:13:32 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:54838 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728551AbeIXSNb (ORCPT ); Mon, 24 Sep 2018 14:13:31 -0400 Received: from localhost (ip-213-127-77-73.ip.prioritytelecom.net [213.127.77.73]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 4DD891082; Mon, 24 Sep 2018 12:11:40 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Alexander Duyck , Benjamin Poirier , Alexander Duyck , Aaron Brown , Jeff Kirsher , Yanhui He , Ben Hutchings Subject: [PATCH 4.9 110/111] e1000e: Fix link check race condition Date: Mon, 24 Sep 2018 13:53:17 +0200 Message-Id: <20180924113116.226495480@linuxfoundation.org> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180924113103.337261320@linuxfoundation.org> References: <20180924113103.337261320@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.9-stable review patch. If anyone has any objections, please let me know. ------------------ From: Benjamin Poirier commit e2710dbf0dc1e37d85368e2404049dadda848d5a upstream. Alex reported the following race condition: /* link goes up... interrupt... schedule watchdog */ \ e1000_watchdog_task \ e1000e_has_link \ hw->mac.ops.check_for_link() === e1000e_check_for_copper_link \ e1000e_phy_has_link_generic(..., &link) link = true /* link goes down... interrupt */ \ e1000_msix_other hw->mac.get_link_status = true /* link is up */ mac->get_link_status = false link_active = true /* link_active is true, wrongly, and stays so because * get_link_status is false */ Avoid this problem by making sure that we don't set get_link_status = false after having checked the link. It seems this problem has been present since the introduction of e1000e. Link: https://lkml.org/lkml/2018/1/29/338 Reported-by: Alexander Duyck Signed-off-by: Benjamin Poirier Acked-by: Alexander Duyck Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher Cc: Yanhui He Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/e1000e/ich8lan.c | 31 +++++++++++++++------------- drivers/net/ethernet/intel/e1000e/mac.c | 14 ++++++------ 2 files changed, 24 insertions(+), 21 deletions(-) --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -1380,6 +1380,7 @@ static s32 e1000_check_for_copper_link_i */ if (!mac->get_link_status) return 0; + mac->get_link_status = false; /* First we want to see if the MII Status Register reports * link. If so, then we want to get the current speed/duplex @@ -1387,12 +1388,12 @@ static s32 e1000_check_for_copper_link_i */ ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); if (ret_val) - return ret_val; + goto out; if (hw->mac.type == e1000_pchlan) { ret_val = e1000_k1_gig_workaround_hv(hw, link); if (ret_val) - return ret_val; + goto out; } /* When connected at 10Mbps half-duplex, some parts are excessively @@ -1427,7 +1428,7 @@ static s32 e1000_check_for_copper_link_i ret_val = hw->phy.ops.acquire(hw); if (ret_val) - return ret_val; + goto out; if (hw->mac.type == e1000_pch2lan) emi_addr = I82579_RX_CONFIG; @@ -1450,7 +1451,7 @@ static s32 e1000_check_for_copper_link_i hw->phy.ops.release(hw); if (ret_val) - return ret_val; + goto out; if (hw->mac.type == e1000_pch_spt) { u16 data; @@ -1459,14 +1460,14 @@ static s32 e1000_check_for_copper_link_i if (speed == SPEED_1000) { ret_val = hw->phy.ops.acquire(hw); if (ret_val) - return ret_val; + goto out; ret_val = e1e_rphy_locked(hw, PHY_REG(776, 20), &data); if (ret_val) { hw->phy.ops.release(hw); - return ret_val; + goto out; } ptr_gap = (data & (0x3FF << 2)) >> 2; @@ -1480,18 +1481,18 @@ static s32 e1000_check_for_copper_link_i } hw->phy.ops.release(hw); if (ret_val) - return ret_val; + goto out; } else { ret_val = hw->phy.ops.acquire(hw); if (ret_val) - return ret_val; + goto out; ret_val = e1e_wphy_locked(hw, PHY_REG(776, 20), 0xC023); hw->phy.ops.release(hw); if (ret_val) - return ret_val; + goto out; } } @@ -1518,7 +1519,7 @@ static s32 e1000_check_for_copper_link_i (hw->adapter->pdev->device == E1000_DEV_ID_PCH_I218_V3)) { ret_val = e1000_k1_workaround_lpt_lp(hw, link); if (ret_val) - return ret_val; + goto out; } if ((hw->mac.type == e1000_pch_lpt) || (hw->mac.type == e1000_pch_spt)) { @@ -1527,7 +1528,7 @@ static s32 e1000_check_for_copper_link_i */ ret_val = e1000_platform_pm_pch_lpt(hw, link); if (ret_val) - return ret_val; + goto out; } /* Clear link partner's EEE ability */ @@ -1547,9 +1548,7 @@ static s32 e1000_check_for_copper_link_i } if (!link) - return 0; /* No link detected */ - - mac->get_link_status = false; + goto out; switch (hw->mac.type) { case e1000_pch2lan: @@ -1615,6 +1614,10 @@ static s32 e1000_check_for_copper_link_i e_dbg("Error configuring flow control\n"); return ret_val; + +out: + mac->get_link_status = true; + return ret_val; } static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) --- a/drivers/net/ethernet/intel/e1000e/mac.c +++ b/drivers/net/ethernet/intel/e1000e/mac.c @@ -424,19 +424,15 @@ s32 e1000e_check_for_copper_link(struct */ if (!mac->get_link_status) return 0; + mac->get_link_status = false; /* First we want to see if the MII Status Register reports * link. If so, then we want to get the current speed/duplex * of the PHY. */ ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); - if (ret_val) - return ret_val; - - if (!link) - return 0; /* No link detected */ - - mac->get_link_status = false; + if (ret_val || !link) + goto out; /* Check if there was DownShift, must be checked * immediately after link-up @@ -465,6 +461,10 @@ s32 e1000e_check_for_copper_link(struct e_dbg("Error configuring flow control\n"); return ret_val; + +out: + mac->get_link_status = true; + return ret_val; } /**