Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2226527/?format=api
{ "id": 2226527, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2226527/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/patch/5c06d6cf37dfc8ff6e8de35fdef4cd5652cdb8b9.1776868550.git.bblock@linux.ibm.com/", "project": { "id": 28, "url": "http://patchwork.ozlabs.org/api/1.1/projects/28/?format=api", "name": "Linux PCI development", "link_name": "linux-pci", "list_id": "linux-pci.vger.kernel.org", "list_email": "linux-pci@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null }, "msgid": "<5c06d6cf37dfc8ff6e8de35fdef4cd5652cdb8b9.1776868550.git.bblock@linux.ibm.com>", "date": "2026-04-22T14:37:44", "name": "[v4,3/3] s390/pci: Fix circular/recursive deadlocks in PCI-bus and -device release", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "6257c83d449687728c5a0fc78fd2f9c0e971c660", "submitter": { "id": 91674, "url": "http://patchwork.ozlabs.org/api/1.1/people/91674/?format=api", "name": "Benjamin Block", "email": "bblock@linux.ibm.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-pci/patch/5c06d6cf37dfc8ff6e8de35fdef4cd5652cdb8b9.1776868550.git.bblock@linux.ibm.com/mbox/", "series": [ { "id": 501022, "url": "http://patchwork.ozlabs.org/api/1.1/series/501022/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/list/?series=501022", "date": "2026-04-22T14:37:42", "name": "PCI: s390/pci: Fix deadlocks on s390 when releasing zPCI-bus or -device objects", "version": 4, "mbox": "http://patchwork.ozlabs.org/series/501022/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2226527/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2226527/checks/", "tags": {}, "headers": { "Return-Path": "\n <linux-pci+bounces-52982-incoming=patchwork.ozlabs.org@vger.kernel.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "linux-pci@vger.kernel.org" ], "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256\n header.s=pp1 header.b=fHm++sUt;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=172.234.253.10; helo=sea.lore.kernel.org;\n envelope-from=linux-pci+bounces-52982-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)", "smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com\n header.b=\"fHm++sUt\"", "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=148.163.158.5", "smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=linux.ibm.com", "smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=linux.ibm.com" ], "Received": [ "from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g126H1WRcz1yCv\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 23 Apr 2026 00:43:51 +1000 (AEST)", "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id 7D5FA30CFAAA\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 14:37:54 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id E2F9C3EDAD7;\n\tWed, 22 Apr 2026 14:37:52 +0000 (UTC)", "from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com\n [148.163.158.5])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 2161F3ED5D6;\n\tWed, 22 Apr 2026 14:37:50 +0000 (UTC)", "from pps.filterd (m0353725.ppops.net [127.0.0.1])\n\tby mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id\n 63M5wtEF2295513;\n\tWed, 22 Apr 2026 14:37:50 GMT", "from ppma21.wdc07v.mail.ibm.com\n (5b.69.3da9.ip4.static.sl-reverse.com [169.61.105.91])\n\tby mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4dpeu3kpkr-1\n\t(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);\n\tWed, 22 Apr 2026 14:37:49 +0000 (GMT)", "from pps.filterd (ppma21.wdc07v.mail.ibm.com [127.0.0.1])\n\tby ppma21.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id\n 63MEZf0C026690;\n\tWed, 22 Apr 2026 14:37:49 GMT", "from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224])\n\tby ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4dpjkyakrf-1\n\t(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);\n\tWed, 22 Apr 2026 14:37:48 +0000 (GMT)", "from smtpav04.fra02v.mail.ibm.com (smtpav04.fra02v.mail.ibm.com\n [10.20.54.103])\n\tby smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id\n 63MEbjP145744486\n\t(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK);\n\tWed, 22 Apr 2026 14:37:45 GMT", "from smtpav04.fra02v.mail.ibm.com (unknown [127.0.0.1])\n\tby IMSVA (Postfix) with ESMTP id 2681E2004E;\n\tWed, 22 Apr 2026 14:37:45 +0000 (GMT)", "from smtpav04.fra02v.mail.ibm.com (unknown [127.0.0.1])\n\tby IMSVA (Postfix) with ESMTP id 09AD32004B;\n\tWed, 22 Apr 2026 14:37:45 +0000 (GMT)", "from p1gen4-pw042f0m (unknown [9.52.223.163])\n\tby smtpav04.fra02v.mail.ibm.com (Postfix) with ESMTPS;\n\tWed, 22 Apr 2026 14:37:44 +0000 (GMT)", "from bblock by p1gen4-pw042f0m with local (Exim 4.99.1)\n\t(envelope-from <bblock@linux.ibm.com>)\n\tid 1wFYi0-0000000G4Rg-3DwY;\n\tWed, 22 Apr 2026 16:37:44 +0200" ], "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1776868672; cv=none;\n b=m4jOUNVIERvBNr1J1whTcyTb/qqdExK0TkBZRNcxWsunpKgnalVGiWzdrx3DrtQoNNIOyEM4olJ30wQMzOIzrNYI+amiuLHYo0xLiFJttcje3I8QrqnLL0Yx/KOCtsqMCDxGDVjgYeupmFKNf+Wdf3odiXi5t3QBM2ZZL8TuWYk=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1776868672; c=relaxed/simple;\n\tbh=ZNta48hiP9ii+dlj+m8fLbFgyJ5rLhiaUCHbCNYBwHw=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version:Content-Type;\n b=jpELV2kSfDPhoUOKnELnjhCheAxZrdPmYA2h9F2z+gHcoQ01rgzdV9OEwb+mStx9W/y8d/IpOxv4yY0kbuG17PwQtkXCiklnd82m5rqrzaP7guy9sydtvEf62nR0mPCvXbiGpps79hbCkaqlQ8c0tgnfoo3G4C/mpj0y/8HDGyU=", "ARC-Authentication-Results": "i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=linux.ibm.com;\n spf=pass smtp.mailfrom=linux.ibm.com;\n dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com\n header.b=fHm++sUt; arc=none smtp.client-ip=148.163.158.5", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc\n\t:content-transfer-encoding:content-type:date:from:in-reply-to\n\t:message-id:mime-version:references:sender:subject:to; s=pp1;\n\t bh=lwxQ+vf6iGOq/j3B8Fs5yWgFSv8Kc5kF1vMdl+NnF2k=; b=fHm++sUtJ1p0\n\tmA74FNIXWMOR7PV/tbT7Inmac6kT6+M36W2HUiy9cpuAnHW+DkG12oz9t/Dof/En\n\tPJ6L07mcybKM4jL6wxKZ4+M8bXzXIbEGEh7aPPuc4mNIrBzCAc9iuquYM9a9riEV\n\tcjjNoKbNzjeIPAv4GellVX4ohn/teUq96vrTsk2GpWqNdj3yzvsy4/orEX71xHJJ\n\tdw3341tWpwHYnVzilR+AjR5mnnx4gTQNvaDg4zJGnJTq9lxRYrCsBtvbDTwnIj7P\n\tZtw5HuxuWZavkuyjx0jN0DgyyGJmtt2a9CgxHA3UyxjmtXJ8j/dZOvgD4hJa8UdI\n\tIsXeoyT4nQ==", "From": "Benjamin Block <bblock@linux.ibm.com>", "To": "Bjorn Helgaas <bhelgaas@google.com>", "Cc": "Niklas Schnelle <schnelle@linux.ibm.com>,\n Tobias Schumacher <ts@linux.ibm.com>,\n linux-s390 <linux-s390@vger.kernel.org>,\n Heiko Carstens <hca@linux.ibm.com>,\n Ionut Nechita <ionut_n2001@yahoo.com>,\n Sven Schnelle <svens@linux.ibm.com>,\n Ionut Nechita <ionut.nechita@windriver.com>,\n Farhan Ali <alifm@linux.ibm.com>,\n Alexander Gordeev <agordeev@linux.ibm.com>,\n Julian Ruess <julianr@linux.ibm.com>,\n Andreas Krebbel <krebbel@linux.ibm.com>,\n Gerd Bayer <gbayer@linux.ibm.com>, Vasily Gorbik <gor@linux.ibm.com>,\n linux-pci <linux-pci@vger.kernel.org>,\n linux-kernel <linux-kernel@vger.kernel.org>,\n Christian Borntraeger <borntraeger@linux.ibm.com>,\n Matthew Rosato <mjrosato@linux.ibm.com>,\n Benjamin Block <bblock@linux.ibm.com>", "Subject": "[PATCH v4 3/3] s390/pci: Fix circular/recursive deadlocks in PCI-bus\n and -device release", "Date": "Wed, 22 Apr 2026 16:37:44 +0200", "Message-ID": "\n <5c06d6cf37dfc8ff6e8de35fdef4cd5652cdb8b9.1776868550.git.bblock@linux.ibm.com>", "X-Mailer": "git-send-email 2.54.0", "In-Reply-To": "<cover.1776868550.git.bblock@linux.ibm.com>", "References": "<cover.1776868550.git.bblock@linux.ibm.com>", "Precedence": "bulk", "X-Mailing-List": "linux-pci@vger.kernel.org", "List-Id": "<linux-pci.vger.kernel.org>", "List-Subscribe": "<mailto:linux-pci+subscribe@vger.kernel.org>", "List-Unsubscribe": "<mailto:linux-pci+unsubscribe@vger.kernel.org>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=UTF-8", "Organization": "=?unknown-8bit?q?IBM_Deutschland_Research_=26_Development_GmbH?=\n\t=?unknown-8bit?q?=2C_https=3A//www=2Eibm=2Ecom/privacy=2C_Vors=2E_Aufs=2E-R?=\n\t=?unknown-8bit?q?=2E=3A_Wolfgang_Wendt=2C_Gesch=C3=A4ftsf=C3=BChrung=3A_Dav?=\n\t=?unknown-8bit?q?id_Faller=2E_Sitz_der_Ges=2E=3A_Ehningen=2C_Registergerich?=\n\t=?unknown-8bit?q?t=3A_AmtsG_Stuttgart=2C_HRB_243294?=", "Content-Transfer-Encoding": "8bit", "Sender": "Benjamin Block <bblock@linux.ibm.com>", "X-TM-AS-GCONF": "00", "X-Proofpoint-Reinject": "loops=2 maxloops=12", "X-Proofpoint-GUID": "lkKc0Z41StXDSEsPprwY_dgph0RDnCvn", "X-Proofpoint-Spam-Details-Enc": "AW1haW4tMjYwNDIyMDEzOCBTYWx0ZWRfX/5xJx50QUxaa\n FWOsQVkCHyFzDpF7+kePpleSBUEGCuwnYPgDpyPYnXtuSVAXZ4EeRUNQZlaQTxH+Bj2oAHXzt4Y\n XTXMs7AbfcRjr5dXAwGiJ92BihQJveiHy4W1/j/apsabhelxpmNxdlwwuOlGn+v1WMlpWalxP+E\n 6pPA+noFjaIePgXME82RLSQ4zpvf71zOkFSuMTe1kDxTMPRSYVjpN6dmz8RObkCkosSjjNzcxvx\n zu26/x7jECG01KnFsilCXCV6yUBOoXL3hELjcQXvWkitq5OWHn97SW8EOdB8K2AILey+JvRokNx\n sm8Hv4aTZK9bozfav7uxcDh3tIJ4nVa92dRlFZ4j/qbuyjsxowz6ye3X0GYJ26Ef+X9JLNoMl5J\n 8/aCjzBwy0qaF/DHFrSF1E93rj5MQCu7KI8REiwFbUPJjRlitAOxMrlFmShQgQ1gobA+u95Dwj9\n mxZRU8A8lGZl4xPQXaw==", "X-Authority-Analysis": "v=2.4 cv=a6kAM0SF c=1 sm=1 tr=0 ts=69e8dd3d cx=c_pps\n a=GFwsV6G8L6GxiO2Y/PsHdQ==:117 a=GFwsV6G8L6GxiO2Y/PsHdQ==:17\n a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=VkNPw1HP01LnGYTKEx00:22\n a=RnoormkPH1_aCDwRdu11:22 a=V8glGbnc2Ofi9Qvn3v5h:22 a=VnNF1IyMAAAA:8\n a=qptzKXhuCiR4edXAYWEA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10", "X-Proofpoint-ORIG-GUID": "67O-PfFj3lSi5AFlZ2PpLPfsHjetMJzF", "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49\n definitions=2026-04-22_01,2026-04-21_02,2025-10-01_01", "X-Proofpoint-Spam-Details": "rule=outbound_notspam policy=outbound score=0\n malwarescore=0 suspectscore=0 spamscore=0 adultscore=0 bulkscore=0\n lowpriorityscore=0 impostorscore=0 clxscore=1015 phishscore=0\n priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc=\n route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000\n definitions=main-2604220138" }, "content": "When removing PCI device or PCI bus objects there are a couple of\ncall-chains where it is possible that the kernel runs into a circular\ndeadlock involving the central `pci_rescan_remove_lock`.\n\nTwo examples:\n\n(A) Thread α receives a PCI event notifying the kernel that a PCI\nvirtual function has been moved into Reserved state, and so the PCI\nsubsystem will try to remove that PCI function. The call-chain for that\nlooks like this:\n __zpci_event_availability()\n -> zpci_zdev_put() # will lock(zpci_add_remove_lock),\n # and lock(zpci_list_lock)\n -> zpci_release_device() # will unlock(zpci_list_lock)\n -> zpci_cleanup_bus_resources() # will lock(pci_rescan_remove_lock)\n\nThread β is triggered by userspace writing 0 into the SysFS attribute\n`sriov_numvfs` of the parent PCI physical function of the same function\nwe just try to remove. This will also try to release the PCI virtual\nfunction; but this time the call-chain looks like this:\n sriov_numvfs_store()\n -> ... (device driver dependent)\n -> sriov_disable()\n -> sriov_del_vfs() # will lock(pci_rescan_remove_lock)\n -> ... (deep chain)\n -> pci_release_dev()\n -> pcibios_release_device()\n -> zpci_zdev_put() # will lock(zpci_add_remove_lock)\n\nIf thread α and β coincide, this will result in a cyclic deadlock.\n\n(B) Thread γ receives a PCI event notifying the kernel that one or more\nPCI functions got hot plugged, and need to be configured. A possible\ncall-chain that might happen while the PCI subsystem is trying to add\nthose new function looks like this:\n __zpci_event_availability()\n -> ... (multiple ways in which a device gets added)\n -> zpci_add_device() # will lock(zpci_add_remove_lock)\n -> zpci_bus_device_register()\n -> zpci_bus_put() # will lock(zbus_list_lock)\n -> zpci_bus_release() # will unlock(zbus_list_lock)\n # will lock(pci_rescan_remove_lock)\n\nNow the same thread β as above in (A) might coincide, and again could\nresult in a cyclic deadlock.\n\n`pci_rescan_remove_lock` has to be and is taken at a \"high level\" in\nmost call-chains since it is intended to protect/mutual exclude all\nrescan and/or removal actions taken in the PCI subsystem. So to prevent\nthe outlined deadlock scenarios above remove it instead from the \"low\nlevel\" release functions for both the PCI device and PCI bus objects.\n\nInstead, lock `pci_rescan_remove_lock` in all call-chains leading to\nthose release functions:\n * initialization of the PCI subsystem;\n * processing of availability events (CRWs) for PCI functions;\n * processing of error events (CRWs) for PCI functions;\n * architecture specific release PCI device implementation.\n\nAdditionally, remove `pci_rescan_remove_lock` from zpci_bus_scan_bus()\nsince its only caller zpci_scan_devices() is now always called with\n`pci_rescan_remove_lock` already held.\n\nLastly, document the new locking expectations after these changes. Add\nsparse and lockdep annotations to functions that previously locked\n`pci_rescan_remove_lock` explicitly, making sure the lock is now\nalready held when called. Additionally also add the annotations to\nzpci_zdev_put() and zpci_bus_put() to make sure that every function that\npotentially drops the last reference already holds the lock to prevent\nsurprises.\n\nFixes: 05bc1be6db4b2 (\"s390/pci: create zPCI bus\")\nFixes: ab909509850b2 (\"PCI: s390: Fix use-after-free of PCI resources with per-function hotplug\")\nReviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>\nTested-by: Niklas Schnelle <schnelle@linux.ibm.com>\nSigned-off-by: Benjamin Block <bblock@linux.ibm.com>\n---\n arch/s390/pci/pci.c | 11 ++++++++---\n arch/s390/pci/pci_bus.c | 15 ++++++++-------\n arch/s390/pci/pci_event.c | 28 +++++++++++++++++++---------\n arch/s390/pci/pci_iov.c | 3 +--\n arch/s390/pci/pci_sysfs.c | 9 +++------\n 5 files changed, 39 insertions(+), 27 deletions(-)", "diff": "diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c\nindex 2a430722cbe4..86ef1e516857 100644\n--- a/arch/s390/pci/pci.c\n+++ b/arch/s390/pci/pci.c\n@@ -71,9 +71,11 @@ struct airq_iv *zpci_aif_sbv;\n EXPORT_SYMBOL_GPL(zpci_aif_sbv);\n \n void zpci_zdev_put(struct zpci_dev *zdev)\n+\t__must_hold(&pci_rescan_remove_lock)\n {\n \tif (!zdev)\n \t\treturn;\n+\tlockdep_assert_held(&pci_rescan_remove_lock);\n \tmutex_lock(&zpci_add_remove_lock);\n \tkref_put_lock(&zdev->kref, zpci_release_device, &zpci_list_lock);\n \tmutex_unlock(&zpci_add_remove_lock);\n@@ -582,11 +584,13 @@ int zpci_setup_bus_resources(struct zpci_dev *zdev)\n }\n \n static void zpci_cleanup_bus_resources(struct zpci_dev *zdev)\n+\t__must_hold(&pci_rescan_remove_lock)\n {\n \tstruct resource *res;\n \tint i;\n \n-\tpci_lock_rescan_remove();\n+\tlockdep_assert_held(&pci_rescan_remove_lock);\n+\n \tfor (i = 0; i < PCI_STD_NUM_BARS; i++) {\n \t\tres = zdev->bars[i].res;\n \t\tif (!res)\n@@ -599,7 +603,6 @@ static void zpci_cleanup_bus_resources(struct zpci_dev *zdev)\n \t\tkfree(res);\n \t}\n \tzdev->has_resources = 0;\n-\tpci_unlock_rescan_remove();\n }\n \n int pcibios_device_add(struct pci_dev *pdev)\n@@ -629,6 +632,7 @@ void pcibios_release_device(struct pci_dev *pdev)\n {\n \tstruct zpci_dev *zdev = to_zpci(pdev);\n \n+\tguard(pci_rescan_remove)();\n \tzpci_unmap_resources(pdev);\n \tzpci_zdev_put(zdev);\n }\n@@ -1208,7 +1212,8 @@ static int __init pci_base_init(void)\n \tif (rc)\n \t\tgoto out_irq;\n \n-\trc = zpci_scan_devices();\n+\tscoped_guard(pci_rescan_remove)\n+\t\trc = zpci_scan_devices();\n \tif (rc)\n \t\tgoto out_find;\n \ndiff --git a/arch/s390/pci/pci_bus.c b/arch/s390/pci/pci_bus.c\nindex 36a4807285fa..c1b48b572e86 100644\n--- a/arch/s390/pci/pci_bus.c\n+++ b/arch/s390/pci/pci_bus.c\n@@ -82,9 +82,8 @@ int zpci_bus_scan_device(struct zpci_dev *zdev)\n \tif (!pdev)\n \t\treturn -ENODEV;\n \n-\tpci_lock_rescan_remove();\n+\tguard(pci_rescan_remove)();\n \tpci_bus_add_device(pdev);\n-\tpci_unlock_rescan_remove();\n \n \treturn 0;\n }\n@@ -132,10 +131,13 @@ void zpci_bus_remove_device(struct zpci_dev *zdev, bool set_error)\n * Return: 0 on success, an error value otherwise\n */\n int zpci_bus_scan_bus(struct zpci_bus *zbus)\n+\t__must_hold(&pci_rescan_remove_lock)\n {\n \tstruct zpci_dev *zdev;\n \tint devfn, rc, ret = 0;\n \n+\tlockdep_assert_held(&pci_rescan_remove_lock);\n+\n \tfor (devfn = 0; devfn < ZPCI_FUNCTIONS_PER_BUS; devfn++) {\n \t\tzdev = zbus->function[devfn];\n \t\tif (zdev && zdev->state == ZPCI_FN_STATE_CONFIGURED) {\n@@ -145,10 +147,8 @@ int zpci_bus_scan_bus(struct zpci_bus *zbus)\n \t\t}\n \t}\n \n-\tpci_lock_rescan_remove();\n \tpci_scan_child_bus(zbus->bus);\n \tpci_bus_add_devices(zbus->bus);\n-\tpci_unlock_rescan_remove();\n \n \treturn ret;\n }\n@@ -214,11 +214,12 @@ static int zpci_bus_create_pci_bus(struct zpci_bus *zbus, struct zpci_dev *fr, s\n * run of the function.\n */\n static inline void zpci_bus_release(struct kref *kref)\n-\t__releases(&zbus_list_lock)\n+\t__releases(&zbus_list_lock) __must_hold(&pci_rescan_remove_lock)\n {\n \tstruct zpci_bus *zbus = container_of(kref, struct zpci_bus, kref);\n \n \tlockdep_assert_held(&zbus_list_lock);\n+\tlockdep_assert_held(&pci_rescan_remove_lock);\n \n \tlist_del(&zbus->bus_next);\n \tmutex_unlock(&zbus_list_lock);\n@@ -229,14 +230,12 @@ static inline void zpci_bus_release(struct kref *kref)\n \t */\n \n \tif (zbus->bus) {\n-\t\tpci_lock_rescan_remove();\n \t\tpci_stop_root_bus(zbus->bus);\n \n \t\tzpci_free_domain(zbus->domain_nr);\n \t\tpci_free_resource_list(&zbus->resources);\n \n \t\tpci_remove_root_bus(zbus->bus);\n-\t\tpci_unlock_rescan_remove();\n \t}\n \n \tzpci_remove_parent_msi_domain(zbus);\n@@ -250,7 +249,9 @@ static inline void __zpci_bus_get(struct zpci_bus *zbus)\n }\n \n static inline void zpci_bus_put(struct zpci_bus *zbus)\n+\t__must_hold(&pci_rescan_remove_lock)\n {\n+\tlockdep_assert_held(&pci_rescan_remove_lock);\n \tkref_put_mutex(&zbus->kref, zpci_bus_release, &zbus_list_lock);\n }\n \ndiff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c\nindex 839bd91c056e..98253706b591 100644\n--- a/arch/s390/pci/pci_event.c\n+++ b/arch/s390/pci/pci_event.c\n@@ -342,6 +342,7 @@ static void __zpci_event_error(struct zpci_ccdf_err *ccdf)\n no_pdev:\n \tif (zdev)\n \t\tmutex_unlock(&zdev->state_lock);\n+\tguard(pci_rescan_remove)();\n \tzpci_zdev_put(zdev);\n }\n \n@@ -400,9 +401,11 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)\n \t\t\tzdev = zpci_create_device(ccdf->fid, ccdf->fh, ZPCI_FN_STATE_CONFIGURED);\n \t\t\tif (IS_ERR(zdev))\n \t\t\t\tbreak;\n-\t\t\tif (zpci_add_device(zdev)) {\n-\t\t\t\tkfree(zdev);\n-\t\t\t\tbreak;\n+\t\t\tscoped_guard(pci_rescan_remove) {\n+\t\t\t\tif (zpci_add_device(zdev)) {\n+\t\t\t\t\tkfree(zdev);\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n \t\t\t}\n \t\t} else {\n \t\t\tif (zdev->state == ZPCI_FN_STATE_RESERVED)\n@@ -419,9 +422,11 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)\n \t\t\tzdev = zpci_create_device(ccdf->fid, ccdf->fh, ZPCI_FN_STATE_STANDBY);\n \t\t\tif (IS_ERR(zdev))\n \t\t\t\tbreak;\n-\t\t\tif (zpci_add_device(zdev)) {\n-\t\t\t\tkfree(zdev);\n-\t\t\t\tbreak;\n+\t\t\tscoped_guard(pci_rescan_remove) {\n+\t\t\t\tif (zpci_add_device(zdev)) {\n+\t\t\t\t\tkfree(zdev);\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n \t\t\t}\n \t\t} else {\n \t\t\tif (zdev->state == ZPCI_FN_STATE_RESERVED)\n@@ -450,24 +455,29 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)\n \t\t\t/* The 0x0304 event may immediately reserve the device */\n \t\t\tif (!clp_get_state(zdev->fid, &state) &&\n \t\t\t state == ZPCI_FN_STATE_RESERVED) {\n+\t\t\t\tguard(pci_rescan_remove)();\n \t\t\t\tzpci_device_reserved(zdev);\n \t\t\t}\n \t\t}\n \t\tbreak;\n \tcase 0x0306: /* 0x308 or 0x302 for multiple devices */\n-\t\tzpci_remove_reserved_devices();\n-\t\tzpci_scan_devices();\n+\t\tscoped_guard(pci_rescan_remove) {\n+\t\t\tzpci_remove_reserved_devices();\n+\t\t\tzpci_scan_devices();\n+\t\t}\n \t\tbreak;\n \tcase 0x0308: /* Standby -> Reserved */\n \t\tif (!zdev)\n \t\t\tbreak;\n-\t\tzpci_device_reserved(zdev);\n+\t\tscoped_guard(pci_rescan_remove)\n+\t\t\tzpci_device_reserved(zdev);\n \t\tbreak;\n \tdefault:\n \t\tbreak;\n \t}\n \tif (existing_zdev) {\n \t\tmutex_unlock(&zdev->state_lock);\n+\t\tguard(pci_rescan_remove)();\n \t\tzpci_zdev_put(zdev);\n \t}\n }\ndiff --git a/arch/s390/pci/pci_iov.c b/arch/s390/pci/pci_iov.c\nindex 13050ce5c3e9..1f7e4dd018e7 100644\n--- a/arch/s390/pci/pci_iov.c\n+++ b/arch/s390/pci/pci_iov.c\n@@ -38,10 +38,9 @@ void zpci_iov_map_resources(struct pci_dev *pdev)\n \n void zpci_iov_remove_virtfn(struct pci_dev *pdev, int vfn)\n {\n-\tpci_lock_rescan_remove();\n+\tguard(pci_rescan_remove)();\n \t/* Linux' vfid's start at 0 vfn at 1 */\n \tpci_iov_remove_virtfn(pdev->physfn, vfn - 1);\n-\tpci_unlock_rescan_remove();\n }\n \n static int zpci_iov_link_virtfn(struct pci_dev *pdev, struct pci_dev *virtfn, int vfid)\ndiff --git a/arch/s390/pci/pci_sysfs.c b/arch/s390/pci/pci_sysfs.c\nindex c2444a23e26c..f5027aa95928 100644\n--- a/arch/s390/pci/pci_sysfs.c\n+++ b/arch/s390/pci/pci_sysfs.c\n@@ -98,9 +98,9 @@ static ssize_t recover_store(struct device *dev, struct device_attribute *attr,\n \tWARN_ON_ONCE(!kn);\n \n \t/* Device needs to be configured and state must not change */\n-\tmutex_lock(&zdev->state_lock);\n+\tguard(mutex)(&zdev->state_lock);\n \tif (zdev->state != ZPCI_FN_STATE_CONFIGURED)\n-\t\tgoto out;\n+\t\treturn count;\n \n \t/* device_remove_file() serializes concurrent calls ignoring all but\n \t * the first\n@@ -112,15 +112,12 @@ static ssize_t recover_store(struct device *dev, struct device_attribute *attr,\n \t * Once it unblocks from pci_lock_rescan_remove() the original pdev\n \t * will already be removed.\n \t */\n-\tpci_lock_rescan_remove();\n+\tguard(pci_rescan_remove)();\n \tif (pci_dev_is_added(pdev)) {\n \t\tret = _do_recover(pdev, zdev);\n \t}\n \tpci_rescan_bus(zdev->zbus->bus);\n-\tpci_unlock_rescan_remove();\n \n-out:\n-\tmutex_unlock(&zdev->state_lock);\n \tif (kn)\n \t\tsysfs_unbreak_active_protection(kn);\n \treturn ret ? ret : count;\n", "prefixes": [ "v4", "3/3" ] }