From patchwork Mon Jul 22 15:19:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 13738897 X-Patchwork-Delegate: bhelgaas@google.com Received: from mx0b-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C7A3C16D9AD for ; Mon, 22 Jul 2024 15:20:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.153.30 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721661626; cv=none; b=KjYUX8LkObbr+KHOSVPda13mu1J9Sfl2lRDUBJpIJP1gnvY2AoHwUsEU6CuTqkQpbmB3rn7ukNoq/90nRX9BtHKzohLAjWRO8iy6Mz9EsyiRMxt1+Gzyp+pVhvh2U39jGu3pbOm2L1bV9FtjzKUMVkbzsN6MtXo2obYroyLx4Sc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721661626; c=relaxed/simple; bh=zWh/KCd15+IVzcMSx7MgWFW/r4pPgXRqoMG51vAFC0U=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=qTrKXrDHf5zfte/4pz8VCbqXT9obXMaDTdbcfl7pALi+Tjwf8eK/8tEbH06Q8MdN98B+nZ7XDZaOuK+gHqUR6tELnjW24Evlqo0Zl4QeJcy3UlkLygSzmUdamGN0SMygjccfBfIHMVUNYDtkixaO/t5PbibbOsgcA0/I5hss5ew= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meta.com; spf=pass smtp.mailfrom=meta.com; dkim=pass (2048-bit key) header.d=meta.com header.i=@meta.com header.b=hc7UUFfI; arc=none smtp.client-ip=67.231.153.30 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meta.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=meta.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=meta.com header.i=@meta.com header.b="hc7UUFfI" Received: from pps.filterd (m0109331.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 46MF6Xxo028485 for ; Mon, 22 Jul 2024 08:20:23 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=meta.com; h=from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= s2048-2021-q4; bh=xiVNsKFQgQWQybXMA8QD6cDtetvdN2dRhFAgNSIcZqk=; b= hc7UUFfIM+IWE028TUUAjNhihbJIGDKUONdod5fBuhk8tH4EhlFRkQmTh3XZ+NCO cg6qbXeqZAxplbXC2lm8Uc0YR8qYRuF8J2gA687RasgTBmGGStXVUpbP0dUUYOTY QF7gsBNep2Um9hp4QZJs+ZXic71VKnNJH0aYA/zlCsQVcLWMv23h4MUX6SnvPUyq knBkCvFPzOX9hllsnMjCCo7K3ypnPbhJVk8/Z9m3HcCKt18oJYYkViR1zvVFtHfc 87fEpzE5q7ujbTaaTWCvy9IKAUEnHgwZSju4Kurbu5Y3V6ACLN9XHxsycf8A4XIX UHHLpI10U8RZoeds4bXoSw== Received: from mail.thefacebook.com ([163.114.134.16]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 40gb2y09ys-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Mon, 22 Jul 2024 08:20:23 -0700 (PDT) Received: from twshared5319.37.frc1.facebook.com (2620:10d:c085:208::11) by mail.thefacebook.com (2620:10d:c08b:78::2ac9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.1544.11; Mon, 22 Jul 2024 15:20:21 +0000 Received: by devbig638.nha1.facebook.com (Postfix, from userid 544533) id 18E2110DA2D9C; Mon, 22 Jul 2024 08:20:06 -0700 (PDT) From: Keith Busch To: , , CC: , Keith Busch Subject: [PATCH RFC 1/8] pci: make pci_stop_dev concurrent safe Date: Mon, 22 Jul 2024 08:19:29 -0700 Message-ID: <20240722151936.1452299-2-kbusch@meta.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240722151936.1452299-1-kbusch@meta.com> References: <20240722151936.1452299-1-kbusch@meta.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: WCex4mV7J3n1kKFYMVrm0SWjvNRSriyJ X-Proofpoint-ORIG-GUID: WCex4mV7J3n1kKFYMVrm0SWjvNRSriyJ X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-07-22_10,2024-07-22_01,2024-05-17_01 From: Keith Busch Use the atomic ADDED flag to safely ensure concurrent callers can't attempt to stop the device multiple times. Signed-off-by: Keith Busch Reviewed-by: Jonathan Cameron --- drivers/pci/bus.c | 2 +- drivers/pci/pci.h | 9 +++++++-- drivers/pci/remove.c | 18 ++++++++---------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 55c8536860518..e41dfece0d969 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -348,7 +348,7 @@ void pci_bus_add_device(struct pci_dev *dev) if (retval < 0 && retval != -EPROBE_DEFER) pci_warn(dev, "device attach failed (%d)\n", retval); - pci_dev_assign_added(dev, true); + pci_dev_assign_added(dev); if (dev_of_node(&dev->dev) && pci_is_bridge(dev)) { retval = of_platform_populate(dev_of_node(&dev->dev), NULL, NULL, diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 79c8398f39384..171dfd6f14e6e 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -444,9 +444,14 @@ static inline int pci_dev_set_disconnected(struct pci_dev *dev, void *unused) #define PCI_DPC_RECOVERED 1 #define PCI_DPC_RECOVERING 2 -static inline void pci_dev_assign_added(struct pci_dev *dev, bool added) +static inline void pci_dev_assign_added(struct pci_dev *dev) { - assign_bit(PCI_DEV_ADDED, &dev->priv_flags, added); + set_bit(PCI_DEV_ADDED, &dev->priv_flags); +} + +static inline bool pci_dev_test_and_clear_added(struct pci_dev *dev) +{ + return test_and_clear_bit(PCI_DEV_ADDED, &dev->priv_flags); } static inline bool pci_dev_is_added(const struct pci_dev *dev) diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 910387e5bdbf9..ec3064a115bf8 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -16,17 +16,15 @@ static void pci_free_resources(struct pci_dev *dev) static void pci_stop_dev(struct pci_dev *dev) { - pci_pme_active(dev, false); - - if (pci_dev_is_added(dev)) { - of_platform_depopulate(&dev->dev); - device_release_driver(&dev->dev); - pci_proc_detach_device(dev); - pci_remove_sysfs_dev_files(dev); - of_pci_remove_node(dev); + if (!pci_dev_test_and_clear_added(dev)) + return; - pci_dev_assign_added(dev, false); - } + pci_pme_active(dev, false); + of_platform_depopulate(&dev->dev); + device_release_driver(&dev->dev); + pci_proc_detach_device(dev); + pci_remove_sysfs_dev_files(dev); + of_pci_remove_node(dev); } static void pci_destroy_dev(struct pci_dev *dev) From patchwork Mon Jul 22 15:19:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 13738894 X-Patchwork-Delegate: bhelgaas@google.com Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C13631428F1 for ; Mon, 22 Jul 2024 15:20:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.145.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721661619; cv=none; b=oZDg2tMvFxuJZBCglhADdhOTRfhF3gd2uhmptg1a1le7Vjdm2RK9FOhUM/r1jn02uUfZ60uGs8tuzyZRQzGH8frmJ6WLeLaSVjLLHV0qxyOgvyRe4KSgemJGCy8dwGYa3D+NYgr1Wc/+vAuEO5TNxEaj1xaXCkhJ8GTcvFA+xxg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721661619; c=relaxed/simple; bh=tr+sd15CCmd14CRZVH3x0xeH8QeazRn86Fu7MGfrr70=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ZPoS32Jb+eiOJwFxS3+y4vbJ1BlH6Mi3RL5ZJ9GffhYHakw4t3ba0Hsab4sVnL4mfVMDTaokZM/bQFc7FFOcXC3YWb5meB+xz05AOScPbodtb6nIf7lEUsPpZUuPUVLgzyw5cLSlWTvH6bOFtYzauQzxD+Rata8lkXVPOiL34QY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meta.com; spf=pass smtp.mailfrom=meta.com; dkim=pass (2048-bit key) header.d=meta.com header.i=@meta.com header.b=OZxbqRBM; arc=none smtp.client-ip=67.231.145.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meta.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=meta.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=meta.com header.i=@meta.com header.b="OZxbqRBM" Received: from pps.filterd (m0044012.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 46MF775Z003181 for ; Mon, 22 Jul 2024 08:20:17 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=meta.com; h=from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= s2048-2021-q4; bh=psj5xqMgUZAmZn4fEDGlNxkA/jse+rQe6TK7u+4Spnk=; b= OZxbqRBMtCc81j/vHeet/vdqkDD0K2BFPr8noNX5gnuztnJ96DioW6nR2kLq7358 3cWhcDMnCXW4kRk9htFgAVELaxlsfQmQWfng5phJlzjGIjp4JJb2sBKYq4f6mc33 s/BH2NWR4urH95okMCJ6J8mmDU790C+Z54VDU7Ze/ZKOkQ7o7KOwGttSGGQuz8nG RStICFqH1CMohB7L6xICuBA4dXPnU7f4aseGSliQ72ZQTbWRNggN2zOzI5cpjNmp JIwGfXLsgdeti9xVyukJ3RmP+It+gAefxGm4bRJL3Xpowv2ogAOAc5Tnc4ZoEnod 9AlfDEcemUx11A5JeFIHJA== Received: from mail.thefacebook.com ([163.114.134.16]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 40gaxggamj-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Mon, 22 Jul 2024 08:20:17 -0700 (PDT) Received: from twshared53332.38.frc1.facebook.com (2620:10d:c085:208::7cb7) by mail.thefacebook.com (2620:10d:c08b:78::c78f) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.1544.11; Mon, 22 Jul 2024 15:20:15 +0000 Received: by devbig638.nha1.facebook.com (Postfix, from userid 544533) id 7681F10DA2D9E; Mon, 22 Jul 2024 08:20:06 -0700 (PDT) From: Keith Busch To: , , CC: , Keith Busch Subject: [PATCH RFC 2/8] pci: make pci_destroy_dev concurrent safe Date: Mon, 22 Jul 2024 08:19:30 -0700 Message-ID: <20240722151936.1452299-3-kbusch@meta.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240722151936.1452299-1-kbusch@meta.com> References: <20240722151936.1452299-1-kbusch@meta.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: 600UgNzdmKWJu71xEglozI6D5AIP5tSo X-Proofpoint-ORIG-GUID: 600UgNzdmKWJu71xEglozI6D5AIP5tSo X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-07-22_10,2024-07-22_01,2024-05-17_01 From: Keith Busch Use an atomic flag instead of the racey check against the device's kobj parent. We shouldn't be poking into device implementation details at this level anyway. Signed-off-by: Keith Busch Reviewed-by: Jonathan Cameron --- drivers/pci/pci.h | 6 ++++++ drivers/pci/remove.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 171dfd6f14e6e..19cbf18743a96 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -443,6 +443,7 @@ static inline int pci_dev_set_disconnected(struct pci_dev *dev, void *unused) #define PCI_DEV_ADDED 0 #define PCI_DPC_RECOVERED 1 #define PCI_DPC_RECOVERING 2 +#define PCI_DEV_REMOVED 3 static inline void pci_dev_assign_added(struct pci_dev *dev) { @@ -459,6 +460,11 @@ static inline bool pci_dev_is_added(const struct pci_dev *dev) return test_bit(PCI_DEV_ADDED, &dev->priv_flags); } +static inline bool pci_dev_test_and_set_removed(struct pci_dev *dev) +{ + return test_and_set_bit(PCI_DEV_REMOVED, &dev->priv_flags); +} + #ifdef CONFIG_PCIEAER #include diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index ec3064a115bf8..8284ab20949c9 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -29,7 +29,7 @@ static void pci_stop_dev(struct pci_dev *dev) static void pci_destroy_dev(struct pci_dev *dev) { - if (!dev->dev.kobj.parent) + if (pci_dev_test_and_set_removed(dev)) return; device_del(&dev->dev); From patchwork Mon Jul 22 15:19:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 13738898 X-Patchwork-Delegate: bhelgaas@google.com Received: from mx0b-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3795016DECF for ; Mon, 22 Jul 2024 15:20:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.153.30 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721661627; cv=none; b=L0Vb/IlFITdVI4P7OuZpGsTjGek6nc3ScLnZsrSIiC1N5lbQ7Lm1swkTjsOFXdPEI5YLOTbcvQMxbOy8CZEqrDyp2nsbjennzmQn259a8VrrGKDrOl1NfrMr3kjC5KfrOEVkEtRvNaahZymGZ70rB66X+Y9MXnJxag7abjzGyWE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721661627; c=relaxed/simple; bh=Q8upQJRiVw+LZzf0iiIMXKkGI4E0s59rz4nYoo6gbFM=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=FkXg1954/ZGtjTJoqOu0Sm8vIuuC4NsEJlEwzyioTgWXy1nH30aBhdtfCaKJiIiGYPyZlh1kC7JoK22AZnIFyJIJxQ7o/pxj61kg7fZHrJFch7Aii5h5EGSIcvPKZtCZQlbUYEc5hg68w5Prp2MUk/tiZjakZkRncarY0Veq3m8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meta.com; spf=pass smtp.mailfrom=meta.com; dkim=pass (2048-bit key) header.d=meta.com header.i=@meta.com header.b=VuY98o2z; arc=none smtp.client-ip=67.231.153.30 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meta.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=meta.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=meta.com header.i=@meta.com header.b="VuY98o2z" Received: from pps.filterd (m0109331.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 46MF6Xxp028485 for ; Mon, 22 Jul 2024 08:20:24 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=meta.com; h=from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= s2048-2021-q4; bh=X9PIEPlvbv7Lql+nxyevUr42IM75OwstLhHSvX2Euy4=; b= VuY98o2zgFRF9ZCsFD7ZZ9QnipKGZKTG7icoln6heVVYXbwUrmxOjpLMNfCwvUGy u90FMXARvhae7iLge/GtkpLP+uALRgg6bIVbElZrjLBuefP4za5Hg1DGmdBKsqvJ CerZ+gtRVHGAuuZcJ7Bkn7497TpMDK5T1SFTKiU7ZSzLseKJorFDREDNfm1xVG3A 43GegmO04gmQgzCx42ln0BEq2TNEa175GN4zbpChFm3HvpphLt4LUSvDF/bY//qq 4KAr5mB6VLGB5RVvButLGXBFDZ1Q4OxMCx68iz1bnkD38TpzoEvTjqj7gEk68mTO woCHPFNkrELoFfxiNAe/GQ== Received: from mail.thefacebook.com ([163.114.134.16]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 40gb2y09ys-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Mon, 22 Jul 2024 08:20:24 -0700 (PDT) Received: from twshared5319.37.frc1.facebook.com (2620:10d:c085:208::11) by mail.thefacebook.com (2620:10d:c08b:78::2ac9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.1544.11; Mon, 22 Jul 2024 15:20:21 +0000 Received: by devbig638.nha1.facebook.com (Postfix, from userid 544533) id BBFE010DA2DA2; Mon, 22 Jul 2024 08:20:06 -0700 (PDT) From: Keith Busch To: , , CC: , Keith Busch Subject: [PATCH RFC 3/8] pci: move the walk bus lock to where its needed Date: Mon, 22 Jul 2024 08:19:31 -0700 Message-ID: <20240722151936.1452299-4-kbusch@meta.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240722151936.1452299-1-kbusch@meta.com> References: <20240722151936.1452299-1-kbusch@meta.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: TbRb7d_Yv5COmZt2O3zpDtI1udxqUdJ- X-Proofpoint-ORIG-GUID: TbRb7d_Yv5COmZt2O3zpDtI1udxqUdJ- X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-07-22_10,2024-07-22_01,2024-05-17_01 From: Keith Busch Simplify the common function by removing an unnecessary parameter that can be more easily handled in the only caller that wants it. Signed-off-by: Keith Busch Reviewed-by: Jonathan Cameron --- drivers/pci/bus.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index e41dfece0d969..7c07a141e8772 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -390,7 +390,7 @@ void pci_bus_add_devices(const struct pci_bus *bus) EXPORT_SYMBOL(pci_bus_add_devices); static void __pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), - void *userdata, bool locked) + void *userdata) { struct pci_dev *dev; struct pci_bus *bus; @@ -398,8 +398,6 @@ static void __pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void int retval; bus = top; - if (!locked) - down_read(&pci_bus_sem); next = top->devices.next; for (;;) { if (next == &bus->devices) { @@ -422,8 +420,6 @@ static void __pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void if (retval) break; } - if (!locked) - up_read(&pci_bus_sem); } /** @@ -441,7 +437,9 @@ static void __pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void */ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), void *userdata) { - __pci_walk_bus(top, cb, userdata, false); + down_read(&pci_bus_sem); + __pci_walk_bus(top, cb, userdata); + up_read(&pci_bus_sem); } EXPORT_SYMBOL_GPL(pci_walk_bus); @@ -449,7 +447,7 @@ void pci_walk_bus_locked(struct pci_bus *top, int (*cb)(struct pci_dev *, void * { lockdep_assert_held(&pci_bus_sem); - __pci_walk_bus(top, cb, userdata, true); + __pci_walk_bus(top, cb, userdata); } EXPORT_SYMBOL_GPL(pci_walk_bus_locked); From patchwork Mon Jul 22 15:19:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 13738896 X-Patchwork-Delegate: bhelgaas@google.com Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1BE3716E861 for ; Mon, 22 Jul 2024 15:20:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.145.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721661621; cv=none; b=Cb8TzDnQgkdMgoSKj6kbm2dDFpHxauDS5xBFjvTxbNJ4NLa++Wy/cnIz939Co2Td70roiTddnj1VpafLoxoTZDdrY21y9kDzTpc1YxhzjMrraU7wNJGXxv94y68YXQ4u+ruv6d/onBwvlB9Dy6CKa8ZAvtW+UF9C2InMtwstdKs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721661621; c=relaxed/simple; bh=eX5ayP8mydF508ZeAhyCUCkBu2JsKBuSE7UVptZ9eKg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=gQ4dlhxIgIbEd+9wz7lnPrbsoac1HhJWIq2ALsa0j1lfXc7E40P89tnCzJzCR2hU+SXanMIFVeK1vWaMUOtrPeKSisf30sq1lfYZ7GjFLg+T4f1wfJNuntm9i8WFgWjLcKZxv1M0TvRPwmmUQQdQZcpJkHSHl1AwHS9wKdeHYzc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meta.com; spf=pass smtp.mailfrom=meta.com; dkim=pass (2048-bit key) header.d=meta.com header.i=@meta.com header.b=T0OOWjHT; arc=none smtp.client-ip=67.231.145.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meta.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=meta.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=meta.com header.i=@meta.com header.b="T0OOWjHT" Received: from pps.filterd (m0148461.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 46MF5uMJ032160 for ; Mon, 22 Jul 2024 08:20:19 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=meta.com; h=from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= s2048-2021-q4; bh=n6yJ78kesDD1jOhEOyxvWuy6+WcsIOgoNRY4IsazV5Q=; b= T0OOWjHTPIwxukW4EJFEooUpIvWMQQFvc4Ks+nEKw2/A8rdzRaZWrmC5cy2XpF/P CUip1xu/PmM0dEGfO4R8gvIYk0V0mdGSZ4MrwFQy1dbO886hixUHr6EJ4ohP8WLM En62B05dyxKGPWWmlhQO70xUw0QIexnLpwgnkoGRSuYBmOu5up5D3aavQEzPlmec jLBg+n8ai3zQ7/c2lvuGMWHtC+sBFuFjuYVnHv8BWuLwrmVVY+blP+HXJNCzDzG6 gTKKi8LJNAGUsOmpHtipatuAAf2reps4UoklLvIthhkfBxRJ/iAKSRjwvbJWhQ1E IxrLS+R5wvTpUxaQwAXXqw== Received: from maileast.thefacebook.com ([163.114.130.16]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 40gabsgd9d-4 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Mon, 22 Jul 2024 08:20:18 -0700 (PDT) Received: from twshared19175.17.frc2.facebook.com (2620:10d:c0a8:1b::2d) by mail.thefacebook.com (2620:10d:c0a9:6f::8fd4) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.1544.11; Mon, 22 Jul 2024 15:20:15 +0000 Received: by devbig638.nha1.facebook.com (Postfix, from userid 544533) id C7E0910DA2DA4; Mon, 22 Jul 2024 08:20:06 -0700 (PDT) From: Keith Busch To: , , CC: , Keith Busch Subject: [PATCH RFC 4/8] pci: walk bus recursively Date: Mon, 22 Jul 2024 08:19:32 -0700 Message-ID: <20240722151936.1452299-5-kbusch@meta.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240722151936.1452299-1-kbusch@meta.com> References: <20240722151936.1452299-1-kbusch@meta.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-ORIG-GUID: 9QaGUX8oL5Ukea9t8OQOoxMsiPGAVUuy X-Proofpoint-GUID: 9QaGUX8oL5Ukea9t8OQOoxMsiPGAVUuy X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-07-22_10,2024-07-22_01,2024-05-17_01 From: Keith Busch The original implementation purposefully chose a non-recursive walk, presumably as a precaution on stack use. We do recursive bus walking in other places though. For example: pci_bus_resettable pci_stop_bus_device pci_remove_bus_device pci_bus_allocate_dev_resources So, recursive pci bus walking is well tested and safe, and the implementation is easier to follow. The motivation for changing it now is to make it easier to introduce finer grain locking in the future. Signed-off-by: Keith Busch Reviewed-by: Jonathan Cameron --- drivers/pci/bus.c | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 7c07a141e8772..b7208e644c79f 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -389,37 +389,23 @@ void pci_bus_add_devices(const struct pci_bus *bus) } EXPORT_SYMBOL(pci_bus_add_devices); -static void __pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), +static int __pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), void *userdata) { struct pci_dev *dev; - struct pci_bus *bus; - struct list_head *next; - int retval; + int ret = 0; - bus = top; - next = top->devices.next; - for (;;) { - if (next == &bus->devices) { - /* end of this bus, go up or finish */ - if (bus == top) + list_for_each_entry(dev, &top->devices, bus_list) { + ret = cb(dev, userdata); + if (ret) + break; + if (dev->subordinate) { + ret = __pci_walk_bus(dev->subordinate, cb, userdata); + if (ret) break; - next = bus->self->bus_list.next; - bus = bus->self->bus; - continue; } - dev = list_entry(next, struct pci_dev, bus_list); - if (dev->subordinate) { - /* this is a pci-pci bridge, do its devices next */ - next = dev->subordinate->devices.next; - bus = dev->subordinate; - } else - next = dev->bus_list.next; - - retval = cb(dev, userdata); - if (retval) - break; } + return ret; } /** From patchwork Mon Jul 22 15:19:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 13738895 X-Patchwork-Delegate: bhelgaas@google.com Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4188E16DED9 for ; Mon, 22 Jul 2024 15:20:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.145.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721661619; cv=none; b=imXfuq4bA+g+BGpwkyP3/zZfOAVnZHCGLWG+tcqJCkQ+UUEmiLeisEkN5/OCFg7E/LkKwbJdt85MkCffPFsqvpS0XJCaWUecM7/WjUz35g085zxJcEBrNfFrKKcHVaOTXyyiJHp/vUES7aBxzuSKxwPLTqPnF3llachQkzCAzRk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721661619; c=relaxed/simple; bh=Aq/OksakNqDFaeACaCs6GoCEmfoj5GUbioNnpN416kU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=dk5fFd+5RNoJ6U0BicXnvI5jaHmgJoX942M32+2LxFeddDuKLHU0fPGhPKkkGsZN/zgkAIk7edjAIFnrAK8aUBtIhmD+bypdAT7nrxeD2d1uuqS5ZTxCw4XeNVcpBBQnGSUvkexC/akhKsMg+ZUpaMGeEjP8v38ZpjHa2+HpZ64= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meta.com; spf=pass smtp.mailfrom=meta.com; dkim=pass (2048-bit key) header.d=meta.com header.i=@meta.com header.b=GrT4Ys07; arc=none smtp.client-ip=67.231.145.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meta.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=meta.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=meta.com header.i=@meta.com header.b="GrT4Ys07" Received: from pps.filterd (m0148461.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 46MF5tlA032112 for ; Mon, 22 Jul 2024 08:20:17 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=meta.com; h=from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= s2048-2021-q4; bh=8b0wf2TfMJnkGFERZwKLjfGHDKzzandulKW6DkEN7j8=; b= GrT4Ys078xappEYSeQ4hST0Ir4c/hIUkSSKGxVdv+ip4U3YGobF2Uc0M4rtAsrft cTosOPZ7oSbLVb+nPxS8aPdkmouRR2LoQOvhU+JW3a+nCBnclcB+EonWS5+AOtt0 EzSqq86WzTh1Jg39eNH09TqEz9q0mkFe8p1RvYQZtCiGoS947HH3yEy+Cnc++ZR4 LIlFt7w2ePlRIioXZWcX6J9vOmHBLicLBFwXNJw18WPd7vJcEiF6m2vorU/g7Yz5 dUrU2kJ1gf1d9+KVxgpPwwN17Agzlc300k9Z5Ck5H3+eyXs0pjB7+2pp9OaZlLG3 CR/gZNmGjkwU/3ilgcpiIA== Received: from maileast.thefacebook.com ([163.114.130.16]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 40gabsgd9e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Mon, 22 Jul 2024 08:20:17 -0700 (PDT) Received: from twshared3252.08.ash8.facebook.com (2620:10d:c0a8:1c::1b) by mail.thefacebook.com (2620:10d:c0a9:6f::237c) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.1544.11; Mon, 22 Jul 2024 15:20:15 +0000 Received: by devbig638.nha1.facebook.com (Postfix, from userid 544533) id EFFC410DA2DA6; Mon, 22 Jul 2024 08:20:06 -0700 (PDT) From: Keith Busch To: , , CC: , Keith Busch Subject: [PATCH RFC 5/8] pci: unexport pci_walk_bus_locked Date: Mon, 22 Jul 2024 08:19:33 -0700 Message-ID: <20240722151936.1452299-6-kbusch@meta.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240722151936.1452299-1-kbusch@meta.com> References: <20240722151936.1452299-1-kbusch@meta.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-ORIG-GUID: Hm0vXbtog7vr4kwMwaglczbIffd-sHD4 X-Proofpoint-GUID: Hm0vXbtog7vr4kwMwaglczbIffd-sHD4 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-07-22_10,2024-07-22_01,2024-05-17_01 From: Keith Busch There's only one user of this, and it's internal, so no need to export it. Signed-off-by: Keith Busch Reviewed-by: Jonathan Cameron --- drivers/pci/bus.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index b7208e644c79f..638e79d10bfab 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -435,7 +435,6 @@ void pci_walk_bus_locked(struct pci_bus *top, int (*cb)(struct pci_dev *, void * __pci_walk_bus(top, cb, userdata); } -EXPORT_SYMBOL_GPL(pci_walk_bus_locked); struct pci_bus *pci_bus_get(struct pci_bus *bus) { From patchwork Mon Jul 22 15:19:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 13738900 X-Patchwork-Delegate: bhelgaas@google.com Received: from mx0b-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 36A711428F1 for ; Mon, 22 Jul 2024 15:20:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.153.30 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721661631; cv=none; b=WeiTKo2wOS2OhTyoARccEU8qjIKcgxugblDVDfjVwxJe8JqHMxKnGk98zNhi9/fVeOtELiiH2WV30S7ywBE1wiZCbucxC4wD3j0dlJEHWkPM/Z9UReBBFj9/9JmOpcVFq+MV/Bh7at3J15aCmoI0Auuecrb/+JMr5GeL2YA2/Os= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721661631; c=relaxed/simple; bh=xMBNPdpQXetoCO/5zx2Yi2BJ12Uz6OpyM3OsVrd6jwk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=oEVTU3aDWjwg1HIvCnEqFwzia0dkuHrjwpyIqvFxLeT2XcQIbnSoKg4OKqnZmXnSHL9XYjNIBEM7p1AeD9f8dCcje5L/UsQrcPvO8qfFr2RSlwahVmQSr/1BkEw6h5kz12KsFBo4fFOXhspzL+7JYhdUlwzr6tkD6ZUBHNNaj7U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meta.com; spf=pass smtp.mailfrom=meta.com; dkim=pass (2048-bit key) header.d=meta.com header.i=@meta.com header.b=BHK+JEAM; arc=none smtp.client-ip=67.231.153.30 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meta.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=meta.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=meta.com header.i=@meta.com header.b="BHK+JEAM" Received: from pps.filterd (m0148460.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 46MF5rFE016663 for ; Mon, 22 Jul 2024 08:20:29 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=meta.com; h=from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= s2048-2021-q4; bh=MlDn5G65Hx6Q86MEHaryX1P7wFBbsIKsy8lbFggSxqo=; b= BHK+JEAM84YTk3HXnzXGxsyDRqZeffjjsE1HznIrAq47RExpgt6BdL6w1ezw1oQn osu9ehYGjRcVYOW6lIsy+JG80rLMcjFGALignZVONU0MBsjWO219boDXTPCiyITQ iWOitdMCtLy6qJVyKPrGrPZFutHNKPGm8c+sFMuKMRinvc+Dw+gg5R1wJ02h1lxl k34VjjtZkKrNZOxUNPsC9tWh5pqML8dEs/suiRJsYXKIHa2aB34F7VaAHvjtRyYn Kfiz/OiriZyW8eaC4sqH2g3Ofx1QmAZ8iq3R5Lcv5UuHrBGl/6kzcyHtAuRXXmcH yQ1KjUWAVlKkeZV89cs85A== Received: from mail.thefacebook.com ([163.114.134.16]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 40garwr95w-11 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Mon, 22 Jul 2024 08:20:28 -0700 (PDT) Received: from twshared5319.37.frc1.facebook.com (2620:10d:c085:208::7cb7) by mail.thefacebook.com (2620:10d:c08b:78::c78f) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.1544.11; Mon, 22 Jul 2024 15:20:21 +0000 Received: by devbig638.nha1.facebook.com (Postfix, from userid 544533) id 46D1E10DA2DA8; Mon, 22 Jul 2024 08:20:06 -0700 (PDT) From: Keith Busch To: , , CC: , Keith Busch Subject: [PATCH RFC 6/8] pci: add helpers for stop and remove bus Date: Mon, 22 Jul 2024 08:19:34 -0700 Message-ID: <20240722151936.1452299-7-kbusch@meta.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240722151936.1452299-1-kbusch@meta.com> References: <20240722151936.1452299-1-kbusch@meta.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: PVUJz2zICqmxoUVSPhrjzlk7Kfs0x9bh X-Proofpoint-ORIG-GUID: PVUJz2zICqmxoUVSPhrjzlk7Kfs0x9bh X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-07-22_10,2024-07-22_01,2024-05-17_01 From: Keith Busch There are repeated patterns of tearing down pci buses, so combine to helper functions and use these. Signed-off-by: Keith Busch --- drivers/pci/remove.c | 46 +++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 8284ab20949c9..288162a11ab19 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -4,6 +4,9 @@ #include #include "pci.h" +static void pci_stop_bus(struct pci_bus *bus); +static void pci_remove_bus_device(struct pci_dev *dev); + static void pci_free_resources(struct pci_dev *dev) { struct resource *res; @@ -45,8 +48,17 @@ static void pci_destroy_dev(struct pci_dev *dev) put_device(&dev->dev); } +static void pci_clear_bus(struct pci_bus *bus) +{ + struct pci_dev *dev, *next; + + list_for_each_entry_safe(dev, next, &bus->devices, bus_list) + pci_remove_bus_device(dev); +} + void pci_remove_bus(struct pci_bus *bus) { + pci_clear_bus(bus); pci_proc_detach_bus(bus); down_write(&pci_bus_sem); @@ -66,7 +78,15 @@ EXPORT_SYMBOL(pci_remove_bus); static void pci_stop_bus_device(struct pci_dev *dev) { struct pci_bus *bus = dev->subordinate; - struct pci_dev *child, *tmp; + + if (bus) + pci_stop_bus(bus); + pci_stop_dev(dev); +} + +static void pci_stop_bus(struct pci_bus *bus) +{ + struct pci_dev *dev, *next; /* * Stopping an SR-IOV PF device removes all the associated VFs, @@ -74,29 +94,18 @@ static void pci_stop_bus_device(struct pci_dev *dev) * iterator. Therefore, iterate in reverse so we remove the VFs * first, then the PF. */ - if (bus) { - list_for_each_entry_safe_reverse(child, tmp, - &bus->devices, bus_list) - pci_stop_bus_device(child); - } - - pci_stop_dev(dev); + list_for_each_entry_safe_reverse(dev, next, &bus->devices, bus_list) + pci_stop_bus_device(dev); } static void pci_remove_bus_device(struct pci_dev *dev) { struct pci_bus *bus = dev->subordinate; - struct pci_dev *child, *tmp; if (bus) { - list_for_each_entry_safe(child, tmp, - &bus->devices, bus_list) - pci_remove_bus_device(child); - pci_remove_bus(bus); dev->subordinate = NULL; } - pci_destroy_dev(dev); } @@ -129,16 +138,13 @@ EXPORT_SYMBOL_GPL(pci_stop_and_remove_bus_device_locked); void pci_stop_root_bus(struct pci_bus *bus) { - struct pci_dev *child, *tmp; struct pci_host_bridge *host_bridge; if (!pci_is_root_bus(bus)) return; host_bridge = to_pci_host_bridge(bus->bridge); - list_for_each_entry_safe_reverse(child, tmp, - &bus->devices, bus_list) - pci_stop_bus_device(child); + pci_stop_bus(bus); /* stop the host bridge */ device_release_driver(&host_bridge->dev); @@ -147,16 +153,12 @@ EXPORT_SYMBOL_GPL(pci_stop_root_bus); void pci_remove_root_bus(struct pci_bus *bus) { - struct pci_dev *child, *tmp; struct pci_host_bridge *host_bridge; if (!pci_is_root_bus(bus)) return; host_bridge = to_pci_host_bridge(bus->bridge); - list_for_each_entry_safe(child, tmp, - &bus->devices, bus_list) - pci_remove_bus_device(child); #ifdef CONFIG_PCI_DOMAINS_GENERIC /* Release domain_nr if it was dynamically allocated */ From patchwork Mon Jul 22 15:19:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 13738901 X-Patchwork-Delegate: bhelgaas@google.com Received: from mx0b-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7542C1428F1 for ; Mon, 22 Jul 2024 15:20:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.153.30 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721661634; cv=none; b=GkubhlD6pFzW4dlCcaFZfQDALuKrWiiH6nwMDuS0LP6HGDHQvLnDbG/6fWobM5JUxVErb0Yz95xSFzfa3RI0alOLsQ+dp9YJqHpsDT4t4Q41/5VnYtck5jZAISMJkZWB+v4Dmimo1rBeE2JvK1vBs2OFlX1LAPMJ3eLrkT5x1iI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721661634; c=relaxed/simple; bh=thY+SX2aoVOF+1cRRvpQ2CmVbCGwRSQkik90WtAWRxc=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DLw/o4UBhFOcUAkqPfcD0AXas3lqRott+2L49I57Vf49KXC2ORqYSjkBHn7fB6K2fDVTBWisdY3zpFtZrjs8xc5eVBBhHj0iHK1K2QsiPQt9c9McdiN3MWcHYrVoxntJE/Blu41viNc+SG/mxsxJT8FKytMV9BMD0W7Aj33cXwU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meta.com; spf=pass smtp.mailfrom=meta.com; dkim=pass (2048-bit key) header.d=meta.com header.i=@meta.com header.b=hfBy+mTA; arc=none smtp.client-ip=67.231.153.30 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meta.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=meta.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=meta.com header.i=@meta.com header.b="hfBy+mTA" Received: from pps.filterd (m0148460.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 46MF5rFH016663 for ; Mon, 22 Jul 2024 08:20:31 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=meta.com; h=from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= s2048-2021-q4; bh=OmbxJUSiKZV8crw5lgkUKEcjM2FOJvIH/duIHGGDutc=; b= hfBy+mTAeHgs2kKDQ04c6HYV65L4zjmK3ycHdiLfu8AutOW7PXpPxdpGdcFXGGR/ z+Hcxmtylxswrom72fIaHtblN3nj2OUTnsjAF8dlwaOVah7i8fI439oVUvTjvRMT uwauL0Z/omBBcQdK9ytGg++5Bv3LugXl85KHx7RwZZNyR0vo3IcL2Dq7j1iPQJwQ pQEEDS/4MrhtmouzDHLJJCEXpIs6z6gP9MBzviZRUcHflhMpVLg0zLe1xgxpwuM5 H9bH/Oy7+VHL7Vc9/1dWAOOHWlNnMhrtjsChR9OVUWOSh7wU6xsBqZGbK7ZyxBXa XJ6c5/IJSBXNJLI0zbv87g== Received: from mail.thefacebook.com ([163.114.134.16]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 40garwr95w-14 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Mon, 22 Jul 2024 08:20:31 -0700 (PDT) Received: from twshared5319.37.frc1.facebook.com (2620:10d:c085:208::7cb7) by mail.thefacebook.com (2620:10d:c08b:78::c78f) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.1544.11; Mon, 22 Jul 2024 15:20:22 +0000 Received: by devbig638.nha1.facebook.com (Postfix, from userid 544533) id 53DF610DA2DAA; Mon, 22 Jul 2024 08:20:07 -0700 (PDT) From: Keith Busch To: , , CC: , Keith Busch Subject: [PATCH RFC 7/8] pci: reference count subordinate Date: Mon, 22 Jul 2024 08:19:35 -0700 Message-ID: <20240722151936.1452299-8-kbusch@meta.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240722151936.1452299-1-kbusch@meta.com> References: <20240722151936.1452299-1-kbusch@meta.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: lK7daMmrW2wSdR5FkSVrLkdd_Dq--2dd X-Proofpoint-ORIG-GUID: lK7daMmrW2wSdR5FkSVrLkdd_Dq--2dd X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-07-22_10,2024-07-22_01,2024-05-17_01 From: Keith Busch The subordinate is accessed under the pci_bus_sem (or often times no lock at at all), but unset under the rescan_remove_lock. Access the subordinate buses with reference counts to guard against a concurrent removal and use-after-free. Signed-off-by: Keith Busch --- drivers/pci/bus.c | 18 +++++++++++++++--- drivers/pci/hotplug/pciehp_pci.c | 12 ++++++++++-- drivers/pci/pci.c | 28 ++++++++++++++++++++++------ drivers/pci/pci.h | 1 + drivers/pci/pcie/aspm.c | 7 +++++-- drivers/pci/probe.c | 7 +++++-- drivers/pci/remove.c | 18 +++++++++++++----- 7 files changed, 71 insertions(+), 20 deletions(-) diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 638e79d10bfab..3085ecaa2ba40 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -382,9 +382,11 @@ void pci_bus_add_devices(const struct pci_bus *bus) /* Skip if device attach failed */ if (!pci_dev_is_added(dev)) continue; - child = dev->subordinate; + + child = pci_dev_get_subordinate(dev); if (child) pci_bus_add_devices(child); + pci_bus_put(child); } } EXPORT_SYMBOL(pci_bus_add_devices); @@ -396,11 +398,16 @@ static int __pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void int ret = 0; list_for_each_entry(dev, &top->devices, bus_list) { + struct pci_bus *bus; + ret = cb(dev, userdata); if (ret) break; - if (dev->subordinate) { - ret = __pci_walk_bus(dev->subordinate, cb, userdata); + + bus = pci_dev_get_subordinate(dev); + if (bus) { + ret = __pci_walk_bus(bus, cb, userdata); + pci_bus_put(bus); if (ret) break; } @@ -448,3 +455,8 @@ void pci_bus_put(struct pci_bus *bus) if (bus) put_device(&bus->dev); } + +struct pci_bus *pci_dev_get_subordinate(struct pci_dev *dev) +{ + return pci_bus_get(READ_ONCE(dev->subordinate)); +} diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 65e50bee1a8c0..b15dcfd86c60a 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -33,9 +33,12 @@ int pciehp_configure_device(struct controller *ctrl) { struct pci_dev *dev; struct pci_dev *bridge = ctrl->pcie->port; - struct pci_bus *parent = bridge->subordinate; + struct pci_bus *parent = pci_dev_get_subordinate(bridge); int num, ret = 0; + if (!parent) + return 0; + pci_lock_rescan_remove(); dev = pci_get_slot(parent, PCI_DEVFN(0, 0)); @@ -78,6 +81,7 @@ int pciehp_configure_device(struct controller *ctrl) out: pci_unlock_rescan_remove(); + pci_bus_put(parent); return ret; } @@ -95,9 +99,12 @@ int pciehp_configure_device(struct controller *ctrl) void pciehp_unconfigure_device(struct controller *ctrl, bool presence) { struct pci_dev *dev, *temp; - struct pci_bus *parent = ctrl->pcie->port->subordinate; + struct pci_bus *parent = pci_dev_get_subordinate(ctrl->pcie->port); u16 command; + if (!parent) + return; + ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:00\n", __func__, pci_domain_nr(parent), parent->number); @@ -138,4 +145,5 @@ void pciehp_unconfigure_device(struct controller *ctrl, bool presence) } pci_unlock_rescan_remove(); + pci_bus_put(parent); } diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e3a49f66982d5..0cd36b7772c8b 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3113,9 +3113,14 @@ void pci_bridge_d3_update(struct pci_dev *dev) * so we need to go through all children to find out if one of them * continues to block D3. */ - if (d3cold_ok && !bridge->bridge_d3) - pci_walk_bus(bridge->subordinate, pci_dev_check_d3cold, - &d3cold_ok); + if (d3cold_ok && !bridge->bridge_d3) { + struct pci_bus *bus = pci_dev_get_subordinate(bridge); + + if (bus) { + pci_walk_bus(bus, pci_dev_check_d3cold, &d3cold_ok); + pci_bus_put(bus); + } + } if (bridge->bridge_d3 != d3cold_ok) { bridge->bridge_d3 = d3cold_ok; @@ -4824,6 +4829,7 @@ static int pci_bus_max_d3cold_delay(const struct pci_bus *bus) int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type) { struct pci_dev *child __free(pci_dev_put) = NULL; + struct pci_bus *bus; int delay; if (pci_dev_is_disconnected(dev)) @@ -4840,7 +4846,17 @@ int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type) * board_added(). In case of ACPI hotplug the firmware is expected * to configure the devices before OS is notified. */ - if (!dev->subordinate || list_empty(&dev->subordinate->devices)) { + bus = pci_dev_get_subordinate(dev); + if (!bus) { + up_read(&pci_bus_sem); + return 0; + } + + child = pci_dev_get(list_first_entry_or_null(&bus->devices, + struct pci_dev, + bus_list)); + if (!child) { + pci_bus_put(bus); up_read(&pci_bus_sem); return 0; } @@ -4848,12 +4864,12 @@ int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type) /* Take d3cold_delay requirements into account */ delay = pci_bus_max_d3cold_delay(dev->subordinate); if (!delay) { + pci_bus_put(bus); up_read(&pci_bus_sem); return 0; } - child = pci_dev_get(list_first_entry(&dev->subordinate->devices, - struct pci_dev, bus_list)); + pci_bus_put(bus); up_read(&pci_bus_sem); /* diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 19cbf18743a96..83e449253066e 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -312,6 +312,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev); void pci_disable_bridge_window(struct pci_dev *dev); struct pci_bus *pci_bus_get(struct pci_bus *bus); void pci_bus_put(struct pci_bus *bus); +struct pci_bus *pci_dev_get_subordinate(struct pci_dev *dev); /* PCIe link information from Link Capabilities 2 */ #define PCIE_LNKCAP2_SLS2SPEED(lnkcap2) \ diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index cee2365e54b8b..3c0c83d35ab86 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -1212,9 +1212,11 @@ static void pcie_update_aspm_capable(struct pcie_link_state *root) link->aspm_capable = link->aspm_support; } list_for_each_entry(link, &link_list, sibling) { + struct pci_bus *linkbus; struct pci_dev *child; - struct pci_bus *linkbus = link->pdev->subordinate; - if (link->root != root) + + linkbus = pci_dev_get_subordinate(link->pdev); + if (!linkbus || link->root != root) continue; list_for_each_entry(child, &linkbus->devices, bus_list) { if ((pci_pcie_type(child) != PCI_EXP_TYPE_ENDPOINT) && @@ -1222,6 +1224,7 @@ static void pcie_update_aspm_capable(struct pcie_link_state *root) continue; pcie_aspm_check_latency(child); } + pci_bus_put(linkbus); } } diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index b14b9876c0303..53522685193da 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1167,7 +1167,10 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i]; child->resource[i]->name = child->name; } - bridge->subordinate = child; + + down_write(&pci_bus_sem); + WRITE_ONCE(bridge->subordinate, child); + up_write(&pci_bus_sem); add_dev: pci_set_bus_msi_domain(child); @@ -3380,7 +3383,7 @@ int pci_hp_add_bridge(struct pci_dev *dev) /* Scan bridges that need to be reconfigured */ pci_scan_bridge_extend(parent, dev, busnr, available_buses, 1); - if (!dev->subordinate) + if (!READ_ONCE(dev->subordinate)) return -1; return 0; diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 288162a11ab19..646c97e41a323 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -77,10 +77,12 @@ EXPORT_SYMBOL(pci_remove_bus); static void pci_stop_bus_device(struct pci_dev *dev) { - struct pci_bus *bus = dev->subordinate; + struct pci_bus *bus = pci_dev_get_subordinate(dev); - if (bus) + if (bus) { pci_stop_bus(bus); + pci_bus_put(bus); + } pci_stop_dev(dev); } @@ -100,12 +102,18 @@ static void pci_stop_bus(struct pci_bus *bus) static void pci_remove_bus_device(struct pci_dev *dev) { - struct pci_bus *bus = dev->subordinate; + struct pci_bus *bus; + down_write(&pci_bus_sem); + bus = pci_dev_get_subordinate(dev); if (bus) { + WRITE_ONCE(dev->subordinate, NULL); + up_write(&pci_bus_sem); + pci_remove_bus(bus); - dev->subordinate = NULL; - } + pci_bus_put(bus); + } else + up_write(&pci_bus_sem); pci_destroy_dev(dev); } From patchwork Mon Jul 22 15:19:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 13738899 X-Patchwork-Delegate: bhelgaas@google.com Received: from mx0b-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3790D16DEBC for ; Mon, 22 Jul 2024 15:20:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.153.30 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721661628; cv=none; b=OtQNkpQm1AYncE9BtIcnBd+eUROwQHNkY2QQzskYmHSNGbYNcsTbJy0hkGJ+02fWw4PbVTEwqv3Zgsib3h+0en05GNINXO4xu88otQ2kO9uTCESTR41CtMprDPy/eIgm5Is27I5cisU564WHktOW86Puubw1QGWQ/35n+VSjSzQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721661628; c=relaxed/simple; bh=CbIC3Ep1eJsFwJsMoISVLSfKq4jtt2YjK21sP/fF6Yk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=csn8cxMxkn9mH6c+dBxiRMc3irmZj7kV9vcvX+V2xiabUTYKkntCFI2zYQEbdL1sUmuIcOmYJfLGH8P23rQAUs+kFiq3xVrE34FMysUqVzJnQ9ZJHwaiFG6f6MdbYalKc70cK1zU5vJYMKJVZQtzyz36cZTNBKAszG2JgDQcShI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meta.com; spf=pass smtp.mailfrom=meta.com; dkim=pass (2048-bit key) header.d=meta.com header.i=@meta.com header.b=X46N9wrm; arc=none smtp.client-ip=67.231.153.30 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meta.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=meta.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=meta.com header.i=@meta.com header.b="X46N9wrm" Received: from pps.filterd (m0148460.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 46MF5rF5016663 for ; Mon, 22 Jul 2024 08:20:23 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=meta.com; h=from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= s2048-2021-q4; bh=R5rA4qIyVXkrdYPh9Ahh2EG2hClhHv6Ye9qjswMa/Sk=; b= X46N9wrmLYtJE35gLFU0mbTYHMNa39hNxjpM2TUFE7cmO6jIXOyRCKLpHJCre+qX 2C/ZKle3vnV0QSh4CcLCr3g88Vrn78aihIfTtHTAPLEVZse1q8bkcBgnz7iXbwiR 8OEaZ5KUX3Lu7lGHCGFhrmPQ/RMMpbwShVnAd/S6M1wbfdRs+gjlEg48E01U3MsL Z8TsVPqlpZ7uCqClXxIgT7nGg4z5QSypbEZjTvBqE6WyfydB3NCgI+2RHYu2Gh2t nY2Os7hJvn3XexUeI/YRtvXNJR7ryCMcuH2P8sVjNE5pmvnPTcusuzLK/+6feqaE I9TSzbr+KSVLIjvbMk4fJw== Received: from mail.thefacebook.com ([163.114.134.16]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 40garwr95w-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Mon, 22 Jul 2024 08:20:23 -0700 (PDT) Received: from twshared5319.37.frc1.facebook.com (2620:10d:c085:208::11) by mail.thefacebook.com (2620:10d:c08b:78::c78f) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.1544.11; Mon, 22 Jul 2024 15:20:21 +0000 Received: by devbig638.nha1.facebook.com (Postfix, from userid 544533) id 5A06710DA2DAC; Mon, 22 Jul 2024 08:20:07 -0700 (PDT) From: Keith Busch To: , , CC: , Keith Busch Subject: [PATCH RFC 8/8] pci: use finer grain locking for bus protection Date: Mon, 22 Jul 2024 08:19:36 -0700 Message-ID: <20240722151936.1452299-9-kbusch@meta.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240722151936.1452299-1-kbusch@meta.com> References: <20240722151936.1452299-1-kbusch@meta.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: Lau465Mgo1yZ_1eNJgmcsXl3-aBOjkWD X-Proofpoint-ORIG-GUID: Lau465Mgo1yZ_1eNJgmcsXl3-aBOjkWD X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-07-22_10,2024-07-22_01,2024-05-17_01 From: Keith Busch The global rescan_remove lock has deadlocks during concurrent removals because it is used within interrupt handlers. Use a bus specific lock instead. Signed-off-by: Keith Busch Reviewed-by: Jonathan Cameron --- drivers/pci/bus.c | 11 ++++++++--- drivers/pci/hotplug/pciehp_pci.c | 11 ++++++----- drivers/pci/pci-sysfs.c | 2 ++ drivers/pci/pci.c | 5 ++++- drivers/pci/probe.c | 9 +++++++++ drivers/pci/remove.c | 10 ++++++++++ include/linux/pci.h | 11 +++++++++++ 7 files changed, 50 insertions(+), 9 deletions(-) diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 3085ecaa2ba40..d80a9e4f39d38 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -384,8 +384,11 @@ void pci_bus_add_devices(const struct pci_bus *bus) continue; child = pci_dev_get_subordinate(dev); - if (child) + if (child) { + pci_lock_bus(child); pci_bus_add_devices(child); + pci_unlock_bus(child); + } pci_bus_put(child); } } @@ -406,7 +409,9 @@ static int __pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void bus = pci_dev_get_subordinate(dev); if (bus) { + pci_lock_bus(bus); ret = __pci_walk_bus(bus, cb, userdata); + pci_unlock_bus(bus); pci_bus_put(bus); if (ret) break; @@ -430,9 +435,9 @@ static int __pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void */ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), void *userdata) { - down_read(&pci_bus_sem); + pci_lock_bus(top); __pci_walk_bus(top, cb, userdata); - up_read(&pci_bus_sem); + pci_unlock_bus(top); } EXPORT_SYMBOL_GPL(pci_walk_bus); diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index b15dcfd86c60a..f6260f1085d81 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -39,8 +39,7 @@ int pciehp_configure_device(struct controller *ctrl) if (!parent) return 0; - pci_lock_rescan_remove(); - + pci_lock_bus(parent); dev = pci_get_slot(parent, PCI_DEVFN(0, 0)); if (dev) { /* @@ -63,6 +62,7 @@ int pciehp_configure_device(struct controller *ctrl) for_each_pci_bridge(dev, parent) pci_hp_add_bridge(dev); + pci_unlock_bus(parent); pci_assign_unassigned_bridge_resources(bridge); pcie_bus_configure_settings(parent); @@ -72,6 +72,7 @@ int pciehp_configure_device(struct controller *ctrl) * to avoid AB-BA deadlock with device_lock. */ up_read(&ctrl->reset_lock); + pci_lock_bus(parent); pci_bus_add_devices(parent); down_read_nested(&ctrl->reset_lock, ctrl->depth); @@ -80,7 +81,7 @@ int pciehp_configure_device(struct controller *ctrl) pci_dev_put(dev); out: - pci_unlock_rescan_remove(); + pci_unlock_bus(parent); pci_bus_put(parent); return ret; } @@ -111,7 +112,7 @@ void pciehp_unconfigure_device(struct controller *ctrl, bool presence) if (!presence) pci_walk_bus(parent, pci_dev_set_disconnected, NULL); - pci_lock_rescan_remove(); + pci_lock_bus(parent); /* * Stopping an SR-IOV PF device removes all the associated VFs, @@ -144,6 +145,6 @@ void pciehp_unconfigure_device(struct controller *ctrl, bool presence) pci_dev_put(dev); } - pci_unlock_rescan_remove(); + pci_unlock_bus(parent); pci_bus_put(parent); } diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 40cfa716392fb..0853c931b3c7d 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -487,8 +487,10 @@ static ssize_t remove_store(struct device *dev, struct device_attribute *attr, if (kstrtoul(buf, 0, &val) < 0) return -EINVAL; + get_device(dev); if (val && device_remove_file_self(dev, attr)) pci_stop_and_remove_bus_device_locked(to_pci_dev(dev)); + put_device(dev); return count; } static DEVICE_ATTR_IGNORE_LOCKDEP(remove, 0220, NULL, diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 0cd36b7772c8b..7e5f05b155658 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3117,7 +3117,10 @@ void pci_bridge_d3_update(struct pci_dev *dev) struct pci_bus *bus = pci_dev_get_subordinate(bridge); if (bus) { - pci_walk_bus(bus, pci_dev_check_d3cold, &d3cold_ok); + down_read(&pci_bus_sem); + pci_walk_bus_locked(bus, pci_dev_check_d3cold, + &d3cold_ok); + up_read(&pci_bus_sem); pci_bus_put(bus); } } diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 53522685193da..9c1589be9c390 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -563,6 +563,7 @@ static struct pci_bus *pci_alloc_bus(struct pci_bus *parent) if (!b) return NULL; + mutex_init(&b->lock); INIT_LIST_HEAD(&b->node); INIT_LIST_HEAD(&b->children); INIT_LIST_HEAD(&b->devices); @@ -1359,7 +1360,9 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev, } buses = subordinate - secondary; + pci_lock_bus(child); cmax = pci_scan_child_bus_extend(child, buses); + pci_unlock_bus(child); if (cmax > subordinate) pci_warn(dev, "bridge has subordinate %02x but max busn %02x\n", subordinate, cmax); @@ -3109,7 +3112,9 @@ int pci_host_probe(struct pci_host_bridge *bridge) list_for_each_entry(child, &bus->children, node) pcie_bus_configure_settings(child); + pci_lock_bus(bus); pci_bus_add_devices(bus); + pci_unlock_bus(bus); return 0; } EXPORT_SYMBOL_GPL(pci_host_probe); @@ -3284,11 +3289,13 @@ unsigned int pci_rescan_bus_bridge_resize(struct pci_dev *bridge) unsigned int max; struct pci_bus *bus = bridge->subordinate; + pci_lock_bus(bus); max = pci_scan_child_bus(bus); pci_assign_unassigned_bridge_resources(bridge); pci_bus_add_devices(bus); + pci_unlock_bus(bus); return max; } @@ -3306,9 +3313,11 @@ unsigned int pci_rescan_bus(struct pci_bus *bus) { unsigned int max; + pci_lock_bus(bus); max = pci_scan_child_bus(bus); pci_assign_unassigned_bus_resources(bus); pci_bus_add_devices(bus); + pci_unlock_bus(bus); return max; } diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 646c97e41a323..cf641a80a7f21 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -52,8 +52,10 @@ static void pci_clear_bus(struct pci_bus *bus) { struct pci_dev *dev, *next; + pci_lock_bus(bus); list_for_each_entry_safe(dev, next, &bus->devices, bus_list) pci_remove_bus_device(dev); + pci_unlock_bus(bus); } void pci_remove_bus(struct pci_bus *bus) @@ -96,8 +98,10 @@ static void pci_stop_bus(struct pci_bus *bus) * iterator. Therefore, iterate in reverse so we remove the VFs * first, then the PF. */ + pci_lock_bus(bus); list_for_each_entry_safe_reverse(dev, next, &bus->devices, bus_list) pci_stop_bus_device(dev); + pci_unlock_bus(bus); } static void pci_remove_bus_device(struct pci_dev *dev) @@ -138,9 +142,15 @@ EXPORT_SYMBOL(pci_stop_and_remove_bus_device); void pci_stop_and_remove_bus_device_locked(struct pci_dev *dev) { + struct pci_bus *bus = pci_bus_get(dev->bus); + pci_lock_rescan_remove(); + pci_lock_bus(bus); pci_stop_and_remove_bus_device(dev); + pci_unlock_bus(bus); pci_unlock_rescan_remove(); + + pci_bus_put(bus); } EXPORT_SYMBOL_GPL(pci_stop_and_remove_bus_device_locked); diff --git a/include/linux/pci.h b/include/linux/pci.h index 9e36b6c1810ea..6b37373b831ec 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -649,6 +649,7 @@ struct pci_bus { struct list_head node; /* Node in list of buses */ struct pci_bus *parent; /* Parent bus this bridge is on */ struct list_head children; /* List of child buses */ + struct mutex lock; /* Lock for devices */ struct list_head devices; /* List of devices on this bus */ struct pci_dev *self; /* Bridge device as seen by parent */ struct list_head slots; /* List of slots on this bus; @@ -681,6 +682,16 @@ struct pci_bus { unsigned int unsafe_warn:1; /* warned about RW1C config write */ }; +static inline void pci_lock_bus(struct pci_bus *bus) +{ + mutex_lock_nested(&bus->lock, bus->number); +} + +static inline void pci_unlock_bus(struct pci_bus *bus) +{ + mutex_unlock(&bus->lock); +} + #define to_pci_bus(n) container_of(n, struct pci_bus, dev) static inline u16 pci_dev_id(struct pci_dev *dev)