From nobody Fri Oct 3 15:35:59 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 3F422326D6E; Fri, 29 Aug 2025 15:48:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756482506; cv=none; b=hcSnGMc4iJ8O6s9bMhGU2kyt68bvg/MiIVF2r2MArtAq0oNoNePeMbbSoeVaY25g/GvCKA6DA0utplmxw+ncYImmckFNAibTHicqK+t3+myczKDhB0WSVJc1zHfs/8FEhlN6zoSn+tJe3IL7F4HYPwABI+6eW7I48/BHemZYtJM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756482506; c=relaxed/simple; bh=SuR/4PvyX3AQ13jiY8VYnneI4pJyFeidjVrUVvNAUMQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lhjZKnvgdMeLfwG3FW9tT0WqXcVyUueLUOGy2UYsLth4a1/ngQNpbsWXvPOxdkOR0K6MMnrqAgVE0TDBcdzYHpoLf9PnXBT5blnyh85PhmQAreZtDk7qF/4MJmmYOx0Uvs52usGfhUfgCyVFREAG4/WOMzC4/6KugZoORofjRBo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=LIZDY4St; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="LIZDY4St" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6E01CC4CEF7; Fri, 29 Aug 2025 15:48:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756482505; bh=SuR/4PvyX3AQ13jiY8VYnneI4pJyFeidjVrUVvNAUMQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LIZDY4StLXVa/LB5d9TsXGTHLSuUzB04YE5nCWjZ/7J6S/WvboX0d3QndN9OcCQVu b2qvGly3nZnPQ2KS+LiPs5Gm+BG5nEp1o05HyNvGbJRTgLfN4fDbcEW2Wk+vIsB21t 8jdEC59wBRKTAAW8ItIIqBMzLw/MquU4IJN0tDHei2eSs8AsGV7Fm7XZZKo8Jh6Uaf Xypbie2z45y0uYQ4z4ZfuK4bQOisvTaDlPuIxtx/Dao7AqMxTwlRF2RAObSQflYDGj hCKr2J7EqQFBFEu5z6URC1OexkAmkg76LhVY/kPYY5J+pv7S+6V7tF6y7V9VtlYBJh +cU35ODJSZQkA== From: Frederic Weisbecker To: LKML Cc: Frederic Weisbecker , Bjorn Helgaas , Marco Crivellari , Michal Hocko , Peter Zijlstra , Tejun Heo , Thomas Gleixner , Vlastimil Babka , Waiman Long , linux-pci@vger.kernel.org Subject: [PATCH 02/33] PCI: Protect against concurrent change of housekeeping cpumask Date: Fri, 29 Aug 2025 17:47:43 +0200 Message-ID: <20250829154814.47015-3-frederic@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250829154814.47015-1-frederic@kernel.org> References: <20250829154814.47015-1-frederic@kernel.org> 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 Content-Type: text/plain; charset="utf-8" HK_TYPE_DOMAIN will soon integrate cpuset isolated partitions and therefore be made modifyable at runtime. Synchronize against the cpumask update using RCU. The RCU locked section includes both the housekeeping CPU target election for the PCI probe work and the work enqueue. This way the housekeeping update side will simply need to flush the pending related works after updating the housekeeping mask in order to make sure that no PCI work ever executes on an isolated CPU. Signed-off-by: Frederic Weisbecker --- drivers/pci/pci-driver.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 63665240ae87..cf2b83004886 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -302,9 +302,8 @@ struct drv_dev_and_id { const struct pci_device_id *id; }; =20 -static long local_pci_probe(void *_ddi) +static int local_pci_probe(struct drv_dev_and_id *ddi) { - struct drv_dev_and_id *ddi =3D _ddi; struct pci_dev *pci_dev =3D ddi->dev; struct pci_driver *pci_drv =3D ddi->drv; struct device *dev =3D &pci_dev->dev; @@ -338,6 +337,19 @@ static long local_pci_probe(void *_ddi) return 0; } =20 +struct pci_probe_arg { + struct drv_dev_and_id *ddi; + struct work_struct work; + int ret; +}; + +static void local_pci_probe_callback(struct work_struct *work) +{ + struct pci_probe_arg *arg =3D container_of(work, struct pci_probe_arg, wo= rk); + + arg->ret =3D local_pci_probe(arg->ddi); +} + static bool pci_physfn_is_probed(struct pci_dev *dev) { #ifdef CONFIG_PCI_IOV @@ -362,34 +374,44 @@ static int pci_call_probe(struct pci_driver *drv, str= uct pci_dev *dev, dev->is_probed =3D 1; =20 cpu_hotplug_disable(); - /* * Prevent nesting work_on_cpu() for the case where a Virtual Function * 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)) { - cpu =3D nr_cpu_ids; + error =3D local_pci_probe(&ddi); } else { cpumask_var_t wq_domain_mask; + struct pci_probe_arg arg =3D { .ddi =3D &ddi }; + + INIT_WORK_ONSTACK(&arg.work, local_pci_probe_callback); =20 if (!zalloc_cpumask_var(&wq_domain_mask, GFP_KERNEL)) { error =3D -ENOMEM; goto out; } + + rcu_read_lock(); cpumask_and(wq_domain_mask, housekeeping_cpumask(HK_TYPE_WQ), housekeeping_cpumask(HK_TYPE_DOMAIN)); =20 cpu =3D cpumask_any_and(cpumask_of_node(node), wq_domain_mask); + if (cpu < nr_cpu_ids) { + schedule_work_on(cpu, &arg.work); + rcu_read_unlock(); + flush_work(&arg.work); + error =3D arg.ret; + } else { + rcu_read_unlock(); + error =3D local_pci_probe(&ddi); + } + free_cpumask_var(wq_domain_mask); + destroy_work_on_stack(&arg.work); } - - if (cpu < nr_cpu_ids) - error =3D work_on_cpu(cpu, local_pci_probe, &ddi); - else - error =3D local_pci_probe(&ddi); out: dev->is_probed =3D 0; cpu_hotplug_enable(); --=20 2.51.0