Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp2079934imu; Wed, 28 Nov 2018 22:01:27 -0800 (PST) X-Google-Smtp-Source: AFSGD/X/JgMhPCLsS/jBLVUrz6tXYLy59hOaWlUPi8Desjzw30jZR7rXM3f95hgntWkmfiyH03Pq X-Received: by 2002:a17:902:7603:: with SMTP id k3mr178718pll.285.1543471287891; Wed, 28 Nov 2018 22:01:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543471287; cv=none; d=google.com; s=arc-20160816; b=pcamaWDOPkyS0yzO4IoQtdHlGPJBul7/V7A1qCs3udr8uePp4jJA6G14pWm5oRZR23 itJkbZ+BJ2h5/24Sj/+ZsqTQGW0QbvB/YXh3lqJXt5ua89gY4MFsjedVUgvBWVVCQ+Wf hjwIA4Lhw+AAHNfMqdcbQQtuMEPfdyFplKXOH2kAWEEoG6+X8Af3ZJ0vGN91wSztXvNj ETOerYKKcax/lD5jP6rVTSaRxDsUM2WF+SVk2TYWK1BcipEU4FYuSz/Bv+LECWQaPNn1 t64+5DeRiTUkUGSwoKmXRDwkFHnJnWdpGBSChxctWM6wTPxbSj6LLPhJC1PJEyQ3etH/ j9Vg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=JDsRXaGXp8j4AfQw7SF9S20pY+tp+Q+k2W3+hA6wtvs=; b=nGhBMQvaP9ZAxWpAFM1Yqto7Pzlb2qdfByiDbVCuSUl7KyDxuTxr9hSuemm3Ogg35i Swfi/X9/7tGYGSnz2v8PSDyZXl2avUONHDErjLGNKbl9YV2Pb1eGwcm1ReJou0vueRY6 6JmBVfn6Q63S0ZSTqEXtFicjFr69WlLzTM9HBF7L7BubKNt1dP+8iP2haAIaK6N8GKvi njjKCVTaE68UcT3TKhdVVlGfaPCcmZgU4bcOvPqwCqvuiHqPJRAWOHerK/+9Bh4erDbw dBYIN3W/3LIhboxIluzdr3wuMroN0cZ26mQfDsAVcujQzPLtWZbao4Q9VMQZLhwyjKMo Sesg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=iJb4sGOD; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v20si1017381pgk.103.2018.11.28.22.01.13; Wed, 28 Nov 2018 22:01:27 -0800 (PST) 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; dkim=pass header.i=@kernel.org header.s=default header.b=iJb4sGOD; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729022AbeK2REC (ORCPT + 99 others); Thu, 29 Nov 2018 12:04:02 -0500 Received: from mail.kernel.org ([198.145.29.99]:38472 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727958AbeK2REB (ORCPT ); Thu, 29 Nov 2018 12:04:01 -0500 Received: from sasha-vm.mshome.net (unknown [37.142.5.207]) (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 3BF3E21104; Thu, 29 Nov 2018 05:59:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1543471190; bh=/KySSdHTSOnyrrEm2qnhYq7IdrcvuV0UJNKEcYwKick=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iJb4sGODF+yKyPQVB+J5jVNw1SLt5hRK7OD9mZc7MqtFVN/CZhRZKmP3cesfR4wq6 IKDzZOm8apKmb/sXTRbUjwWJ86CW+6QOtUpk8TN3BajE9KiAczujZ9GBmMnb7ROvrN es9PRymXuCZZI9ZmJgnarJStdkvGLmubBViUFDUM= From: Sasha Levin To: stable@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Juliet Kim , "David S . Miller" , Sasha Levin , linuxppc-dev@lists.ozlabs.org, netdev@vger.kernel.org Subject: [PATCH AUTOSEL 4.19 49/68] net/ibmnvic: Fix deadlock problem in reset Date: Thu, 29 Nov 2018 00:55:40 -0500 Message-Id: <20181129055559.159228-49-sashal@kernel.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181129055559.159228-1-sashal@kernel.org> References: <20181129055559.159228-1-sashal@kernel.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Juliet Kim [ Upstream commit a5681e20b541a507c7d4fd48ae4a4040d32ee1ef ] This patch changes to use rtnl_lock only during a reset to avoid deadlock that could occur when a thread operating close is holding rtnl_lock and waiting for reset_lock acquired by another thread, which is waiting for rtnl_lock in order to set the number of tx/rx queues during a reset. Also, we now setting the number of tx/rx queues during a soft reset for failover or LPM events. Signed-off-by: Juliet Kim Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/ibm/ibmvnic.c | 59 +++++++++++------------------- drivers/net/ethernet/ibm/ibmvnic.h | 2 +- 2 files changed, 22 insertions(+), 39 deletions(-) diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 7661064c815b..a646de07cbdc 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -1103,20 +1103,15 @@ static int ibmvnic_open(struct net_device *netdev) return 0; } - mutex_lock(&adapter->reset_lock); - if (adapter->state != VNIC_CLOSED) { rc = ibmvnic_login(netdev); - if (rc) { - mutex_unlock(&adapter->reset_lock); + if (rc) return rc; - } rc = init_resources(adapter); if (rc) { netdev_err(netdev, "failed to initialize resources\n"); release_resources(adapter); - mutex_unlock(&adapter->reset_lock); return rc; } } @@ -1124,8 +1119,6 @@ static int ibmvnic_open(struct net_device *netdev) rc = __ibmvnic_open(netdev); netif_carrier_on(netdev); - mutex_unlock(&adapter->reset_lock); - return rc; } @@ -1269,10 +1262,8 @@ static int ibmvnic_close(struct net_device *netdev) return 0; } - mutex_lock(&adapter->reset_lock); rc = __ibmvnic_close(netdev); ibmvnic_cleanup(netdev); - mutex_unlock(&adapter->reset_lock); return rc; } @@ -1820,20 +1811,15 @@ static int do_reset(struct ibmvnic_adapter *adapter, return rc; } else if (adapter->req_rx_queues != old_num_rx_queues || adapter->req_tx_queues != old_num_tx_queues) { - adapter->map_id = 1; release_rx_pools(adapter); release_tx_pools(adapter); - rc = init_rx_pools(netdev); - if (rc) - return rc; - rc = init_tx_pools(netdev); - if (rc) - return rc; - release_napi(adapter); - rc = init_napi(adapter); + release_vpd_data(adapter); + + rc = init_resources(adapter); if (rc) return rc; + } else { rc = reset_tx_pools(adapter); if (rc) @@ -1917,17 +1903,8 @@ static int do_hard_reset(struct ibmvnic_adapter *adapter, adapter->state = VNIC_PROBED; return 0; } - /* netif_set_real_num_xx_queues needs to take rtnl lock here - * unless wait_for_reset is set, in which case the rtnl lock - * has already been taken before initializing the reset - */ - if (!adapter->wait_for_reset) { - rtnl_lock(); - rc = init_resources(adapter); - rtnl_unlock(); - } else { - rc = init_resources(adapter); - } + + rc = init_resources(adapter); if (rc) return rc; @@ -1986,13 +1963,21 @@ static void __ibmvnic_reset(struct work_struct *work) struct ibmvnic_rwi *rwi; struct ibmvnic_adapter *adapter; struct net_device *netdev; + bool we_lock_rtnl = false; u32 reset_state; int rc = 0; adapter = container_of(work, struct ibmvnic_adapter, ibmvnic_reset); netdev = adapter->netdev; - mutex_lock(&adapter->reset_lock); + /* netif_set_real_num_xx_queues needs to take rtnl lock here + * unless wait_for_reset is set, in which case the rtnl lock + * has already been taken before initializing the reset + */ + if (!adapter->wait_for_reset) { + rtnl_lock(); + we_lock_rtnl = true; + } reset_state = adapter->state; rwi = get_next_rwi(adapter); @@ -2020,12 +2005,11 @@ static void __ibmvnic_reset(struct work_struct *work) if (rc) { netdev_dbg(adapter->netdev, "Reset failed\n"); free_all_rwi(adapter); - mutex_unlock(&adapter->reset_lock); - return; } adapter->resetting = false; - mutex_unlock(&adapter->reset_lock); + if (we_lock_rtnl) + rtnl_unlock(); } static int ibmvnic_reset(struct ibmvnic_adapter *adapter, @@ -4709,7 +4693,6 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id) INIT_WORK(&adapter->ibmvnic_reset, __ibmvnic_reset); INIT_LIST_HEAD(&adapter->rwi_list); - mutex_init(&adapter->reset_lock); mutex_init(&adapter->rwi_lock); adapter->resetting = false; @@ -4781,8 +4764,8 @@ static int ibmvnic_remove(struct vio_dev *dev) struct ibmvnic_adapter *adapter = netdev_priv(netdev); adapter->state = VNIC_REMOVING; - unregister_netdev(netdev); - mutex_lock(&adapter->reset_lock); + rtnl_lock(); + unregister_netdevice(netdev); release_resources(adapter); release_sub_crqs(adapter, 1); @@ -4793,7 +4776,7 @@ static int ibmvnic_remove(struct vio_dev *dev) adapter->state = VNIC_REMOVED; - mutex_unlock(&adapter->reset_lock); + rtnl_unlock(); device_remove_file(&dev->dev, &dev_attr_failover); free_netdev(netdev); dev_set_drvdata(&dev->dev, NULL); diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h index f06eec145ca6..735f481b1870 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.h +++ b/drivers/net/ethernet/ibm/ibmvnic.h @@ -1068,7 +1068,7 @@ struct ibmvnic_adapter { struct tasklet_struct tasklet; enum vnic_state state; enum ibmvnic_reset_reason reset_reason; - struct mutex reset_lock, rwi_lock; + struct mutex rwi_lock; struct list_head rwi_list; struct work_struct ibmvnic_reset; bool resetting; -- 2.17.1