From nobody Thu Sep 24 12:53:02 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 7E5565304C6 for ; Wed, 23 Sep 2026 13:18:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790169503; cv=none; b=U6ghRZv91oT1/vL6OwWzPZaT3mgt+D4odMvK7iCpoGsb6hDIF9oOorpgJSBYze3vWILNSSuyN++PnHHyboq0ODLD2bMwtkBYWeNtQpSjJgJj7TAK1/JLlo4nwkTrKo0Q/JiJMjZtUezQ4KalH2SL/PHBXBf/y2rl4AdDbsZkaIM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790169503; c=relaxed/simple; bh=VAeffurB1LEC7MePWxGtJFLS0+Wo9Bw4rm++iGLvDsA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=uAN1WhJqKcxlnNp5IF18lZ8oUdjmB7o06xaQ2qnLxgjJIBt1iLttbO/sPPq5tIFef+lO/tB257XjWwY5huG3Z2K1pZlYaU3g8kQAS3XuWxzc94DoQ+HxCYsAL60UWOXbFQc5nQtByUhFYWnw3wXXA7E5uh1WWOgyOyOYpSylX/k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=RCkcnDnv; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="RCkcnDnv" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1790169501; x=1821705501; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=VAeffurB1LEC7MePWxGtJFLS0+Wo9Bw4rm++iGLvDsA=; b=RCkcnDnvZLIZ3VfjrgtkmdNd5CYePrWcREmkIoTo6aITWJBoIN38l0uX JcipGXDH/ccjL58s68W65SfKkq0VN3KU2jOE719goifc/+Af11adYzVJc Qm5tujea48X/ebyW5PntpzO8n6aYPzWMdA3yjekMfdVeMyOiwu/QX+qiV hVb6vIQ7iU9ylvZJ5qE4gPxoFuK8zwkU/ZHgVKI40R/D8VzEZBjYWm2vx gf4L3Az4yBxpx5TI/8C6meOexpsh6z4nihCpcwcDFWD+xaoEjThhJIwSi BiI5Yy1sRuBQxJrO3IJdF2wvTPjvR7P0M/mYJ570fh16o45ogHLlzxDnW Q==; X-CSE-ConnectionGUID: aHg/qptPThOAMKzcc/VxmA== X-CSE-MsgGUID: 0vvrX+C5Qa27T4cboaReWg== X-IronPort-AV: E=McAfee;i="6800,10657,11913"; a="90979643" X-IronPort-AV: E=Sophos;i="6.27,118,1787036400"; d="scan'208";a="90979643" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2026 06:18:19 -0700 X-CSE-ConnectionGUID: YONggUCYQsylg7bfmOoSYg== X-CSE-MsgGUID: SD4dEv2nTdyKwSGYtLnrTw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,118,1787036400"; d="scan'208";a="272784454" Received: from ijarvine-mobl1.ger.corp.intel.com (HELO localhost) ([10.245.244.13]) by fmviesa010-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2026 06:18:15 -0700 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= To: Maciej Grochowski , Nikolas Joshua Britton , Geramy Loveless , Eric Auger , Alexey Fomenko , Bjorn Helgaas , Lorenzo Pieralisi , Rob Herring , =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= , linux-kernel@vger.kernel.org Cc: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Subject: [PATCH 1/5] resource: Mark free space assigned Date: Wed, 23 Sep 2026 16:17:51 +0300 Message-ID: <20260923131757.7792-2-ilpo.jarvinen@linux.intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260923131757.7792-1-ilpo.jarvinen@linux.intel.com> References: <20260923131757.7792-1-ilpo.jarvinen@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Free space ranges are (part of) assigned ranges. Since new resources have IORESOURCE_UNSET, the flag gets copied also to full_avail.flags, which hampers printing them with %pR. Clear IORESOURCE_UNSET for the free space indicator resource. Signed-off-by: Ilpo J=C3=A4rvinen Reviewed-by: Bradley Morgan --- kernel/resource.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/resource.c b/kernel/resource.c index e60539a55541..17e7fccd859c 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -731,6 +731,7 @@ static int __find_resource_space(struct resource *root,= struct resource *old, resource_alignf alignf =3D constraint->alignf; =20 full_avail.start =3D root->start; + full_avail.flags &=3D ~IORESOURCE_UNSET; /* * Skip past an allocated resource that starts at 0, since the assignment * of this->start - 1 to full_avail->end below would cause an underflow. --=20 2.47.3 From nobody Thu Sep 24 12:53:02 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 C3EE45218AF; Wed, 23 Sep 2026 13:18:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790169517; cv=none; b=Glrx+YI8MUf94RY/Y4J5Km/lQJLllckT2tNe18swTHSu8DTvb5+Nb0+iSMGGOTM3i1vJrNsaeDEwfOLe9fyZ/AErWmexC+GAk4nFPtdkoUvMT9ivK+Cq+VnoPtGGQtzjKAlE3phoxHVzD4C1XsNPSxHP1cPLdsOj4I8rwNtdR2s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790169517; c=relaxed/simple; bh=0dWCjrgLSm8/r6A8g9qrCMimfAoYRcYaBYZ8vU5IJ1w=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Ikd8NGhyj+0Himiaxzu76o403Egu/m3TRGCrCYnYhHJwhTq8UDm+WLoKQ4WMeScXtigCfdWphDmNcz/NuTfq/X5g9sUaSOnzWx6khbKaEBzRQP4cX3Mfn0S1lZ21wJH0SjpXZJ/YK3wwWG+DJYJ8c1d2rpmMNvNmY6bJaM7K9SU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=EnPlg1cG; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="EnPlg1cG" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1790169512; x=1821705512; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=0dWCjrgLSm8/r6A8g9qrCMimfAoYRcYaBYZ8vU5IJ1w=; b=EnPlg1cGpvZ3DhtKskn00H38YlRyNIr9djDUyNOs4uyKuGBnA9EfVO7D 8MnVTtdAT2rl0c9SJ2Rnw4U19uzRLsEHs6U6lo4it6lmnLCno4ICDV2BS KXh+nTcTJ7+StKe5BKWfwKkf/5zzeiOOkzItBME1BR++oW0YEectiGX7w 93elfz058udliFp0NjYw9HBz+sd+uB3vBH3/+Pwg3EhxglDSTxFecvBfX gCgQpspGguG69w4zPwFIQqFI2rJlszSAW+d49Aq7f77c6afmfOAxELWb3 JhAa2bJCm+TXJQ0YlKMybXjfNz06m9YnNXjLwn/IwZHCY3g1YTazK3mfG Q==; X-CSE-ConnectionGUID: pGJf+7jHRbK576aOsNu+gA== X-CSE-MsgGUID: 9lVAJtxkQpavbq4UwPBibA== X-IronPort-AV: E=McAfee;i="6800,10657,11913"; a="90979685" X-IronPort-AV: E=Sophos;i="6.27,118,1787036400"; d="scan'208";a="90979685" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2026 06:18:29 -0700 X-CSE-ConnectionGUID: bO/vsl57Q+6+EpjCHIMxjw== X-CSE-MsgGUID: hLB89dyqReaPpy4+siDkVw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,118,1787036400"; d="scan'208";a="272784505" Received: from ijarvine-mobl1.ger.corp.intel.com (HELO localhost) ([10.245.244.13]) by fmviesa010-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2026 06:18:24 -0700 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= To: Maciej Grochowski , Nikolas Joshua Britton , Geramy Loveless , Eric Auger , Alexey Fomenko , Bjorn Helgaas , Lorenzo Pieralisi , Rob Herring , =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/5] PCI: Fix nesting windows with remainder at the left edge Date: Wed, 23 Sep 2026 16:17:52 +0300 Message-ID: <20260923131757.7792-3-ilpo.jarvinen@linux.intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260923131757.7792-1-ilpo.jarvinen@linux.intel.com> References: <20260923131757.7792-1-ilpo.jarvinen@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable If a bridge window has its non-aligning remainder at the left edge of the window, assigning a nested bridge window of same size will fail because resource side code will only allow starting a candicate range from an aligning address. In such case, aligned address is somewhere in the middle, not at the left edge of the window. Since the entire available space is required for full-sized nested bridge window, resource side code rejects the free space. To solve this problem, PCI side code has to bypass the resource side alignment code by giving a smaller alignment and must check the aligment requirement itself. This allows resource side code to consider the entire available space as candidate to fit the required size. Wrap pcibios_align_resource() with PCI core function that performs the alignment checks and left edge recalculation if needed. As the alignment given for the resource side code is artificially small, the real alignment has to be passed through alignf_data. Fixes: 9036bd0efcb6 ("PCI: Align head space better") Signed-off-by: Ilpo J=C3=A4rvinen --- I've not seen a report about this problem (thus no log quotes) but with nested thunderbolt topologies it seems well within realms of possibility of occurring. --- drivers/pci/setup-res.c | 64 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 376f09630a4a..eacce9e2486b 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -13,6 +13,8 @@ * Resource sorting */ =20 +#include +#include #include #include #include @@ -260,6 +262,12 @@ resource_size_t pci_resource_alignment(const struct pc= i_dev *dev, return resource_alignment(res); } =20 +static resource_size_t pci_resreq_remainder(resource_size_t size, + resource_size_t align) +{ + return size - ALIGN_DOWN(size, align); +} + /* * For mem bridge windows, try to relocate tail remainder space to space * before res->start if there's enough free space there. This enables @@ -276,10 +284,17 @@ resource_size_t pci_align_resource(struct pci_dev *de= v, if (!(res->flags & IORESOURCE_MEM)) return res->start; =20 - if (IS_ALIGNED(size, align)) + remainder =3D pci_resreq_remainder(size, align); + if (!remainder) + return res->start; + + /* + * Size constraints forced an early start move in + * pci_check_and_align_resource()? + */ + if (!IS_ALIGNED(res->start, align)) return res->start; =20 - remainder =3D size - ALIGN_DOWN(size, align); /* Don't mess with size that doesn't align with window size granularity */ if (!IS_ALIGNED(remainder, pci_min_window_alignment(dev->bus, res->flags)= )) return res->start; @@ -311,15 +326,54 @@ resource_size_t __weak pcibios_align_resource(void *d= ata, return pci_align_resource(dev, res, empty_res, size, align); } =20 +struct pci_resreq_data { + struct pci_dev *dev; + resource_size_t real_align; +}; + +static resource_size_t pci_resreq_check(void *data, + const struct resource *res, + const struct resource *empty_res, + resource_size_t size, + resource_size_t min_align) +{ + struct pci_resreq_data *rr =3D data; + resource_size_t align =3D rr->real_align; + resource_size_t remainder, start; + struct resource tmp =3D *res; + + if (res->flags & IORESOURCE_MEM && !IS_ALIGNED(res->start, align)) { + resource_set_range(&tmp, ALIGN(res->start, align), size); + if (!__resource_contains_unbound(empty_res, &tmp)) { + remainder =3D pci_resreq_remainder(size, align); + resource_set_range(&tmp, tmp.start - remainder, size); + if (!__resource_contains_unbound(empty_res, &tmp)) + return tmp.start; /* caller skips range */ + } + } + + start =3D pcibios_align_resource(rr->dev, &tmp, empty_res, size, align); + WARN_ON_ONCE(!IS_ALIGNED(start, min_align)); + + return start; +} + static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, int resno, resource_size_t size, resource_size_t align) { + struct pci_resreq_data rr =3D { .dev =3D dev, .real_align =3D align }; struct resource *res =3D pci_resource_n(dev, resno); resource_size_t min; int ret; =20 min =3D (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; =20 + if ((res->flags & IORESOURCE_MEM) && pci_resreq_remainder(size, align)) { + align =3D min; + if (pci_resource_is_bridge_win(resno)) + align =3D pci_min_window_alignment(bus, res->flags); + } + /* * First, try exact prefetching match. Even if a 64-bit * prefetchable bridge window is below 4GB, we can't put a 32-bit @@ -329,7 +383,7 @@ static int __pci_assign_resource(struct pci_bus *bus, s= truct pci_dev *dev, */ ret =3D pci_bus_alloc_resource(bus, res, size, align, min, IORESOURCE_PREFETCH | IORESOURCE_MEM_64, - pcibios_align_resource, dev); + pci_resreq_check, &rr); if (ret =3D=3D 0) return 0; =20 @@ -341,7 +395,7 @@ static int __pci_assign_resource(struct pci_bus *bus, s= truct pci_dev *dev, (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) { ret =3D pci_bus_alloc_resource(bus, res, size, align, min, IORESOURCE_PREFETCH, - pcibios_align_resource, dev); + pci_resreq_check, &rr); if (ret =3D=3D 0) return 0; } @@ -354,7 +408,7 @@ static int __pci_assign_resource(struct pci_bus *bus, s= truct pci_dev *dev, */ if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) ret =3D pci_bus_alloc_resource(bus, res, size, align, min, 0, - pcibios_align_resource, dev); + pci_resreq_check, &rr); =20 return ret; } --=20 2.47.3 From nobody Thu Sep 24 12:53:02 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (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 DEAB45304CD; Wed, 23 Sep 2026 13:18:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790169530; cv=none; b=kDjHTeRUeLhG90Ax4loR8BoFcLp9HWTqwATJBeph1GR2DEO1FstoEuOKkG0C2wT8YXBxbxmc+KeJsMAXEfLy/flyJEn/OBzwXyAjmCNtr0A8Owt6XhhlumMkmljJMQHDn00JSCD7P5Ef9mr3RdCxOCv2YBAaCAtngV3M1tRP/T0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790169530; c=relaxed/simple; bh=FqBqpq3ZkuE9Ee7H2XuTzHfnQ8ujMXIt8BfcHZVcIY4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=uwg9/H8N48SRbwk4MYcAUyvQCjMqyEWGWUQ9O45OBr7471EFxrTttwvi0+IpFgMtdwU/K7eXBsxI9/tPWizIkmElGBi7qS1+1QjBzXfmabxdI9kSZ8D3q9d3syzx1zz81LGKi3HBO+Xg7ATu9PD9SBkZRVMO1cjsNyPs+EIvjvI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=lTIVogwN; arc=none smtp.client-ip=192.198.163.12 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="lTIVogwN" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1790169524; x=1821705524; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=FqBqpq3ZkuE9Ee7H2XuTzHfnQ8ujMXIt8BfcHZVcIY4=; b=lTIVogwN+H2E1hFCurlUhGGddLSbMgtuAYR7I7am+PIkQFHA7Kb6nCmA d8KGgPlAINhDSKtwMLnHFG8apgrRzqW4l6MQ496fHYPV7Qeiu5LBWg5X3 N66vJFZfmZ8JsHpAw8kruMLXvvsDyD/uH9+t4cnHRxCK9yMX/G4GBcJr7 VNA8/swBusuj5EIbfqhka0SfVKABZ2lnw4qfWWbA6O9ZNpzg62spewiql O2ftAVBKUWoK9t0+gm9MyoTMLSW/nXwQx0kL7A9Pku1LbfWjiW5E3uJ4K /uxpeQVEC3Qdeas9GpUlAKOKRZjxeX2Y9mU9JP6+9/AfAB1kOuYWu12bL A==; X-CSE-ConnectionGUID: yCRJfNzMSmqW7q0AonqwCA== X-CSE-MsgGUID: 1DImji45SMOisDU+HVxSIQ== X-IronPort-AV: E=McAfee;i="6800,10657,11913"; a="94683832" X-IronPort-AV: E=Sophos;i="6.27,118,1787036400"; d="scan'208";a="94683832" Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2026 06:18:38 -0700 X-CSE-ConnectionGUID: Ei24QBb9TjqYt9j8PyadRA== X-CSE-MsgGUID: n5Cpl1N8Q/WnK0UP/c3IZw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,118,1787036400"; d="scan'208";a="301535195" Received: from ijarvine-mobl1.ger.corp.intel.com (HELO localhost) ([10.245.244.13]) by smtpauth.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2026 06:18:34 -0700 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= To: Maciej Grochowski , Nikolas Joshua Britton , Geramy Loveless , Eric Auger , Alexey Fomenko , Bjorn Helgaas , Lorenzo Pieralisi , Rob Herring , =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Eric Auger Subject: [PATCH 3/5] PCI: Place resources to either edge of the window Date: Wed, 23 Sep 2026 16:17:53 +0300 Message-ID: <20260923131757.7792-4-ilpo.jarvinen@linux.intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260923131757.7792-1-ilpo.jarvinen@linux.intel.com> References: <20260923131757.7792-1-ilpo.jarvinen@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable PCI resource assignment phase based on a greedy algorithm. The resources are assigned in descending order of required alignment. Because the PCI BARs are power-of-two sized resources, it mostly works (bridge windows and VF BARs are composite resources that might not necessarily have power-of-two size but internally they are still composed of BARs). The resource assignment prior to the commit 9036bd0efcb6 ("PCI: Align head space better") placed resource to/towards the left edge of the window. The commit 9036bd0efcb6 ("PCI: Align head space better") altered assignment for resources whose size is not a perfect multiple of the required alignment by moving the remainder before the left edge of the window if possible. The behavior after the commit 9036bd0efcb6 ("PCI: Align head space better") may result in problems when a bridge window consists of one large alignment resource and a composite one with a smaller alignment (this is a typical setup for GPUs PF BAR and VF BARs). The resource with largest alignment is assigned first and placed such that the remainder space is left of the assigned resource, which effectively splits the remaining space into two. While the VF BAR could fit to the remaining space, it requires continuous free space that is no longer there because the large resource is now in the middle. In this log exceprt, BAR 2 is placed in the middle of the window blocking the larger VF BAR 2 from fitting anywhere: pci 0000:03:01.0: bridge window [mem 0xa9f8000000-0xbfffffffff 64bit pref]:= assigned pci 0000:04:00.0: BAR 2 [mem 0xb000000000-0xb7ffffffff 64bit pref]: assigned pci 0000:04:00.0: VF BAR 2 [mem size 0xe00000000 64bit pref]: can't assign;= no space pci 0000:04:00.0: VF BAR 2 [mem size 0xe00000000 64bit pref]: failed to ass= ign The old behavior, despite being greedy, naturally consumed space from the left edge leaving the remainder space adjacent to the other free space. When remainder space is at the left edge of the window, the greedy algorithm should instead assign to the right edge of the window. (If both ends do align, either end works equally.) While defining window edge aware resource assignment algorithm, one additional thing is useful to note. In DT setups the bridge windows/root bus resources are often very precisely sized, with right edge of the window having much smaller alignment that the left edge. They also often come with a small BAR that should be placed to the right edge to not block bridge window placed to the left edge of the window. The bridge window may be entirely optional at this point because of hotplug. The resource assignment fallback phase assigns mandatory resources first and in such a case, small BAR gets assigned first. One example where mandatory BAR 0 blocks bridge windows from fitting (both bridge windows wouldn't fit because of qemu not providing enough space for both bridge windows but one should fit like it was originally setup by the platform): pci_bus 0000:0a: root bus resource [mem 0x10a00000-0x10c00fff window] pci 0000:0a:00.0: [1b36:000c] type 01 class 0x060400 PCIe Root Port pci 0000:0a:00.0: BAR 0 [mem 0x10c00000-0x10c00fff] pci 0000:0a:00.0: PCI bridge to [bus 0b-0d] pci 0000:0a:00.0: bridge window [mem 0x10a00000-0x10bfffff] pci 0000:0a:00.0: enabling Extended Tags pci 0000:0a:00.0: bridge window [mem 0x00100000-0x000fffff 64bit pref] to [= bus 0b-0d] add_size 200000 add_align 100000 pci 0000:0a:00.0: bridge window [mem 0x00100000-0x000fffff] to [bus 0b-0d] = add_size 200000 add_align 100000 pci 0000:0a:00.0: bridge window [mem 0x10a00000-0x10bfffff]: assigned pci 0000:0a:00.0: bridge window [mem size 0x00200000 64bit pref]: can't ass= ign; no space pci 0000:0a:00.0: bridge window [mem size 0x00200000 64bit pref]: failed to= assign pci 0000:0a:00.0: BAR 0 [mem 0x10c00000-0x10c00fff]: assigned pci 0000:0a:00.0: bridge window [mem 0x10a00000-0x10bfffff]: releasing pci 0000:0a:00.0: BAR 0 [mem 0x10c00000-0x10c00fff]: releasing pci 0000:0a:00.0: BAR 0 [mem 0x10a00000-0x10a00fff]: assigned pci 0000:0a:00.0: bridge window [mem size 0x00200000]: can't assign; no spa= ce pci 0000:0a:00.0: bridge window [mem size 0x00200000]: failed to assign pci 0000:0a:00.0: bridge window [mem size 0x00200000 64bit pref]: can't ass= ign; no space pci 0000:0a:00.0: bridge window [mem size 0x00200000 64bit pref]: failed to= assign pci_bus 0000:0a: Some PCI device resources are unassigned, try booting with= pci=3Drealloc To achieve best generalization of the approach, the solution should also avoid consuming space from the window edge that can fit largest aligning resources in the future, whenever possible. Reported-by: Alexey Fomenko Tested-by: Alexey Fomenko Reported-by: Eric Auger Tested-by: Eric Auger Fixes: 9036bd0efcb6 ("PCI: Align head space better") Signed-off-by: Ilpo J=C3=A4rvinen --- Both reports are private discussions (Eric's report started as public and produced another fix but further problem was only visible in the privately send logs after that). Thus no links. Unfortunately, those debug resource prints cannot currently use pci_resource_name() because the original resource (the one within pci_dev's resource array) isn't available. I'll change that eventually so that pci_dev's resource is passed to pcibios_align_resource() but that will require changing its signature again which is a bit tedious as it requires touching all those arch/ functions. --- drivers/pci/pci.h | 4 + drivers/pci/setup-bus.c | 4 - drivers/pci/setup-res.c | 157 ++++++++++++++++++++++++++++++++++------ 3 files changed, 137 insertions(+), 28 deletions(-) diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index ba3c3fddddc2..691711e56597 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -109,6 +109,10 @@ struct pcie_tlp_log; #define PCI_EXP_AER_FLAGS (PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | \ PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE) =20 +#define PCI_RES_TYPE_MASK \ + (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH |\ + IORESOURCE_MEM_64) + extern const unsigned char pcie_link_speed[]; unsigned char pcie_get_link_speed(unsigned int speed); =20 diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index e8c94aa1d3c1..7ca0e9f4ffb6 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -31,10 +31,6 @@ #include #include "pci.h" =20 -#define PCI_RES_TYPE_MASK \ - (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH |\ - IORESOURCE_MEM_64) - unsigned int pci_flags; EXPORT_SYMBOL_GPL(pci_flags); =20 diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index eacce9e2486b..1ab5d167ab5c 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -17,6 +17,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -262,16 +265,80 @@ resource_size_t pci_resource_alignment(const struct p= ci_dev *dev, return resource_alignment(res); } =20 +static resource_size_t pci_max_natural_size(const struct resource *res, + resource_size_t *max_align) +{ + resource_size_t size =3D resource_size(res); + resource_size_t powof2, natural_start; + + *max_align =3D 1; + if (!size) + return 0; + + powof2 =3D rounddown_pow_of_two(size); + natural_start =3D ALIGN(res->start, powof2); + if (natural_start >=3D ALIGN_DOWN(res->end + 1, powof2)) { + powof2 =3D max(powof2 / 2, 1U); + natural_start =3D ALIGN(res->start, powof2); + } + + if (natural_start) { + *max_align <<=3D __ffs(natural_start); + } else { + /* + * Zero address has infinite alignment, return the largest + * representable number even if it's not a power of two. + */ + *max_align =3D RESOURCE_SIZE_MAX; + } + + return powof2; +} + static resource_size_t pci_resreq_remainder(resource_size_t size, resource_size_t align) { return size - ALIGN_DOWN(size, align); } =20 -/* - * For mem bridge windows, try to relocate tail remainder space to space - * before res->start if there's enough free space there. This enables - * tighter packing for resources. +/** + * pci_align_resource - Places resource into empty space range + * @dev: PCI device resource belongs to + * @res: Candidate range calculated by caller (not among @dev's resources!) + * @empty_res: Full free space range + * @size: Required size for the resource + * @align: Required alignment (see below for details) + * + * Places resource inside @empty_res honoring @size and @align. Following + * special logic only applies to mem resources currently. For composite + * resources not divisable by @align, @align does not apply to non-aligning + * remainder part giving some leeway for its placement. + * + * There are 4 candidate positions: + * + * W0WWW0WWW0WWW + * 1. AAAAr + * 2. rAAAA + * 3. AAAAr + * 4. rAAAA + * + * W =3D bridge window + * 0 =3D bridge window offset matching align + * A =3D aligning part of size (size rounded down by align) + * r =3D non-aligning remainder + * + * Cases 1 & 3 and 2 & 4 may degenerate to the same candidate. + * + * Select resource placement based on the remaining free space. Pick the + * candidate with which the remaining free space has (in decreasing order = of + * priority): + * + * 1. the largest naturally aligning power-of-two-sized address range wi= thin, + * 2. the largest continous free space, + * 3. the largest alignment of the start address for the naturally align= ing + * free space range (from check 1). + * + * Cases 1 & 2 check only right edge free space and 3 & 4 the left edge. */ resource_size_t pci_align_resource(struct pci_dev *dev, const struct resource *res, @@ -279,35 +346,77 @@ resource_size_t pci_align_resource(struct pci_dev *de= v, resource_size_t size, resource_size_t align) { - resource_size_t remainder, start_addr; + unsigned long type =3D res->flags & PCI_RES_TYPE_MASK; + resource_size_t best_natural_size =3D 0, best_size =3D 0, best_maxalign = =3D 0; + resource_size_t aligning, remainder; + struct resource candidate[4]; + unsigned int i; + int best =3D -1; =20 if (!(res->flags & IORESOURCE_MEM)) return res->start; =20 remainder =3D pci_resreq_remainder(size, align); - if (!remainder) - return res->start; + aligning =3D size - remainder; + + candidate[0] =3D DEFINE_RES(ALIGN(empty_res->start, align), size, type); + candidate[1] =3D DEFINE_RES(ALIGN(empty_res->start, align) - remainder, + size, type); + candidate[2] =3D DEFINE_RES(ALIGN_DOWN(empty_res->end + 1 - remainder, al= ign) - + aligning, size, type); + candidate[3] =3D DEFINE_RES(ALIGN_DOWN(empty_res->end + 1, align) - size, + size, type); + + for (i =3D 0; i < ARRAY_SIZE(candidate); i++) { + struct resource remaining; + resource_size_t natural_size, size, maxalign; + + if ((candidate[i].start > candidate[i].end) || + !__resource_contains_unbound(empty_res, &candidate[i])) { + pci_dbg(dev, "%pR: candidate %u %pR not within free space %pR\n", + res, i, &candidate[i], empty_res); + continue; + } =20 - /* - * Size constraints forced an early start move in - * pci_check_and_align_resource()? - */ - if (!IS_ALIGNED(res->start, align)) - return res->start; + remaining.flags =3D type; + if (i <=3D 1) { + remaining.start =3D candidate[i].end + 1; + remaining.end =3D empty_res->end; + } else { + remaining.start =3D empty_res->start; + remaining.end =3D candidate[i].start - 1; + } =20 - /* Don't mess with size that doesn't align with window size granularity */ - if (!IS_ALIGNED(remainder, pci_min_window_alignment(dev->bus, res->flags)= )) - return res->start; - /* Try to place remainder that doesn't fill align before */ - if (res->start < remainder) - return res->start; - start_addr =3D res->start - remainder; - if (empty_res->start > start_addr) + natural_size =3D pci_max_natural_size(&remaining, &maxalign); + size =3D resource_size(&remaining); + pci_dbg(dev, "%pR: candidate %u %pR, free space naturalsize=3D%llx size= =3D%llx maxalign=3D%llx\n", + res, i, &candidate[i], + (unsigned long long)natural_size, + (unsigned long long)size, + (unsigned long long)maxalign); + if ((best < 0) || + (natural_size > best_natural_size) || + (natural_size =3D=3D best_natural_size && size > best_size) || + (natural_size =3D=3D best_natural_size && size =3D=3D best_size && + maxalign > best_maxalign)) { + best =3D i; + best_natural_size =3D natural_size; + best_size =3D size; + best_maxalign =3D maxalign; + } + } + + /* None fits? Return some address and let the caller deal with it. */ + if (best =3D=3D -1) return res->start; =20 - pci_dbg(dev, "%pR: moving candidate start address below align to %llx\n", - res, (unsigned long long)start_addr); - return start_addr; + pci_dbg(dev, "%pR: picked candidate %u (free space %pR), size: %llx + %ll= x, align: %llx\n", + &candidate[best], best, empty_res, + (unsigned long long)aligning, + (unsigned long long)remainder, + (unsigned long long)align); + + return candidate[best].start; } =20 /* --=20 2.47.3 From nobody Thu Sep 24 12:53:02 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (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 2106C5304C6; Wed, 23 Sep 2026 13:18:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790169539; cv=none; b=tkqu9DOvROVUkCScHvcuV4gsX81z4QBrl3YQwIBVTzegMMzvuIb07DEDyA4jZSIry2prWH6jJLzAcNZE+wjkhoyIIc1hMndt5SptN+K5BMRocw2YfN9mZPDvejE0qRlHYa4b+VdON5vmKlDNKLG1ximraR6QnfmS5AOd8sLlcD0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790169539; c=relaxed/simple; bh=wWH4fKsWOyheCbNebbp+8OlkINLgIfqoiOwkTCoUDzk=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Hg2T0MwZW/skWUWJsJF527jPqdVwVFtPSdGcTvEYOceljQ1u0yYmLxtCIfJNz9Zx9gsTImSSKm0f4yUxg7K8LbPiYYhtBFKbrDf9+HIrAgvkSx/HZfEGaH/3z8+grCtvA0l3DVH5yR7qz7l7tjW9YYEyfZz0HT2OnWBf2a4kaM8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=drlErN7P; arc=none smtp.client-ip=192.198.163.12 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="drlErN7P" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1790169533; x=1821705533; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=wWH4fKsWOyheCbNebbp+8OlkINLgIfqoiOwkTCoUDzk=; b=drlErN7PnqYwFdp6GVqE6RjnTmiqxSCrdWG+fTFPTDmkzEndWcndn8qr xMbX+KbMgG1/6Trc5Bo3vN+SA2ESQ3xCcN77n4i5mFr3axGolwg+iCpfV hMxtHtnCPVSUHjzMNgfBT3Jm02s9o0bgBK/t2ARmsPw+SwR7VbmWvh0dp 0GT6TY9HG4PJkLmAQ8D9HP4IdZ7AZRm3hFZiG6ouzkzx/eTdPWMETcNgJ 2wjAvM7TwAU+bLir0UepqTrBwCorJ6AVQxFd9gfutbW6en8dhZeojCQQR uEe+UlPVPgJzxrmJsbvj8HS0rE+Oo7m0QOuO36G82G8JA/2FfXvqJbCFG A==; X-CSE-ConnectionGUID: DR6XR7OqRMauL2cLN5aVug== X-CSE-MsgGUID: e4SP+jSZRoy/0fwIUcxbMA== X-IronPort-AV: E=McAfee;i="6800,10657,11913"; a="94683858" X-IronPort-AV: E=Sophos;i="6.27,118,1787036400"; d="scan'208";a="94683858" Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2026 06:18:49 -0700 X-CSE-ConnectionGUID: h3cBXUa/SOaGK6vZZ/aHxQ== X-CSE-MsgGUID: bW+g54EqSaCvFWzquOR33Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,118,1787036400"; d="scan'208";a="301535283" Received: from ijarvine-mobl1.ger.corp.intel.com (HELO localhost) ([10.245.244.13]) by smtpauth.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2026 06:18:43 -0700 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= To: Maciej Grochowski , Nikolas Joshua Britton , Geramy Loveless , Eric Auger , Alexey Fomenko , Bjorn Helgaas , Lorenzo Pieralisi , Rob Herring , =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 4/5] PCI: Fix composite resource sizing Date: Wed, 23 Sep 2026 16:17:54 +0300 Message-ID: <20260923131757.7792-5-ilpo.jarvinen@linux.intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260923131757.7792-1-ilpo.jarvinen@linux.intel.com> References: <20260923131757.7792-1-ilpo.jarvinen@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The bridge window sizing algorithm aims to pack child resources back to back. With multiple composite child resources whose sizes do not align to the calculated minimal alignment for the bridge window, back-to-back placement may not be possible. The non-aligning remainder placement is limited because it must be adjacent to the rest of the composite resource. Effectively, two remainder parts may be placed into the same align sized block, but sum of their size might not match align. In such case, a gap is required to meet the alignment requirement of both resources. Add bridge window gap size calculator. Basic rules: 1) Gaps are only necessary if there is more than one non-aligning composite resource within a single bridge window. 2) If there are only two remainder parts that amount to less than align together, the required gap is the difference of align and the sum of remainder sizes. 3) On other cases, round each remainder part to align to get the gap size. Sometimes, smaller size may be possible but due to how sizing and assignment are made in different phases, it is not always possible to predict where each resource is assigned. Thus, the sizing has to play safe. The gap is calculated based on the minimal alignment for the bridge window, which may be different for the case with only required resources and the case with optional resources. Fixes: 9036bd0efcb6 ("PCI: Align head space better") Reported-by: Bjorn Helgaas Tested-by: Bjorn Helgaas Reported-by: Nikolas Joshua Britton Link: https://lore.kernel.org/linux-pci/20260903063124.9316-1-nbritton@exab= it.io/ Reported-by: Maciej Grochowski Signed-off-by: Ilpo J=C3=A4rvinen --- drivers/pci/setup-bus.c | 79 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 3 deletions(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 7ca0e9f4ffb6..9d828a59bd00 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1164,6 +1164,76 @@ static inline resource_size_t calculate_mem_align(re= source_size_t *aligns, return min_align; } =20 +/* + * Bridge window gap size calculator. + * + * Calculates gap (empty space) necessary because of non-aligning composite + * resources (VF BARs, bridge windows). + * + * Rules: + * + * 1) Gaps are only necessary if there is more than one non-aligning + * composite resource within a single bridge window. + * + * 2) If there are only two remainder parts that amount to less than win_a= lign + * together, the required gap is the difference of win_align and the su= m of + * remainder sizes. + * + * 3) On other cases, round each remainder part to win_align to get the gap + * size. Sometimes, tighter packing might be possible but due to how + * sizing and assignment are made in different phases, it is not always + * possible to predict where each resource is assigned. Thus, the sizing + * has to play safe even if it may overestimate in some cases. + */ +static resource_size_t calculate_win_gap_size(struct pci_bus *bus, + struct resource *b_res, + resource_size_t win_align, + bool optional) +{ + resource_size_t safe_gap =3D 0, remainders =3D 0; + unsigned int nonaligning =3D 0; + struct pci_dev *dev; + + list_for_each_entry(dev, &bus->devices, bus_list) { + struct resource *r; + int i; + + pci_dev_for_each_resource(dev, r, i) { + resource_size_t r_size, remainder, aligning; + + if (!pdev_resources_assignable(dev) || + !pdev_resource_should_fit(dev, r)) + continue; + if (b_res !=3D pbus_select_window(bus, r)) + continue; + + if (!optional && pci_resource_is_optional(dev, i)) + continue; + + r_size =3D resource_size(r); + if (r_size <=3D win_align) + continue; + + aligning =3D ALIGN_DOWN(r_size, win_align); + remainder =3D r_size - aligning; + if (!remainder) + continue; + + nonaligning++; + remainders +=3D remainder; + safe_gap +=3D win_align - remainder; + } + } + + if (nonaligning =3D=3D 2 && (remainders <=3D win_align)) + return win_align - remainders; + + if (nonaligning >=3D 2) + return safe_gap; + + return 0; +} + /* * Calculate bridge window head alignment that leaves no gaps in between * resources. @@ -1281,6 +1351,7 @@ static void pbus_size_mem(struct pci_bus *bus, struct= resource *b_res, int order, max_order; resource_size_t children_add_size =3D 0; resource_size_t add_align =3D 0; + resource_size_t gap_size; =20 if (!b_res) return; @@ -1345,7 +1416,8 @@ static void pbus_size_mem(struct pci_bus *bus, struct= resource *b_res, win_align =3D pci_min_window_alignment(bus, b_res->flags); min_align =3D calculate_head_align(aligns, max_order); min_align =3D max(min_align, win_align); - size0 =3D calculate_memsize(size, realloc_head ? 0 : add_size, + gap_size =3D calculate_win_gap_size(bus, b_res, min_align, false); + size0 =3D calculate_memsize(size + gap_size, realloc_head ? 0 : add_size, 0, win_align); =20 if (size0) { @@ -1355,8 +1427,9 @@ static void pbus_size_mem(struct pci_bus *bus, struct= resource *b_res, =20 if (realloc_head && (add_size > 0 || children_add_size > 0)) { add_align =3D max(min_align, add_align); - size1 =3D calculate_memsize(size, add_size, children_add_size, - win_align); + gap_size =3D calculate_win_gap_size(bus, b_res, add_align, true); + size1 =3D calculate_memsize(size + gap_size, add_size, + children_add_size, win_align); } =20 if (!size0 && !size1) { --=20 2.47.3 From nobody Thu Sep 24 12:53:02 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.14]) (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 C0C7732B133; Wed, 23 Sep 2026 13:19:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.14 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790169548; cv=none; b=kJZbzdatOCs4+SOfNyWa4V9NZ9JD7y18NjlfM6HnNFjPadtHFUtoMc8WoCZoHbiwvLiIMk7eC/jDgUEKqc5d7cXxZnC7TbFdK8qMe3OqAwncd9qxNNA7U27/VUHuJKgkUa3wLZepBZv/NU6QStreTyd5+ONoV7rLMeartmBvBEc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790169548; c=relaxed/simple; bh=shV/jHwiOOO+2nu26tUkKGDmxnj6c238IyYyiu83uR0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=NmLzBb6fHPyi/Bcj2x1NA4la1othJQybyiIVjvxskk7dM3eHwBilKD1ls+HxXTZbgqwNNSOsRVm3LNZASGHZYqQTleJiU91b5CjmbSZYtoZoeAgxMQQ+5d0MiJVew96MTkorLzHYIFVCM0/mcjhTKp7HlteVfdRXJT6IsnWZjko= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=lpuKPlhl; arc=none smtp.client-ip=192.198.163.14 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="lpuKPlhl" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1790169544; x=1821705544; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=shV/jHwiOOO+2nu26tUkKGDmxnj6c238IyYyiu83uR0=; b=lpuKPlhl90tQSgplZBFn8FoFK2qOMgsow9yX61jjFfoqlOOVnhCujwrc /DiRUn4te6iLFa8JWI9liVcNyd6EoXBngF//e081tYP9XSKVUADb9t8Pn ZzQUsRcDqbv1ZZ+9fg2Vbi6YvXlbLdbv7o95TJeDEZn/ARhF2ynonqPIy WTz2WnmtSiCjHO9xraYJ4xiu9pZqHAJ54IBp3CzcxsppAjWM8wE7hfaKb M9DNxlz3TVIgfBRdjgqluEkSTA6GpAzeMPGkkO6YCF28TRiFMdrT1Blzf xERrxR0M7OFCw0GNo4i2VTQf2lPxq3oacPUb8z9a7vbuOh+E4qAIv52zA Q==; X-CSE-ConnectionGUID: DmYBjP/iR/Oba//jQ2vWHg== X-CSE-MsgGUID: HlzectgsTXaSLaKlvu7Smg== X-IronPort-AV: E=McAfee;i="6800,10657,11913"; a="90886641" X-IronPort-AV: E=Sophos;i="6.27,118,1787036400"; d="scan'208";a="90886641" Received: from fmviesa007.fm.intel.com ([10.60.135.147]) by fmvoesa108.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2026 06:18:57 -0700 X-CSE-ConnectionGUID: m6WdkbLYTZGqzoTJLaYxXQ== X-CSE-MsgGUID: s7hw7WjkQQyUFIaw1/+0pw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,118,1787036400"; d="scan'208";a="273080862" Received: from ijarvine-mobl1.ger.corp.intel.com (HELO localhost) ([10.245.244.13]) by fmviesa007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2026 06:18:51 -0700 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= To: Maciej Grochowski , Nikolas Joshua Britton , Geramy Loveless , Eric Auger , Alexey Fomenko , Bjorn Helgaas , Lorenzo Pieralisi , Rob Herring , =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org Cc: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Subject: [PATCH 5/5] PCI/quirks: Avoid certain BAR 0 address with igb Date: Wed, 23 Sep 2026 16:17:55 +0300 Message-ID: <20260923131757.7792-6-ilpo.jarvinen@linux.intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260923131757.7792-1-ilpo.jarvinen@linux.intel.com> References: <20260923131757.7792-1-ilpo.jarvinen@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable While testing the resource placement changes, my tests hit a case where igb fails to probe when BAR 0 is placed at 0x9c000000: 90000000-9cffffff : PCI Bus 0000:a0 - 90000000-902fffff : PCI Bus 0000:a1 - 90000000-900fffff : 0000:a1:00.0 - 90000000-900fffff : igb - 90100000-901fffff : 0000:a1:00.0 - 90200000-90203fff : 0000:a1:00.0 - 90200000-90203fff : igb + 9be00000-9c0fffff : PCI Bus 0000:a1 + 9be00000-9befffff : 0000:a1:00.0 + 9bf00000-9bf03fff : 0000:a1:00.0 + 9c000000-9c0fffff : 0000:a1:00.0 9c100000-9c17ffff : amd_iommu 9c180000-9c1803ff : IOAPIC 8 - Region 0: Memory at 90000000 (32-bit, non-prefetchable) [size=3D1= M] - Region 3: Memory at 90200000 (32-bit, non-prefetchable) [size=3D1= 6K] - Expansion ROM at 90100000 [disabled] [size=3D1M] + Region 0: Memory at 9c000000 (32-bit, non-prefetchable) [size=3D1= M] + Region 3: Memory at 9bf00000 (32-bit, non-prefetchable) [size=3D1= 6K] + Expansion ROM at 9be00000 [disabled] [size=3D1M] igb 0000:a1:00.0 0000:a1:00.0 (uninitialized): PCIe link lost ------------[ cut here ]------------ igb: Failed to read reg 0x18! WARNING: drivers/net/ethernet/intel/igb/igb_main.c:724 at igb_rd32.cold+0x3= c/0x4f [igb], CPU#32: kworker/32:1/706 ... igb_get_invariants_82575+0xff/0xf00 [igb] igb_probe+0x3c8/0x1190 [igb] local_pci_probe+0x3b/0x80 Apparently, the igb driver bails out, after its initial sanity check detects an unexpected ~0 read. Hacking around the sanity check just results in more failures down the road so the sanity check itself is not the cause for the failure. The resource placement looks valid so the actual placement patches seem to work normally. All other possible 1M address I could test (with a hack patch) did work. Add quirk to reshuffle igb resources, use BAR 3 to block the problematic address. Signed-off-by: Ilpo J=C3=A4rvinen --- I know this is ugly and I don't like it either but do not know better way to avoid the regression. I've tried with iommu=3Doff and that did not resolve the issue. I also managed to prove igb works with the same resource layout in another system. So identifying the case should probably be tightened by matching with more devices than the one used by igb. This is open to discussion. --- drivers/pci/quirks.c | 56 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index de9bbccda21f..e6f3e2ab1fd4 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -6288,6 +6288,62 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1536,= rom_bar_overlap_defect); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1537, rom_bar_overlap_defec= t); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1538, rom_bar_overlap_defec= t); =20 +/* + * The igb driver probe (due to reads returning ~0 unexpected) when BAR 0 + * appears at 0x9c000000. The cause is unknown. + * + * Use BAR 3 to block 0x9c000000 address. + */ +static void bar0_address_breakage(struct pci_dev *dev) +{ + struct resource *bar0 =3D pci_resource_n(dev, 0); + struct resource *bar3 =3D pci_resource_n(dev, 3); + resource_size_t broken_addr =3D 0x9c000000; + struct resource *res; + int i, ret; + + if (bar0->start !=3D broken_addr) + return; + + /* + * HW BAR sizes seems to vary. Exclude non-1M BAR 0 case and + * sanity check BAR 0 & 3 before attempting this quirk. + */ + if (resource_type(bar0) !=3D IORESOURCE_MEM || + resource_size(bar0) !=3D SZ_1M || + resource_type(bar3) !=3D IORESOURCE_MEM) + return; + + pci_info(dev, "%pR: relocating BAR\n", bar0); + + pci_dev_for_each_resource(dev, res, i) { + if (!resource_assigned(res) || + resource_type(res) !=3D IORESOURCE_MEM) + continue; + + pci_release_resource(dev, i); + } + + resource_set_range(bar3, broken_addr, resource_size(bar3)); + bar3->flags &=3D ~IORESOURCE_UNSET; + pci_claim_resource(dev, 3); + if (!resource_assigned(bar3)) { + bar3->flags |=3D IORESOURCE_UNSET; + pci_warn(dev, "resource relocation failed\n"); + } + + pci_dev_for_each_resource(dev, res, i) { + if (resource_assigned(res) || + resource_type(res) !=3D IORESOURCE_MEM) + continue; + + ret =3D pci_assign_resource(dev, i); + if (ret) + pci_warn(dev, "resource relocation failed\n"); + } +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1533, bar0_address_breakage= ); + #ifdef CONFIG_PCIEASPM /* * Several Intel DG2 graphics devices advertise that they can only tolerate --=20 2.47.3