From nobody Fri Sep 25 13:55:01 2026 Received: from pdx-out-001.esa.us-west-2.outbound.mail-perimeter.amazon.com (pdx-out-001.esa.us-west-2.outbound.mail-perimeter.amazon.com [44.245.243.92]) (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 600E7399011; Fri, 11 Sep 2026 12:28:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=44.245.243.92 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789129698; cv=none; b=f3MigWoHw5/qgIXFSJxBEqkwoN1Byym4EW3+sWj8QxuWADW6wGLDG3KH0fcflN8soZ+0J/iYmCMnCLrQrdkv76yWYORw35BUDHUBc9lLvGQW8BF0z/YAqD7qmdaPYph3w1oy/FnLNKrwp7QwtiTX5tYaqual9A/swgPUailIZZs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789129698; c=relaxed/simple; bh=vB1R5io1mWpCtA2MMP4ZynnoMjna9AplOnQoqTrLewA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=OkAgp+Gk9jFHULdTCmM67A8NuhSo+OwtDDWYF8NEIYr3K7zKIo4E7+RsagxvMzK7JDRSv+taP5OM9TUYysLmTIuZzSnAmC5oMJu26yy7U+yAEvrFx2p5Vj6YyIquQKMGQIqKOX6ctjgC4zHbAWqBX84EXQMmOGf4UfmNIZFfapA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (2048-bit key) header.d=amazon.de header.i=@amazon.de header.b=DROsCDPb; arc=none smtp.client-ip=44.245.243.92 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=amazon.de header.i=@amazon.de header.b="DROsCDPb" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazoncorp2; t=1789129697; x=1820665697; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Rdyf/8Ttgw33V+vNGIFbMELJ7FZ26Y0HGkd+2ks6jXI=; b=DROsCDPbb6zRgPvpG1IbQdRNz9ca4GDGqyZ5rBRSoielI/LX5XVrA9Kt Fgy1Q7qGcKYD9fO/XxdOrZ9rjiCF7k7Nnf9MhuuatK+lD+52h2vBdid5S xJe03O+A4iEc8dXhjyc0IXfDw7Xxx5y3Moo9KYbgZaO8hQYCvXNr08LCN TPZa95BkiGkddRp4KCZdc94T2F501MGnefKxDOr3kXV5AHM4Uq98Hy+rA AFBuIowuN/TXPZYyKg6afPDVYpeTfqDRKNCORP1SggONHyo9jNk0PUksj FNUkng5T4KzRUw7+O2ddyabq6wn/tMLW9C20Pxbg4Qvd/Qsf6g180yDJi w==; X-CSE-ConnectionGUID: qGcm9O6eS2WTX6u9iGMBPg== X-CSE-MsgGUID: JxZKmnZMSe6zlBWCIJeRvw== X-IronPort-AV: E=Sophos;i="6.27,97,1787011200"; d="scan'208";a="27923845" Received: from ip-10-5-0-115.us-west-2.compute.internal (HELO smtpout.naws.us-west-2.prod.farcaster.email.amazon.dev) ([10.5.0.115]) by internal-pdx-out-001.esa.us-west-2.outbound.mail-perimeter.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Sep 2026 12:28:14 +0000 Received: from EX19MTAUWB002.ant.amazon.com [205.251.233.48:6057] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.4.34:2525] with esmtp (Farcaster) id b9a7c6f5-244d-4b45-b807-db7ef58f2f97; Fri, 11 Sep 2026 12:28:14 +0000 (UTC) X-Farcaster-Flow-ID: b9a7c6f5-244d-4b45-b807-db7ef58f2f97 Received: from EX19D001UWA001.ant.amazon.com (10.13.138.214) by EX19MTAUWB002.ant.amazon.com (10.250.64.231) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.2562.45; Fri, 11 Sep 2026 12:28:14 +0000 Received: from dev-dsk-sakacpav-1a-480d1124.eu-west-1.amazon.com (172.19.96.155) by EX19D001UWA001.ant.amazon.com (10.13.138.214) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.2562.46; Fri, 11 Sep 2026 12:28:11 +0000 From: Pavol Sakac To: Bjorn Helgaas CC: , , David Matlack , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= , Kees Cook , Madhavan Srinivasan , Michael Ellerman , Nicholas Piggin , Christophe Leroy , , Niklas Schnelle , Benjamin Block , Lukas Wunner , "Ionut Nechita" , Subject: [RFC PATCH 1/8] PCI/IOV: Split virtfn bus handling out of pci_iov_add_virtfn() Date: Fri, 11 Sep 2026 14:28:04 +0200 Message-ID: <20260911122804.80063-1-sakacpav@amazon.de> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260911-vfopt-s1-v1-0-693271dc0226@amazon.de> References: <20260911-vfopt-s1-v1-0-693271dc0226@amazon.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: EX19D032UWA004.ant.amazon.com (10.13.139.56) To EX19D001UWA001.ant.amazon.com (10.13.138.214) Content-Type: text/plain; charset="utf-8" pci_iov_add_virtfn() creates the virtfn bus, scans and registers the VF, and removes the bus again on failure. A later commit creates all virtfn buses up front, so separate the bus-lifetime concern from the VF-add concern: move the VF add into a new __pci_iov_add_virtfn() taking the bus as an argument, and keep bus creation and on-failure bus removal in the public wrapper. No functional change intended. Assisted-by: LLM Signed-off-by: Pavol Sakac --- drivers/pci/iov.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 9d408fb8ac25..1826d32a2364 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -343,25 +343,17 @@ static struct pci_dev *pci_iov_scan_device(struct pci= _dev *dev, int id, return virtfn; } =20 -int pci_iov_add_virtfn(struct pci_dev *dev, int id) +static int __pci_iov_add_virtfn(struct pci_dev *dev, struct pci_bus *bus, + int id) { - struct pci_bus *bus; struct pci_dev *virtfn; struct resource *res; int rc, i; u64 size; =20 - bus =3D virtfn_add_bus(dev->bus, pci_iov_virtfn_bus(dev, id)); - if (!bus) { - rc =3D -ENOMEM; - goto failed; - } - virtfn =3D pci_iov_scan_device(dev, id, bus); - if (IS_ERR(virtfn)) { - rc =3D PTR_ERR(virtfn); - goto failed0; - } + if (IS_ERR(virtfn)) + return PTR_ERR(virtfn); =20 virtfn->dev.parent =3D dev->dev.parent; virtfn->multifunction =3D 0; @@ -393,9 +385,22 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id) failed1: pci_stop_and_remove_bus_device(virtfn); pci_dev_put(dev); -failed0: - virtfn_remove_bus(dev->bus, bus); -failed: + + return rc; +} + +int pci_iov_add_virtfn(struct pci_dev *dev, int id) +{ + struct pci_bus *bus; + int rc; + + bus =3D virtfn_add_bus(dev->bus, pci_iov_virtfn_bus(dev, id)); + if (!bus) + return -ENOMEM; + + rc =3D __pci_iov_add_virtfn(dev, bus, id); + if (rc) + virtfn_remove_bus(dev->bus, bus); =20 return rc; } --=20 2.47.3 From nobody Fri Sep 25 13:55:01 2026 Received: from pdx-out-014.esa.us-west-2.outbound.mail-perimeter.amazon.com (pdx-out-014.esa.us-west-2.outbound.mail-perimeter.amazon.com [35.83.148.184]) (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 7FDD64718FA; Fri, 11 Sep 2026 12:29:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=35.83.148.184 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789129753; cv=none; b=G65IbW39pH40fwqKKx8dwVPuhUMnuGceAslhdnDgDPxnJdL5uctHmi2Kq7ohbBSTsKzcQgt6+s4tS5CfFsRdDT3HIu0CcWICUsLTFcuXmlCXiYdhCjXcQr8nW8e4Wdo3GtHQLWMkCId3A82fKCKLmczScJ08TZ3GfzCwwwklXbU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789129753; c=relaxed/simple; bh=piyOoOK1B1tp5A8gBr1tP1kJIJ7R+ZagJMPXY7S3P28=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=i2ag9zrtP94BDscs/Iv6OJ3nfEUTkNOiYrZKm03A7YUogvFycdPsEcvQel2tuGvE9qIsDCHC1VSi28uUvH/d5LD6OLu1s2WH1B4tAXwGoPPBrCPpbjXJFD03FwGRmjVNFXqHxhDFC8FBiN4cfEw/Rw9ERG4bK1x7AD5P6Xh+OcY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (2048-bit key) header.d=amazon.de header.i=@amazon.de header.b=s1ZiMLSb; arc=none smtp.client-ip=35.83.148.184 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=amazon.de header.i=@amazon.de header.b="s1ZiMLSb" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazoncorp2; t=1789129751; x=1820665751; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=f0dNMrQX9nlSUWSHEteekI596QsuKLoL7NzPMKWWv2s=; b=s1ZiMLSbMycrQ0/EwEk/6E+WVrzP3s5/Gm31LXsApDh3fzC6DY9GRkUR fJjNevMCsE63js/128qU9WVVADCOs+tZuqaZDZs7WCnBrxTDHO/GoAx5h 1kObmYZL4UZwtUWYoVJzm8fy37ZA21Eqnf0rMRoMYgQynxFZzfPypuGx9 z5igVv1Z/CAj17jdgd1hPsiAYZmtBTn4MHZUhnDb0O2/a80aW6uThGqYj m73wG2GZPHricHnpQBAhz3/ft7N8rUAiBUke2Luk9QQejBEAK/gPrnxdp vvoTTeVrns8PLXfY9yl0s+hHjB+a2M83RqSA4q7u2YNfJONsDdpaecrO5 A==; X-CSE-ConnectionGUID: wIn58uYPQ96TRm2APJ38+g== X-CSE-MsgGUID: rUD9oqXSTHOsAxr+5f17IQ== X-IronPort-AV: E=Sophos;i="6.27,97,1787011200"; d="scan'208";a="28215968" Received: from ip-10-5-0-115.us-west-2.compute.internal (HELO smtpout.naws.us-west-2.prod.farcaster.email.amazon.dev) ([10.5.0.115]) by internal-pdx-out-014.esa.us-west-2.outbound.mail-perimeter.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Sep 2026 12:29:09 +0000 Received: from EX19MTAUWA002.ant.amazon.com [205.251.233.178:12471] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.37.160:2525] with esmtp (Farcaster) id 2742a140-836f-44a1-bad7-d2f5f8a45c98; Fri, 11 Sep 2026 12:29:08 +0000 (UTC) X-Farcaster-Flow-ID: 2742a140-836f-44a1-bad7-d2f5f8a45c98 Received: from EX19D001UWA001.ant.amazon.com (10.13.138.214) by EX19MTAUWA002.ant.amazon.com (10.250.64.202) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.2562.45; Fri, 11 Sep 2026 12:29:08 +0000 Received: from dev-dsk-sakacpav-1a-480d1124.eu-west-1.amazon.com (172.19.96.155) by EX19D001UWA001.ant.amazon.com (10.13.138.214) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.2562.46; Fri, 11 Sep 2026 12:29:05 +0000 From: Pavol Sakac To: Bjorn Helgaas CC: , , David Matlack , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= , Kees Cook , Madhavan Srinivasan , Michael Ellerman , Nicholas Piggin , Christophe Leroy , , Niklas Schnelle , Benjamin Block , Lukas Wunner , "Ionut Nechita" , Subject: [RFC PATCH 2/8] PCI/IOV: Create virtfn buses up front in sriov_add_vfs() Date: Fri, 11 Sep 2026 14:29:04 +0200 Message-ID: <20260911122904.85386-1-sakacpav@amazon.de> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260911-vfopt-s1-v1-0-693271dc0226@amazon.de> References: <20260911-vfopt-s1-v1-0-693271dc0226@amazon.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: EX19D035UWA004.ant.amazon.com (10.13.139.109) To EX19D001UWA001.ant.amazon.com (10.13.138.214) Content-Type: text/plain; charset="utf-8" virtfn_add_bus() is find-then-create and therefore assumes external serialization. Create every virtfn bus before adding any VF, taking the bus-create path out of the per-VF loop so a later commit can run the per-VF adds concurrently against a stable bus set. Bus numbers are already fixed before the loop, since pci_iov_set_numvfs() has latched offset and stride. The cleanup pass must remove only buses this enable created, because virtfn_remove_bus() checks that a bus is empty rather than who created it, so virtfn_add_bus() now reports whether it created the bus and sriov_add_vfs() records that per VF id in a bitmap. Return early for num_vfs =3D=3D 0: kvcalloc(0, ...) returns ZERO_SIZE_PTR and a later commit dereferences buses[0] unconditionally. Several ids can share one bus number; only the creating id's bit is set. Assisted-by: LLM Signed-off-by: Pavol Sakac --- drivers/pci/iov.c | 60 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 1826d32a2364..dda9303516f5 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -8,6 +8,7 @@ */ =20 #include +#include #include #include #include @@ -124,10 +125,14 @@ static int compute_max_vf_buses(struct pci_dev *dev) return rc; } =20 -static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr) +static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr, + bool *created) { struct pci_bus *child; =20 + if (created) + *created =3D false; + if (bus->number =3D=3D busnr) return bus; =20 @@ -140,6 +145,8 @@ static struct pci_bus *virtfn_add_bus(struct pci_bus *b= us, int busnr) return NULL; =20 pci_bus_insert_busn_res(child, busnr, busnr); + if (created) + *created =3D true; =20 return child; } @@ -394,7 +401,7 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id) struct pci_bus *bus; int rc; =20 - bus =3D virtfn_add_bus(dev->bus, pci_iov_virtfn_bus(dev, id)); + bus =3D virtfn_add_bus(dev->bus, pci_iov_virtfn_bus(dev, id), NULL); if (!bus) return -ENOMEM; =20 @@ -632,22 +639,67 @@ int __weak pcibios_sriov_disable(struct pci_dev *pdev) =20 static int sriov_add_vfs(struct pci_dev *dev, u16 num_vfs) { + unsigned long *created_buses; + struct pci_bus **buses; + struct pci_bus *bus; unsigned int i; int rc; =20 - if (dev->no_vf_scan) + if (!num_vfs || dev->no_vf_scan) return 0; =20 + buses =3D kvcalloc(num_vfs, sizeof(*buses), GFP_KERNEL); + if (!buses) + return -ENOMEM; + + created_buses =3D bitmap_zalloc(num_vfs, GFP_KERNEL); + if (!created_buses) { + kvfree(buses); + return -ENOMEM; + } + for (i =3D 0; i < num_vfs; i++) { - rc =3D pci_iov_add_virtfn(dev, i); + bool created; + + buses[i] =3D virtfn_add_bus(dev->bus, pci_iov_virtfn_bus(dev, i), + &created); + if (!buses[i]) { + rc =3D -ENOMEM; + goto remove_buses; + } + if (created) + __set_bit(i, created_buses); + } + + for (i =3D 0; i < num_vfs; i++) { + rc =3D __pci_iov_add_virtfn(dev, buses[i], i); if (rc) goto failed; } + + bitmap_free(created_buses); + kvfree(buses); return 0; failed: while (i--) pci_iov_remove_virtfn(dev, i); =20 +remove_buses: + /* + * Remove only buses this enable created: several ids can share one + * bus and only the creating id is recorded; virtfn_remove_bus() + * checks emptiness, not ownership. Re-look each up by number -- + * the VF unwind above may already have freed it. + */ + for_each_set_bit(i, created_buses, num_vfs) { + bus =3D pci_find_bus(pci_domain_nr(dev->bus), + pci_iov_virtfn_bus(dev, i)); + if (bus) + virtfn_remove_bus(dev->bus, bus); + } + + bitmap_free(created_buses); + kvfree(buses); return rc; } =20 --=20 2.47.3 From nobody Fri Sep 25 13:55:01 2026 Received: from pdx-out-010.esa.us-west-2.outbound.mail-perimeter.amazon.com (pdx-out-010.esa.us-west-2.outbound.mail-perimeter.amazon.com [52.12.53.23]) (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 0636F31282F; Fri, 11 Sep 2026 12:30:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=52.12.53.23 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789129809; cv=none; b=tSJuBgo0yPpTE01QwfFwEHDL7YRHqWUF9z4NKwlkAPs4bjgy4FRol0E6RC0Z+FyqLKMoAyH7yORP4u5Y6C3Uw1PAZG9y0xPTCNPRE5cewmDjmo5DqqLjNZdWmg1d6AJ5YXiUPiBJXliX3/UKi8i+98yOyg3M6eSCJ6/s9HYx4vY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789129809; c=relaxed/simple; bh=MoCJ6xcjiR21RrAJBnK4huR+J1dRKWSeef/TOmR4fYQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=HpE24k/IXuiyLcmLxtUcOHgThAdH0IJbuKMgWLjD4JYR6CpI7OUgGriY4LNGz7Uisp+oG8QTiZ4H7MRuTTSrsH6OIfqXlYQ65aeqZwKYMvcrCSpai4vNhA5uNfiqV821bbnmAoW7gzTxgQx4kzQwUs3meFdI1JdYQRYPbDapya8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (2048-bit key) header.d=amazon.de header.i=@amazon.de header.b=goybNU4J; arc=none smtp.client-ip=52.12.53.23 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=amazon.de header.i=@amazon.de header.b="goybNU4J" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazoncorp2; t=1789129805; x=1820665805; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=76//lFNoD73PWgho8H4Yagi2iOr5lIAS/w2o2f0iL7E=; b=goybNU4JXvSARFdDDoeSkR31fh8TqnFEZYMN9WW1upRdaX5lIhWnYBi9 PSH0812p8jfEogtjAhNaY9XgDfjtWbghBvNL2LM8ULzGvVxaTWSsd4Ogi MHzsJOXeWu7rbqsqBdBbUi6tFskMbwboLhWarQu7/KEmTOyybTAH2FKOz 7rTY6bVm7RuXEpzVS9gSLghiaIfpDfLRdPZR6YK5U7MlYRBaXnsnqBs4h qwaaiXFwZg8D3t+P60vTU3Qcyc/nzIUBDWY0d4fdMGd350jiA2BzqNHjx 1MRUPNK2JUew2CceGu1P0WwLrl+n/pnDTOAgRPCd7a6lInVpaaJr6jlJW Q==; X-CSE-ConnectionGUID: ZRF+sWN8SxyaluaZFeHopg== X-CSE-MsgGUID: pjbUDy3lSES4SHUcYAZPSA== X-IronPort-AV: E=Sophos;i="6.27,97,1787011200"; d="scan'208";a="28293784" Received: from ip-10-5-9-48.us-west-2.compute.internal (HELO smtpout.naws.us-west-2.prod.farcaster.email.amazon.dev) ([10.5.9.48]) by internal-pdx-out-010.esa.us-west-2.outbound.mail-perimeter.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Sep 2026 12:30:03 +0000 Received: from EX19MTAUWB001.ant.amazon.com [205.251.233.104:15106] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.62.198:2525] with esmtp (Farcaster) id 0ebb7c56-e5f4-4c1a-a205-8c4760150ebb; Fri, 11 Sep 2026 12:30:03 +0000 (UTC) X-Farcaster-Flow-ID: 0ebb7c56-e5f4-4c1a-a205-8c4760150ebb Received: from EX19D001UWA001.ant.amazon.com (10.13.138.214) by EX19MTAUWB001.ant.amazon.com (10.250.64.248) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.2562.45; Fri, 11 Sep 2026 12:30:02 +0000 Received: from dev-dsk-sakacpav-1a-480d1124.eu-west-1.amazon.com (172.19.96.155) by EX19D001UWA001.ant.amazon.com (10.13.138.214) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.2562.46; Fri, 11 Sep 2026 12:30:00 +0000 From: Pavol Sakac To: Bjorn Helgaas CC: , , David Matlack , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= , Kees Cook , Madhavan Srinivasan , Michael Ellerman , Nicholas Piggin , Christophe Leroy , , Niklas Schnelle , Benjamin Block , Lukas Wunner , "Ionut Nechita" , Subject: [RFC PATCH 3/8] PCI/PM: Convert pci_bridge_d3_update() recursion to iteration Date: Fri, 11 Sep 2026 14:29:58 +0200 Message-ID: <20260911122958.88717-1-sakacpav@amazon.de> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260911-vfopt-s1-v1-0-693271dc0226@amazon.de> References: <20260911-vfopt-s1-v1-0-693271dc0226@amazon.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: EX19D035UWA003.ant.amazon.com (10.13.139.86) To EX19D001UWA001.ant.amazon.com (10.13.138.214) Content-Type: text/plain; charset="utf-8" pci_bridge_d3_update() propagates a bridge_d3 change to upstream bridges by tail recursion: when a bridge's bridge_d3 value changes, the function calls itself with that bridge as the new device. Convert the tail recursion into an iterative loop. Each level recomputes "remove" and d3cold_ok exactly as the recursive call did for its own device, and the early returns become loop exits. No functional change intended. An upcoming change serializes this update with a mutex; the iterative form lets that mutex be taken once per external call instead of once per bridge level. Assisted-by: LLM Signed-off-by: Pavol Sakac --- drivers/pci/pci.c | 67 +++++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b2879a6be5f8..c62a315c0b4c 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3104,46 +3104,49 @@ static int pci_dev_check_d3cold(struct pci_dev *dev= , void *data) */ void pci_bridge_d3_update(struct pci_dev *dev) { - bool remove =3D !device_is_registered(&dev->dev); struct pci_dev *bridge; - bool d3cold_ok =3D true; =20 - bridge =3D pci_upstream_bridge(dev); - if (!bridge || !pci_bridge_d3_possible(bridge)) - return; + while ((bridge =3D pci_upstream_bridge(dev)) && + pci_bridge_d3_possible(bridge)) { + bool remove =3D !device_is_registered(&dev->dev); + bool d3cold_ok =3D true; =20 - /* - * If D3 is currently allowed for the bridge, removing one of its - * children won't change that. - */ - if (remove && bridge->bridge_d3) - return; + /* + * If D3 is currently allowed for the bridge, removing one of + * its children won't change that. + */ + if (remove && bridge->bridge_d3) + break; =20 - /* - * If D3 is currently allowed for the bridge and a child is added or - * changed, disallowance of D3 can only be caused by that child, so - * we only need to check that single device, not any of its siblings. - * - * If D3 is currently not allowed for the bridge, checking the device - * first may allow us to skip checking its siblings. - */ - if (!remove) - pci_dev_check_d3cold(dev, &d3cold_ok); + /* + * If D3 is currently allowed for the bridge and a child is + * added or changed, disallowance of D3 can only be caused by + * that child, so we only need to check that single device, + * not any of its siblings. + * + * If D3 is currently not allowed for the bridge, checking the + * device first may allow us to skip checking its siblings. + */ + if (!remove) + pci_dev_check_d3cold(dev, &d3cold_ok); =20 - /* - * If D3 is currently not allowed for the bridge, this may be caused - * either by the device being changed/removed or any of its siblings, - * 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 D3 is currently not allowed for the bridge, this may be + * caused either by the device being changed/removed or any of + * its siblings, 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 (bridge->bridge_d3 =3D=3D d3cold_ok) + break; =20 - if (bridge->bridge_d3 !=3D d3cold_ok) { bridge->bridge_d3 =3D d3cold_ok; + /* Propagate change to upstream bridges */ - pci_bridge_d3_update(bridge); + dev =3D bridge; } } =20 --=20 2.47.3 From nobody Fri Sep 25 13:55:01 2026 Received: from pdx-out-004.esa.us-west-2.outbound.mail-perimeter.amazon.com (pdx-out-004.esa.us-west-2.outbound.mail-perimeter.amazon.com [44.246.77.92]) (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 3B603474255; Fri, 11 Sep 2026 12:31:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=44.246.77.92 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789129865; cv=none; b=uHjPfAyFn4ojb6WMTDYnn2Gt48uDFE3KhC7R+3BuUwwq9mIWrjOR3byejMQ+zWfeA1WG2SzuCR/ys/X+NgC1Wp49n9dZWo2eyx/ynUX7vdunfuAOMKY6sqIlS/HHzhKqqdwxoMVp5rK7w15HYGyYHvOV4AVLwdgwYAKPSvA3V4w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789129865; c=relaxed/simple; bh=GrjwxhfGDXlTi4UTHHRV9ln6o+zUVXk5lXAkKITEpwg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=SJbzKpihkBLL4Q9pyITpSgAxvtVJMX8c4l3Wahr0o4Bi86rRUeHSuC0XwpTwEGZIAbo+pBM63AhS9SpW7qBX6aYkowpJ6ZnvnoFMx/H6CvJoElvpNCtTqR1dOn59WrhwN1M106WTxZS3EBVRW9nDcnvUfrEcmOQCk6tvzkqXSfA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (2048-bit key) header.d=amazon.de header.i=@amazon.de header.b=pEJW25eS; arc=none smtp.client-ip=44.246.77.92 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=amazon.de header.i=@amazon.de header.b="pEJW25eS" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazoncorp2; t=1789129861; x=1820665861; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=opd+WPzQfIayk9e7GEeBv5N8aZ9REoyrAqKoAc96BV4=; b=pEJW25eSjZ65l40hhuwQAYHmFchyHCpLEZ+7jDX229m2y7B9DfUAUhsw 9dY5jXO0ex9K9EM1fg+zMDAiHZkwKfl79nCr59f517rH5q39wPhd9Y7pD E2pSmKrQl7wSS1buq8w9XAWRaANp+MzX2+hOaln1X/Px696AcWy+Uak4R s67fXgHqiwC7kbAyAq4n7bSL9nWgi1UNZfO+Sodzea1r32UN5d+dJnX8G csNaoczxsrnL8lXgutDy1fRPle2lTyi66GNntXTcWHu2mCTeGEliTKHnQ qWO/N4quxTk0mwDZrj5Yd3ZigKhZGPTS8Qr8VUMEYn2e5hKiqQJM3eCdd A==; X-CSE-ConnectionGUID: MWmo8yIbQ/yVZfLriKnhlg== X-CSE-MsgGUID: OkrTFEs5SgCvU9PUbqh1zA== X-IronPort-AV: E=Sophos;i="6.27,97,1787011200"; d="scan'208";a="28418067" Received: from ip-10-5-12-219.us-west-2.compute.internal (HELO smtpout.naws.us-west-2.prod.farcaster.email.amazon.dev) ([10.5.12.219]) by internal-pdx-out-004.esa.us-west-2.outbound.mail-perimeter.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Sep 2026 12:30:57 +0000 Received: from EX19MTAUWC002.ant.amazon.com [205.251.233.51:21145] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.62.198:2525] with esmtp (Farcaster) id 53f93df2-f4cc-426b-a8bf-346efb1e2633; Fri, 11 Sep 2026 12:30:57 +0000 (UTC) X-Farcaster-Flow-ID: 53f93df2-f4cc-426b-a8bf-346efb1e2633 Received: from EX19D001UWA001.ant.amazon.com (10.13.138.214) by EX19MTAUWC002.ant.amazon.com (10.250.64.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.2562.45; Fri, 11 Sep 2026 12:30:57 +0000 Received: from dev-dsk-sakacpav-1a-480d1124.eu-west-1.amazon.com (172.19.96.155) by EX19D001UWA001.ant.amazon.com (10.13.138.214) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.2562.46; Fri, 11 Sep 2026 12:30:54 +0000 From: Pavol Sakac To: Bjorn Helgaas CC: , , David Matlack , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= , Kees Cook , Madhavan Srinivasan , Michael Ellerman , Nicholas Piggin , Christophe Leroy , , Niklas Schnelle , Benjamin Block , Lukas Wunner , "Ionut Nechita" , Subject: [RFC PATCH 4/8] PCI/PM: Serialize pci_bridge_d3_update() Date: Fri, 11 Sep 2026 14:30:52 +0200 Message-ID: <20260911123052.94884-1-sakacpav@amazon.de> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260911-vfopt-s1-v1-0-693271dc0226@amazon.de> References: <20260911-vfopt-s1-v1-0-693271dc0226@amazon.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: EX19D037UWC001.ant.amazon.com (10.13.139.197) To EX19D001UWA001.ant.amazon.com (10.13.138.214) Content-Type: text/plain; charset="utf-8" pci_bridge_d3_update() does an unlocked read-modify-write of bridge->bridge_d3, and its callers are not mutually serialized: the d3cold_allowed sysfs write and the driver-context D3cold helpers hold neither pci_rescan_remove_lock nor device_lock. A concurrent write can lose an update and leave bridge_d3 stale, costing a wrong D3cold decision rather than memory safety. An upcoming change runs pci_bus_add_device() for sibling VFs concurrently, making sibling additions concurrent callers too, so this must land first. Add a mutex around the whole update, taken once for the propagation loop. A device with no D3cold-capable port above it returns before the mutex, so the common add is not funneled through a global lock, and the loop re-evaluates both conditions under it. The mutex serializes the updaters against each other only; the d3cold_allowed store itself still writes an adjacent bit of the same word unlocked, a pre-existing exposure this change neither widens nor closes. The resulting order is pci_rescan_remove_lock, device_lock(any) -> pci_bridge_d3_lock -> pci_bus_sem (read), so pci_bridge_d3_lock must never be acquired while holding pci_bus_sem and no pci_walk_bus() callback may call into this path. The race dates back to commit 9d26d3a8f1b0 ("PCI: Put PCIe ports into D3 during suspend"), is theoretical with no known report, and so carries no Fixes: tag and no stable designation; it claims no measured performance contribution. Assisted-by: LLM Signed-off-by: Pavol Sakac --- drivers/pci/pci.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index c62a315c0b4c..b2a159ef125b 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3095,17 +3095,36 @@ static int pci_dev_check_d3cold(struct pci_dev *dev= , void *data) } =20 /* + * Serializes pci_bridge_d3_update()'s bridge_d3 read-modify-writes and + * their upstream propagation. Ordering: pci_rescan_remove_lock, + * device_lock(any) -> pci_bridge_d3_lock -> pci_bus_sem (read); no + * pci_walk_bus() callback may call into this path. + */ +static DEFINE_MUTEX(pci_bridge_d3_lock); + +/** * pci_bridge_d3_update - Update bridge D3 capabilities * @dev: PCI device which is changed * * Update upstream bridge PM capabilities accordingly depending on if the * device PM configuration was changed or the device is being removed. The * change is also propagated upstream. + * + * Context: Process context. Takes and releases pci_bridge_d3_lock. */ void pci_bridge_d3_update(struct pci_dev *dev) { struct pci_dev *bridge; =20 + /* + * Unlocked fast path; the loop condition re-evaluates both checks + * under the lock. + */ + bridge =3D pci_upstream_bridge(dev); + if (!bridge || !pci_bridge_d3_possible(bridge)) + return; + + mutex_lock(&pci_bridge_d3_lock); while ((bridge =3D pci_upstream_bridge(dev)) && pci_bridge_d3_possible(bridge)) { bool remove =3D !device_is_registered(&dev->dev); @@ -3148,6 +3167,7 @@ void pci_bridge_d3_update(struct pci_dev *dev) /* Propagate change to upstream bridges */ dev =3D bridge; } + mutex_unlock(&pci_bridge_d3_lock); } =20 /** @@ -3157,6 +3177,9 @@ void pci_bridge_d3_update(struct pci_dev *dev) * This function can be used in drivers to enable D3cold from the device * they handle. It also updates upstream PCI bridge PM capabilities * accordingly. + * + * Context: Process context. Takes and releases pci_bridge_d3_lock; + * must not be called from a pci_walk_bus() callback. */ void pci_d3cold_enable(struct pci_dev *dev) { @@ -3174,6 +3197,9 @@ EXPORT_SYMBOL_GPL(pci_d3cold_enable); * This function can be used in drivers to disable D3cold from the device * they handle. It also updates upstream PCI bridge PM capabilities * accordingly. + * + * Context: Process context. Takes and releases pci_bridge_d3_lock; + * must not be called from a pci_walk_bus() callback. */ void pci_d3cold_disable(struct pci_dev *dev) { --=20 2.47.3 From nobody Fri Sep 25 13:55:01 2026 Received: from pdx-out-014.esa.us-west-2.outbound.mail-perimeter.amazon.com (pdx-out-014.esa.us-west-2.outbound.mail-perimeter.amazon.com [35.83.148.184]) (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 168C24756A7; Fri, 11 Sep 2026 12:31:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=35.83.148.184 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789129919; cv=none; b=o5R4APF7v1u/j8UKb8VHqMNE834AAS6Fy2v/ewC3OlR60dR+RKEaXVxP9L1NzY/DA4vzlTV2ssoAm50+WUfhy2od0sJo7hY3ZCnqnKuUY7vbrQe1fAocTawHA+IvbcHqjEJIty2ncl/LuYUEsMdDQ8ySVI3iIRRkiUKdi37uHs4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789129919; c=relaxed/simple; bh=xWx3SoAbj06B10n7IzmRPp8lX8OkmaAcAzNtEiyBYtE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=psKIe7AkYNwVSvCdgCDGBBXk8tsJhzKaVcogF4Pxf+TIiWV2js8k4guh/OUl010kGC2Ro0RwChF4pc+LWPTYCQ7PNdqWl9nTxGbQBpG6zHo3CkYq/SWYgGYhhhpzRcj8C9N2k5SnBhLF5s/iZOHwo6Ptq7Ckam9+Oyye92kg1JI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (2048-bit key) header.d=amazon.de header.i=@amazon.de header.b=nym6RHOL; arc=none smtp.client-ip=35.83.148.184 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=amazon.de header.i=@amazon.de header.b="nym6RHOL" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazoncorp2; t=1789129915; x=1820665915; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=uaHpFCf9InS1VfMhfcAUazBouVXMvz/Y4XYVoqAOo5k=; b=nym6RHOLkYNFt/AGSDBQDY6lPwNuvdtm+nO5+cbGQATdocb6qBfsSfxv 3vK+u4jpwmffirIsGUWsuxY/LQj4qlGUhFWQjV+7uuLBMm5AGMIVzSehP 4CWBUeveIZSJatvxQAC7zdn50WOMKuQ3VhPyivKyPUj8LFj6ixU37IYDM RWi33OEhZ6AoY+w1doCq/sPo6XdRKLiUZYU1yLze8gmg//VPnNSsY3Q2q 21MDnyEYDLWw2ANPZBifLilkn3Rba2fwegRqm/YA4UGhXcJK8c8dAZcDk CHgB5VuLRu8hICqYj32x0RMhhSfDG8C3TG0f4hpJHZ4q06xR0pyRoSvkd A==; X-CSE-ConnectionGUID: 4qH0kDm0QqiBa/83nnHZYQ== X-CSE-MsgGUID: ERk3P2wWQmek5gdyP0r88w== X-IronPort-AV: E=Sophos;i="6.27,97,1787011200"; d="scan'208";a="28216167" Received: from ip-10-5-9-48.us-west-2.compute.internal (HELO smtpout.naws.us-west-2.prod.farcaster.email.amazon.dev) ([10.5.9.48]) by internal-pdx-out-014.esa.us-west-2.outbound.mail-perimeter.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Sep 2026 12:31:52 +0000 Received: from EX19MTAUWA001.ant.amazon.com [205.251.233.236:21641] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.6.93:2525] with esmtp (Farcaster) id 5cb3e6e0-d9b0-4a56-aa7b-619d6898f09c; Fri, 11 Sep 2026 12:31:51 +0000 (UTC) X-Farcaster-Flow-ID: 5cb3e6e0-d9b0-4a56-aa7b-619d6898f09c Received: from EX19D001UWA001.ant.amazon.com (10.13.138.214) by EX19MTAUWA001.ant.amazon.com (10.250.64.204) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.2562.45; Fri, 11 Sep 2026 12:31:51 +0000 Received: from dev-dsk-sakacpav-1a-480d1124.eu-west-1.amazon.com (172.19.96.155) by EX19D001UWA001.ant.amazon.com (10.13.138.214) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.2562.46; Fri, 11 Sep 2026 12:31:48 +0000 From: Pavol Sakac To: Bjorn Helgaas CC: , , David Matlack , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= , Kees Cook , Madhavan Srinivasan , Michael Ellerman , Nicholas Piggin , Christophe Leroy , , Niklas Schnelle , Benjamin Block , Lukas Wunner , "Ionut Nechita" , Subject: [RFC PATCH 5/8] powerpc/pci: Serialize pcibios_bus_add_device() Date: Fri, 11 Sep 2026 14:31:47 +0200 Message-ID: <20260911123147.97312-1-sakacpav@amazon.de> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260911-vfopt-s1-v1-0-693271dc0226@amazon.de> References: <20260911-vfopt-s1-v1-0-693271dc0226@amazon.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: EX19D039UWB002.ant.amazon.com (10.13.138.79) To EX19D001UWA001.ant.amazon.com (10.13.138.214) Content-Type: text/plain; charset="utf-8" The pseries and powernv pcibios_bus_add_device() hooks insert the device into the EEH PE tree with bare list manipulation that arch/powerpc/kernel/eeh.c itself flags as unlocked, and for SR-IOV the pseries hook attaches every VF's eeh_dev to the shared physfn PE. Every caller is serialized by enumeration context today; an upcoming change runs pci_bus_add_device() for sibling VFs concurrently and makes the race reachable. Serialize the platform hook dispatch with an arch-local mutex. Exclusion against the EEH recovery thread stays carried by pci_rescan_remove_lock, and on probe-path enables the residue folds into the pre-existing exposure described in a later patch in this series ("PCI/IOV: Initialize virtual functions in parallel"). A proper PE-tree lock is a larger EEH cleanup, so eeh_pe.c is left alone. Assisted-by: LLM Signed-off-by: Pavol Sakac --- arch/powerpc/kernel/pci-common.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-com= mon.c index 4fc52c21fe5d..21cccd0e97f8 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1046,6 +1046,15 @@ void pcibios_setup_bus_self(struct pci_bus *bus) phb->controller_ops.dma_bus_setup(bus); } =20 +/* + * The pseries/powernv hooks update the shared EEH PE tree with no + * internal locking; serialize concurrent sibling VF additions. + * Removal-side updates do not take this lock: additions are + * drained before any unwind, and the sysfs enable and EEH paths + * hold pci_rescan_remove_lock. + */ +static DEFINE_MUTEX(pcibios_bus_add_device_lock); + void pcibios_bus_add_device(struct pci_dev *dev) { struct pci_controller *phb; @@ -1068,8 +1077,11 @@ void pcibios_bus_add_device(struct pci_dev *dev) if (ppc_md.pci_irq_fixup) ppc_md.pci_irq_fixup(dev); =20 - if (ppc_md.pcibios_bus_add_device) + if (ppc_md.pcibios_bus_add_device) { + mutex_lock(&pcibios_bus_add_device_lock); ppc_md.pcibios_bus_add_device(dev); + mutex_unlock(&pcibios_bus_add_device_lock); + } } =20 int pcibios_device_add(struct pci_dev *dev) --=20 2.47.3 From nobody Fri Sep 25 13:55:01 2026 Received: from pdx-out-012.esa.us-west-2.outbound.mail-perimeter.amazon.com (pdx-out-012.esa.us-west-2.outbound.mail-perimeter.amazon.com [35.162.73.231]) (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 D5A5936C9C0; Fri, 11 Sep 2026 12:32:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=35.162.73.231 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789129972; cv=none; b=VxvEXf4VtTHCQazgzd6JeTIflNGqa1C3sS5htXCSsBTwux3rB8nkPC/qGlG1vUJC2bnml1iXL3xi6sVXIFGf96jibIgx+7+BQguZ8V+MXrOvl2Hql54ZiOzgbrBYGONFpX7oRtZt3HhElELOmL+yKch3oHPxSjigpnaXMoXnjxo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789129972; c=relaxed/simple; bh=gkfBq/d2KCZiWb76KJJvG3RW2xOb5uDlYHUE3mhl5ls=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=rCs00cjrMBHNXo/gPZtLcxUd32AL/BA2YJUN0bN2glvFWzN70nygB16uGKMbjSkVIZlVqWaD/u75FPFp1SdQalSDdz86QBnJoCUX5a11DROmrQKBgfA9RvbMwJ924jUxQ2WzPx/5xx1JX+G4xEwpJcivUvaNla3x7UPkqeP7kcQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (2048-bit key) header.d=amazon.de header.i=@amazon.de header.b=bBgnqd3c; arc=none smtp.client-ip=35.162.73.231 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=amazon.de header.i=@amazon.de header.b="bBgnqd3c" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazoncorp2; t=1789129969; x=1820665969; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Ltbq+GWhG/1KvJm+1fqt+ZO5n9zoPu7qeY/Gw0JRs8Q=; b=bBgnqd3cumFs7HIhM56qIVj40CWOnPbQOqa8LYsx3iZIzw9mRfreTsv+ pyiw5bojI7B8w459QEWcXznkjOnXsatbHN4G4A34yex3Mc9gGAxjLU6tC M295HLrisbG5wPZLzW2QYEav/IYExFUv9sDt131oUI50SZrE/HAR1ZrGa XAVD4t7geZkcN0+a6aGH6qPBMYKKaCxVF3yieJErX7/5wEDbUD2H/jrAc JFYRSqnRPKrFJ3yIG2HYP01wRAY/Imh2JgDCmlSKd2vfcZc8mNpCNiX6S +nhCS4KjUF1MOebplxtuOjby/nzw2rDkziLbI4/NyA7f1aoOofH1jSOGs A==; X-CSE-ConnectionGUID: 2DIrQMtuQdu/rLuQKS2jXQ== X-CSE-MsgGUID: MvMsu7H/QwOI0AyHD2ETgg== X-IronPort-AV: E=Sophos;i="6.27,97,1787011200"; d="scan'208";a="28221489" Received: from ip-10-5-9-48.us-west-2.compute.internal (HELO smtpout.naws.us-west-2.prod.farcaster.email.amazon.dev) ([10.5.9.48]) by internal-pdx-out-012.esa.us-west-2.outbound.mail-perimeter.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Sep 2026 12:32:46 +0000 Received: from EX19MTAUWC001.ant.amazon.com [205.251.233.105:23580] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.22.113:2525] with esmtp (Farcaster) id beb290be-5da5-4822-b0d6-73219791d65a; Fri, 11 Sep 2026 12:32:45 +0000 (UTC) X-Farcaster-Flow-ID: beb290be-5da5-4822-b0d6-73219791d65a Received: from EX19D001UWA001.ant.amazon.com (10.13.138.214) by EX19MTAUWC001.ant.amazon.com (10.250.64.174) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.2562.45; Fri, 11 Sep 2026 12:32:45 +0000 Received: from dev-dsk-sakacpav-1a-480d1124.eu-west-1.amazon.com (172.19.96.155) by EX19D001UWA001.ant.amazon.com (10.13.138.214) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.2562.46; Fri, 11 Sep 2026 12:32:42 +0000 From: Pavol Sakac To: Bjorn Helgaas CC: , , David Matlack , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= , Kees Cook , Madhavan Srinivasan , Michael Ellerman , Nicholas Piggin , Christophe Leroy , , Niklas Schnelle , Benjamin Block , Lukas Wunner , "Ionut Nechita" , Subject: [RFC PATCH 6/8] PCI/IOV: Let sriov_add_vfs() own the failure unwind Date: Fri, 11 Sep 2026 14:32:41 +0200 Message-ID: <20260911123241.3312-1-sakacpav@amazon.de> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260911-vfopt-s1-v1-0-693271dc0226@amazon.de> References: <20260911-vfopt-s1-v1-0-693271dc0226@amazon.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: EX19D039UWB002.ant.amazon.com (10.13.138.79) To EX19D001UWA001.ant.amazon.com (10.13.138.214) Content-Type: text/plain; charset="utf-8" __pci_iov_add_virtfn() unwinds its own sysfs-link failure with pci_stop_and_remove_bus_device(), which lockdep-asserts pci_rescan_remove_lock. The next commit runs __pci_iov_add_virtfn() from async workers that must never take or require that lock, so the unwind has to move to the enabling task. Leave __pci_iov_add_virtfn() reporting only and let each caller unwind through pci_iov_remove_virtfn(), whose lookup-based design is correct at every failure stage. sriov_add_vfs() unwinds ids 0..i inclusive on failure of VF i, since VF i may be registered but not yet linked. The wrapper unwinds fully before returning, because its EEH caller discards the return code: the VF is removed through pci_iov_remove_virtfn(), which also frees the bus it empties, and a bus this call created with no VF registered on it is removed explicitly. Assisted-by: LLM Signed-off-by: Pavol Sakac --- drivers/pci/iov.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index dda9303516f5..a32b2c295922 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -383,35 +383,42 @@ static int __pci_iov_add_virtfn(struct pci_dev *dev, = struct pci_bus *bus, pci_device_add(virtfn, virtfn->bus); rc =3D pci_iov_sysfs_link(dev, virtfn, id); if (rc) - goto failed1; + return rc; =20 pci_bus_add_device(virtfn); =20 return 0; - -failed1: - pci_stop_and_remove_bus_device(virtfn); - pci_dev_put(dev); - - return rc; } =20 int pci_iov_add_virtfn(struct pci_dev *dev, int id) { struct pci_bus *bus; + bool created; int rc; =20 - bus =3D virtfn_add_bus(dev->bus, pci_iov_virtfn_bus(dev, id), NULL); + bus =3D virtfn_add_bus(dev->bus, pci_iov_virtfn_bus(dev, id), &created); if (!bus) return -ENOMEM; =20 rc =3D __pci_iov_add_virtfn(dev, bus, id); - if (rc) - virtfn_remove_bus(dev->bus, bus); + if (rc) { + pci_iov_remove_virtfn(dev, id); + /* + * Same ownership and stale-pointer rules as the + * sriov_add_vfs() bus unwind. + */ + if (created) { + bus =3D pci_find_bus(pci_domain_nr(dev->bus), + pci_iov_virtfn_bus(dev, id)); + if (bus) + virtfn_remove_bus(dev->bus, bus); + } + } =20 return rc; } =20 +/* Unwind primitive for partial adds: a missing VF must stay a silent no-o= p. */ void pci_iov_remove_virtfn(struct pci_dev *dev, int id) { char buf[VIRTFN_ID_LEN]; @@ -681,8 +688,10 @@ static int sriov_add_vfs(struct pci_dev *dev, u16 num_= vfs) kvfree(buses); return 0; failed: - while (i--) + /* VF i may be partially added: unwind ids 0..i inclusive. */ + do { pci_iov_remove_virtfn(dev, i); + } while (i--); =20 remove_buses: /* --=20 2.47.3 From nobody Fri Sep 25 13:55:01 2026 Received: from pdx-out-001.esa.us-west-2.outbound.mail-perimeter.amazon.com (pdx-out-001.esa.us-west-2.outbound.mail-perimeter.amazon.com [44.245.243.92]) (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 DC8E54756B4; Fri, 11 Sep 2026 12:33:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=44.245.243.92 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789130022; cv=none; b=gIW7rikf67fyzpAj1eeQarGAUElNCATHHAzH9F+N9QxX81xT8GirItyfBrdoyIcd4eoo+AWgLlHs+UAOmufRCj/aRF0YcW+b3v+Vm7fsD9bdGU9bGUXE6GRONJ2ZDNMVu/8bowCfChrynejHg3VnA3kW1d9E+kTB6HEGkUZDgw8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789130022; c=relaxed/simple; bh=VjakNwENdXvrn/9FZZ8OZL8oQvOvPLvx4BwTPCaqVYA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Y6EtxOxObkCxn7BOK2juIo2gvI63s0W7fPtf7sfG5gEjbi+Nzb5GCNDaJ1lHCyUhjZ4TdEnm60S5AGRBsVE/UfAHK6G4LLr+G5mF1lYNrACwTppwvp1aJD50wJh2g2cQVYr/vY17rb1pMSrSiJergEmJIAZIIzYyDvHZTawRcpE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (2048-bit key) header.d=amazon.de header.i=@amazon.de header.b=BNT1qZXH; arc=none smtp.client-ip=44.245.243.92 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=amazon.de header.i=@amazon.de header.b="BNT1qZXH" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazoncorp2; t=1789130020; x=1820666020; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=1vETXbf3r5hI7BpXmqQgNKVdrE3cdotOo6s5YjUJkp8=; b=BNT1qZXHQdirSLM7AMFEOdjhMZDdq1P/NLKosfCZnGfjaxjOmUmGMnLx VLp8b9LKnRamHv3Ojz4X08BXPsjXoykfzWUfQZnJmo6hWFV7N/8jS4ovh +8+MBoR/mQ0yVmC8JhIDLTkcNVU4MuVZfFBD/ijky6+5FRRfjYZzUEimX pMTTlnudUXg3FN03kRFmJCTypMWEUrhWCFkkFHipFiRsHtW5SNaYKaH3k VJL3Po5ogIl3/oZX9Z8G4QmEe3oRmJ6EKLqr2iELFSC0UrSLVC0PSAC/k yGc5vuSf253vHk8eY8Oqqk0norjEE6InZbDYrQimojOgpwMCx3dvOMc1C g==; X-CSE-ConnectionGUID: UkOggjMGQ66LJB+WpG4Ung== X-CSE-MsgGUID: 0IQ9IS1yRgOD0kiITQ7KdQ== X-IronPort-AV: E=Sophos;i="6.27,97,1787011200"; d="scan'208";a="27924283" Received: from ip-10-5-12-219.us-west-2.compute.internal (HELO smtpout.naws.us-west-2.prod.farcaster.email.amazon.dev) ([10.5.12.219]) by internal-pdx-out-001.esa.us-west-2.outbound.mail-perimeter.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Sep 2026 12:33:40 +0000 Received: from EX19MTAUWB002.ant.amazon.com [205.251.233.111:4960] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.22.113:2525] with esmtp (Farcaster) id fe2077a9-0e1e-48fc-8900-b530f5abcdae; Fri, 11 Sep 2026 12:33:40 +0000 (UTC) X-Farcaster-Flow-ID: fe2077a9-0e1e-48fc-8900-b530f5abcdae Received: from EX19D001UWA001.ant.amazon.com (10.13.138.214) by EX19MTAUWB002.ant.amazon.com (10.250.64.231) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.2562.45; Fri, 11 Sep 2026 12:33:39 +0000 Received: from dev-dsk-sakacpav-1a-480d1124.eu-west-1.amazon.com (172.19.96.155) by EX19D001UWA001.ant.amazon.com (10.13.138.214) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.2562.46; Fri, 11 Sep 2026 12:33:37 +0000 From: Pavol Sakac To: Bjorn Helgaas CC: , , David Matlack , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= , Kees Cook , Madhavan Srinivasan , Michael Ellerman , Nicholas Piggin , Christophe Leroy , , Niklas Schnelle , Benjamin Block , Lukas Wunner , "Ionut Nechita" , Subject: [RFC PATCH 7/8] PCI/IOV: Initialize virtual functions in parallel Date: Fri, 11 Sep 2026 14:33:35 +0200 Message-ID: <20260911123335.7558-1-sakacpav@amazon.de> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260911-vfopt-s1-v1-0-693271dc0226@amazon.de> References: <20260911-vfopt-s1-v1-0-693271dc0226@amazon.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: EX19D039UWB004.ant.amazon.com (10.13.138.57) To EX19D001UWA001.ant.amazon.com (10.13.138.214) Content-Type: text/plain; charset="utf-8" Serial per-VF scanning and device addition dominate SR-IOV enable time at large VF counts, and a kexec-based live update re-creates every VF through this same loop. Distribute the per-VF work over the kernel's async machinery. VF0 is added synchronously first because pci_iov_scan_device() writes the config fields shared by every VF only on the id =3D=3D 0 pass and reads them locklessly afterwards. The rest are fanned out over async entries sharing an on-stack context with an atomic id cursor, scheduled on the PF's node with async_schedule_node_domain(). A worker that fails records the first error there and the enabling task unwinds every id descending; when several fail the temporally first errno is reported where the serial code reported the lowest failing id's, and nothing in-tree consumes the distinction. The workers claim ids from that cursor and keep draining until the range is exhausted, so entries are capped at one per online CPU rather than one per VF. One entry per VF would make the submission cost -- an allocation plus the global async_lock per entry -- scale with the VF count and fall on the enabling task, contending with the workers it has already queued. No worker takes pci_rescan_remove_lock, which the sysfs enable path holds around the whole sriov_configure() call, and each runs exactly the code the enabling task ran serially, so no new deadlock class is constructible. The probe-time pci_enable_sriov() path holds no rescan lock, so its failure unwind reaches pci_stop_and_remove_bus_device() unlocked, a pre-existing hole this neither widens nor closes. Within one enable, sysfs links, uevents and VF binds now occur in nondeterministic order, and a failed enable may transiently create VFs past the failing id before unwinding them all. VF probes run in async context, where a synchronous request_module() WARNs. Assisted-by: LLM Signed-off-by: Pavol Sakac --- drivers/pci/iov.c | 83 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 5 deletions(-) diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index a32b2c295922..ac2ddda4bf14 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -7,6 +7,7 @@ * Copyright (C) 2009 Intel Corporation, Yu Zhao */ =20 +#include #include #include #include @@ -350,6 +351,12 @@ static struct pci_dev *pci_iov_scan_device(struct pci_= dev *dev, int id, return virtfn; } =20 +/* + * Safe to run concurrently for distinct ids only, on pre-created buses + * the caller keeps alive; id 0 must complete first + * (pci_read_vf_config_common()). Must not take pci_rescan_remove_lock; + * failures are unwound by the caller via pci_iov_remove_virtfn(). + */ static int __pci_iov_add_virtfn(struct pci_dev *dev, struct pci_bus *bus, int id) { @@ -644,11 +651,41 @@ int __weak pcibios_sriov_disable(struct pci_dev *pdev) return 0; } =20 +/* On-stack; live until async_synchronize_full_domain() drains the workers= . */ +struct sriov_add_ctx { + struct pci_dev *dev; + struct pci_bus **buses; + u16 num_vfs; + atomic_t next_id; + atomic_t error; +}; + +static void sriov_add_vf_work(void *data, async_cookie_t cookie) +{ + struct sriov_add_ctx *ctx =3D data; + int id; + int rc; + + while ((id =3D atomic_fetch_inc(&ctx->next_id)) < ctx->num_vfs) { + rc =3D __pci_iov_add_virtfn(ctx->dev, ctx->buses[id], id); + if (rc) + atomic_cmpxchg(&ctx->error, 0, rc); + } +} + static int sriov_add_vfs(struct pci_dev *dev, u16 num_vfs) { + /* + * EXCLUSIVE: a registered domain joins async_global_pending, so a + * VF probe calling async_synchronize_full() from a worker would + * self-deadlock. + */ + ASYNC_DOMAIN_EXCLUSIVE(sriov_async_domain); + struct sriov_add_ctx ctx; unsigned long *created_buses; struct pci_bus **buses; struct pci_bus *bus; + unsigned int nr_workers; unsigned int i; int rc; =20 @@ -678,17 +715,48 @@ static int sriov_add_vfs(struct pci_dev *dev, u16 num= _vfs) __set_bit(i, created_buses); } =20 - for (i =3D 0; i < num_vfs; i++) { - rc =3D __pci_iov_add_virtfn(dev, buses[i], i); - if (rc) - goto failed; + /* Id 0 writes the shared config fields later ids read locklessly. */ + rc =3D __pci_iov_add_virtfn(dev, buses[0], 0); + if (rc) { + i =3D 0; + goto failed; + } + + ctx.dev =3D dev; + ctx.buses =3D buses; + ctx.num_vfs =3D num_vfs; + atomic_set(&ctx.next_id, 1); /* VF0 was added above */ + atomic_set(&ctx.error, 0); + + /* + * An entry async_schedule_node_domain() cannot queue (allocation + * failure or async backlog) runs in the caller and drains the + * remaining range -- every id is added exactly once. + */ + nr_workers =3D min_t(unsigned int, num_vfs - 1, num_online_cpus()); + for (i =3D 0; i < nr_workers; i++) + async_schedule_node_domain(sriov_add_vf_work, &ctx, + dev_to_node(&dev->dev), + &sriov_async_domain); + + async_synchronize_full_domain(&sriov_async_domain); + + rc =3D atomic_read(&ctx.error); + if (rc) { + i =3D num_vfs - 1; + goto failed; } =20 bitmap_free(created_buses); kvfree(buses); return 0; failed: - /* VF i may be partially added: unwind ids 0..i inclusive. */ + /* + * Unwind ids 0..i inclusive: i is 0 on the sync VF0 path and + * num_vfs - 1 on the worker path (workers past the first failure + * may have added more); pci_iov_remove_virtfn() copes with + * partial and never-added ids. + */ do { pci_iov_remove_virtfn(dev, i); } while (i--); @@ -832,6 +900,11 @@ static void sriov_del_vfs(struct pci_dev *dev) struct pci_sriov *iov =3D dev->sriov; int i; =20 + /* + * Deliberately serial: the parallel-add locking arguments (and the + * powerpc pcibios_bus_add_device() serialization) assume removal + * never runs concurrently. + */ for (i =3D 0; i < iov->num_VFs; i++) pci_iov_remove_virtfn(dev, i); } --=20 2.47.3 From nobody Fri Sep 25 13:55:01 2026 Received: from pdx-out-010.esa.us-west-2.outbound.mail-perimeter.amazon.com (pdx-out-010.esa.us-west-2.outbound.mail-perimeter.amazon.com [52.12.53.23]) (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 EF7CD46AA60; Fri, 11 Sep 2026 12:34:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=52.12.53.23 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789130076; cv=none; b=KRLZ6914IhBYNZwGqueHmadBeGVz52NLHJTwG0f8eoFdllJ44SLsDJR+yU8GA0iCv6Xly8GbG1YTkdQrAsV5WP18DmS45eoFlVJRLZbzi4Ss58AuXDz9duEVIx9GuVf4qiuyiP292qn+3zUYgrCg4DqDE3FZA5ZqvCINyo6toWM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789130076; c=relaxed/simple; bh=cmspiYdTEUA6pGHUuwd7h1loRX0CIRxqktQS3CmMLoI=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=BPuyNRENq8UJR8xqx9UQO6rpBhtJqVdZ/Tt4Kz1uRLcLJ8Szap8k+LSk1pwoRSRsp6RIXPuIatz2W0RtOZwZo4b1WtiQ7eRf2Oct62IHl9uLxIW6Nj1wdwLc2PZ/NBJTDTOoEStzweV1SC+3eb7fmJXMp187j+zk5M2BosYs+xo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (2048-bit key) header.d=amazon.de header.i=@amazon.de header.b=optqVINp; arc=none smtp.client-ip=52.12.53.23 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=amazon.de header.i=@amazon.de header.b="optqVINp" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazoncorp2; t=1789130074; x=1820666074; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=TtB3+ZqqigKPMCEU3NIGj/FC5xLnLRZnxg1hSDBeBgU=; b=optqVINpGpbjNAwMpGcawgo4mvXrafOxx0oedHj62ETScRgdho84pSmT 4znE5BWZv9C2s7NexK8tlYKEFnQOdMebaBmAh5sNiuzWv2xYJ50V1cj0Q HqH3d+P9tzp2tSo47ydq0b4gbR3FoPnVK8Vz68d8QFZ4SLF6NNCPiMpZ2 mGcNEsCcp/1+NauJ9eKkA9cwbkojXFCUkPa0YfNMoGF2iDalrUt7wQrSj R9VGcDdMjQtk1H2EJrYpaWFOGQcW8DKJ46nft5cTOL2tTHZoDutGyj1Ex BtobLzC1v/eIcn4vQOUHDQ53KtLGgvZLlCT9gyWPEzQ/s5wWFqvOxXpC5 g==; X-CSE-ConnectionGUID: V8kWbUZpS0uhb04BY/Kk5g== X-CSE-MsgGUID: ZOhDAvsiSRaGYYP42HgeRg== X-IronPort-AV: E=Sophos;i="6.27,97,1787011200"; d="scan'208";a="28294073" Received: from ip-10-5-0-115.us-west-2.compute.internal (HELO smtpout.naws.us-west-2.prod.farcaster.email.amazon.dev) ([10.5.0.115]) by internal-pdx-out-010.esa.us-west-2.outbound.mail-perimeter.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Sep 2026 12:34:34 +0000 Received: from EX19MTAUWA002.ant.amazon.com [205.251.233.234:3959] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.6.93:2525] with esmtp (Farcaster) id 48290a84-2435-4cd0-b88c-3197c072d08d; Fri, 11 Sep 2026 12:34:34 +0000 (UTC) X-Farcaster-Flow-ID: 48290a84-2435-4cd0-b88c-3197c072d08d Received: from EX19D001UWA001.ant.amazon.com (10.13.138.214) by EX19MTAUWA002.ant.amazon.com (10.250.64.202) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.2562.45; Fri, 11 Sep 2026 12:34:33 +0000 Received: from dev-dsk-sakacpav-1a-480d1124.eu-west-1.amazon.com (172.19.96.155) by EX19D001UWA001.ant.amazon.com (10.13.138.214) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.2562.46; Fri, 11 Sep 2026 12:34:31 +0000 From: Pavol Sakac To: Bjorn Helgaas CC: , , David Matlack , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= , Kees Cook , Madhavan Srinivasan , Michael Ellerman , Nicholas Piggin , Christophe Leroy , , Niklas Schnelle , Benjamin Block , Lukas Wunner , "Ionut Nechita" , Subject: [RFC PATCH 8/8] PCI: Probe inline from node-local workqueue workers Date: Fri, 11 Sep 2026 14:34:29 +0200 Message-ID: <20260911123429.11491-1-sakacpav@amazon.de> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260911-vfopt-s1-v1-0-693271dc0226@amazon.de> References: <20260911-vfopt-s1-v1-0-693271dc0226@amazon.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: EX19D032UWB004.ant.amazon.com (10.13.139.136) To EX19D001UWA001.ant.amazon.com (10.13.138.214) Content-Type: text/plain; charset="utf-8" pci_call_probe() dispatches each probe with queue_work_on() to a housekeeping CPU of the device's node, except where it already probes inline. A VF added by one of the preceding node-placed async VF-add workers already executes on its device's node, so the dispatch buys it no locality: it funnels every VF probe through the single CPU cpumask_any_and() elects and re-serializes the parallel enable at the probe step. Call local_pci_probe() directly when the caller is a workqueue worker (PF_WQ_WORKER) whose current CPU is on the device's node and in the same HK_TYPE_DOMAIN housekeeping mask the dispatch elects from. The gate is not VF-specific: any probe already running in a node-local housekeeping kworker takes it, while a probe from a task that is not a worker keeps the dispatch. Assisted-by: LLM Signed-off-by: Pavol Sakac --- drivers/pci/pci-driver.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index e16aa59dd7ac..f5e12a5044cf 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -392,6 +392,22 @@ static bool pci_physfn_is_probed(struct pci_dev *dev) #endif } =20 +static bool pci_probe_inline(int node) +{ + /* The CPU is a placement hint; an unstable raw read is fine. */ + int cpu =3D raw_smp_processor_id(); + bool ret; + + if (!(current->flags & PF_WQ_WORKER) || cpu_to_node(cpu) !=3D node) + return false; + + rcu_read_lock(); + ret =3D housekeeping_cpu(cpu, HK_TYPE_DOMAIN); + rcu_read_unlock(); + + return ret; +} + static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, const struct pci_device_id *id) { @@ -412,7 +428,7 @@ static int pci_call_probe(struct pci_driver *drv, struc= t pci_dev *dev, * device is probed from work_on_cpu() of the Physical device. */ if (node < 0 || node >=3D MAX_NUMNODES || !node_online(node) || - pci_physfn_is_probed(dev)) { + pci_physfn_is_probed(dev) || pci_probe_inline(node)) { error =3D local_pci_probe(&ddi); } else { struct pci_probe_arg arg =3D { .ddi =3D &ddi }; --=20 2.47.3