[{"id":3676635,"web_url":"http://patchwork.ozlabs.org/comment/3676635/","msgid":"<f8c3aa99-ab27-e316-8449-27b0049893a9@linux.intel.com>","list_archive_url":null,"date":"2026-04-13T10:22:54","subject":"Re: [PATCH] PCI: release empty sibling bridge resources during window\n resize","submitter":{"id":83553,"url":"http://patchwork.ozlabs.org/api/people/83553/","name":"Ilpo Järvinen","email":"ilpo.jarvinen@linux.intel.com"},"content":"On Fri, 10 Apr 2026, Geramy Loveless wrote:\n\nPlease try to remember to increment the version counter whenever \nresubmitting the patch (if there's even a slightest change to the patch).\nThis should have been v3 I think.\n\n> pbus_reassign_bridge_resources() refuses to release bridge windows that\n> have child resources.  On multi-port PCIe switches (e.g. Thunderbolt\n> docks), empty sibling downstream ports hold small reservations that\n> prevent the parent window from being freed and re-sized for rebar.\n> \n> Add a bottom-up recursive release that saves and frees each empty bridge\n> window individually, so the parent window can then be released and grown.\n\nAs this starts to get close being ready, put the parts of the log here \nwhich show the pinning problem so it's easier to find this with search \nengine. Only include relevant parts (things like timestamps and totally \nunrelated lines can be cut out).\n\nIf it seems reasonable in length, consider adding also the post change \nlog.\n \n> Suggested-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>\n> Signed-off-by: Geramy Loveless <gloveless@jqluv.com>\n> ---\n\nPlease start adding version history of the patch here (what was changed \ncompared with the previous version).\n\n>  drivers/pci/setup-bus.c | 63 +++++++++++++++++++++++++++++++++++++++--\n>  1 file changed, 61 insertions(+), 2 deletions(-)\n> \n> diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c\n> index 4cf120ebe5ad..0c1fb654c9cc 100644\n> --- a/drivers/pci/setup-bus.c\n> +++ b/drivers/pci/setup-bus.c\n> @@ -2292,6 +2292,60 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)\n>  }\n>  EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);\n>  \n> +/*\n> + * pci_bus_release_empty_bridge_resources - Bottom-up release of bridge\n> + * window resources in empty subtrees.\n\nThis is summary, so I'd change \"bridge window resources\" to just \"bridge \nwindows\"\n\n> + * @bus: PCI bus whose child bridges to process\n> + * @b_win: Ancestor bridge window; only children of this resource are released\n> + * @saved: List to save released resources for rollback\n> + *\n> + * Recurses depth-first into subordinate buses, then releases bridge windows\n\n... that are (grand)parented by @b_win\n\n> + * on the way back up.  Each resource is individually saved before release so\n\nindividually saved -> stored into @saved\n\nNit, one whitespace is enough.\n\n> + * the entire operation can be rolled back.\n> + */\n> +static void pci_bus_release_empty_bridge_resources(struct pci_bus *bus,\n> +\t\t\t\t\t\t   struct resource *b_win,\n> +\t\t\t\t\t\t   struct list_head *saved)\n> +{\n> +\tstruct pci_dev *dev;\n> +\n> +\tlist_for_each_entry(dev, &bus->devices, bus_list) {\n> +\t\tstruct resource *r;\n> +\t\tunsigned int i;\n> +\n> +\t\tif (!dev->subordinate)\n> +\t\t\tcontinue;\n> +\n> +\t\t/* Recurse first — release deepest resources before parents */\n> +\t\tpci_bus_release_empty_bridge_resources(dev->subordinate,\n> +\t\t\t\t\t\t      b_win, saved);\n> +\n> +\t\tpci_dev_for_each_resource(dev, r, i) {\n> +\t\t\tif (!pci_resource_is_bridge_win(i))\n> +\t\t\t\tcontinue;\n> +\n> +\t\t\tif (!resource_assigned(r))\n> +\t\t\t\tcontinue;\n> +\n> +\t\t\tif (r->parent != b_win)\n\nThis has to also walk upstream as in nested topologies, b_win is not \nnecessarily the immediate parent.\n\nWhen converting to the suggested iteration form (see below), r itself can \nbe b_win too but it's relatively easy to handle once you convert this into \na while loop.\n\n> +\t\t\t\tcontinue;\n> +\n\n\n> +\t\t\tif (r->child) {\n> +\t\t\t\tconst char *res_name = pci_resource_name(dev, i);\n> +\n> +\t\t\t\tpci_info(dev, \"%s %pR: not released, children still present\\n\",\n> +\t\t\t\t\t res_name, r);\n> +\t\t\t\tcontinue;\n> +\t\t\t}\n> +\n> +\t\t\tif (pci_dev_res_add_to_list(saved, dev, r, 0, 0))\n> +\t\t\t\tcontinue;\n> +\n> +\t\t\tpci_release_resource(dev, i);\n\nThese three things are effectively what the caller does right after \ncalling this function so the current way to iterate duplicates the \nrelease to two places. This is what I meant when I said you may want to \nrestructure things a bit.\n\nI think this structure would allow you to remove the caller side release \nentirely:\n\n\tlist_for_each_entry(dev, &bus->devices, bus_list) {\n\t\t... recursion ...\n\t}\n\n\tpci_bus_for_each_resource(bus, ...) {\n\t\t...checks and release here...\n\t}\n\nI suspect you don't even need to check pci_resource_is_bridge_win() when \niterating over them as bus resources.\n\n> +\t\t}\n> +\t}\n> +}\n> +\n>  /*\n>   * Walk to the root bus, find the bridge window relevant for @res and\n>   * release it when possible. If the bridge window contains assigned\n> @@ -2316,7 +2370,12 @@ static int pbus_reassign_bridge_resources(struct pci_bus *bus, struct resource *\n>  \n>  \t\ti = pci_resource_num(bridge, res);\n>  \n> -\t\t/* Ignore BARs which are still in use */\n> +\t\t/* Release empty sibling bridge windows bottom-up */\n> +\t\tif (bridge->subordinate)\n> +\t\t\tpci_bus_release_empty_bridge_resources(\n> +\t\t\t\tbridge->subordinate, res, saved);\n\nIf you call is pbus_... it is a bit shorter and you can fit the first arg \non the first line.\n\nUse braces with multi-line constructs.\n\n> +\n> +\t\t/* Ignore bridge windows which are still in use */\n>  \t\tif (!res->child) {\n>  \t\t\tret = pci_dev_res_add_to_list(saved, bridge, res, 0, 0);\n>  \t\t\tif (ret)\n> @@ -2327,7 +2386,7 @@ static int pbus_reassign_bridge_resources(struct pci_bus *bus, struct resource *\n>  \t\t\tconst char *res_name = pci_resource_name(bridge, i);\n>  \n>  \t\t\tpci_warn(bridge,\n> -\t\t\t\t \"%s %pR: was not released (still contains assigned resources)\\n\",\n> +\t\t\t\t \"%s %pR: not released, active children present\\n\",\n>  \t\t\t\t res_name, res);\n>  \t\t}\n>  \n>","headers":{"Return-Path":"\n <linux-pci+bounces-52422-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-pci@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256\n header.s=Intel header.b=mRrFMRXW;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c04:e001:36c::12fc:5321; helo=tor.lore.kernel.org;\n envelope-from=linux-pci+bounces-52422-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com\n header.b=\"mRrFMRXW\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=192.198.163.14","smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=linux.intel.com","smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=linux.intel.com"],"Received":["from tor.lore.kernel.org (tor.lore.kernel.org\n [IPv6:2600:3c04:e001:36c::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fvNpj1DYYz1y2d\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 13 Apr 2026 20:25:49 +1000 (AEST)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby tor.lore.kernel.org (Postfix) with ESMTP id 8DC2C3023A45\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 13 Apr 2026 10:23:07 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 160503B19A3;\n\tMon, 13 Apr 2026 10:23:05 +0000 (UTC)","from mgamail.intel.com (mgamail.intel.com [192.198.163.14])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 5108E3AE1A8\n\tfor <linux-pci@vger.kernel.org>; Mon, 13 Apr 2026 10:23:02 +0000 (UTC)","from fmviesa003.fm.intel.com ([10.60.135.143])\n  by fmvoesa108.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 13 Apr 2026 03:23:02 -0700","from ijarvine-mobl1.ger.corp.intel.com (HELO localhost)\n ([10.245.245.63])\n  by fmviesa003-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 13 Apr 2026 03:22:58 -0700"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1776075785; cv=none;\n b=sUmMnekryO3w8soj6nGgfyo6+1thbnL+rkcU3I4/FqP6x0ymo7bAM6ypOI8btB5b66sSQGuah9nG6cK+XbZxiKgnM8VaZHfJRx9NcAqJoXOFFpJ9EB37vThY2uPhkJ1mVmSB8Fykp/faWRzuu9BF1uTPdwBOFO/f6fbNwtuxN0M=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1776075785; c=relaxed/simple;\n\tbh=ogwRpu0Eo//vWBMhvJ2k0elopZSZSmZeRbxPPtzbJHM=;\n\th=From:Date:To:cc:Subject:In-Reply-To:Message-ID:References:\n\t MIME-Version:Content-Type;\n b=THpKuJueL92zKX1A0uTeZTGQ+f1GEbYmsXTcvBv7WAjC5sieUm4E+bFu+NUX8HWQHH3eUpZw1InHVvYY/RAumS82pnnr3vOw81pVU7blXW6QC/IlSjHulWK3q0Kl5oTH1r2N28VZsXlavCYfCTtr+tviFeiUulS5cR7eQCunfdU=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=linux.intel.com;\n spf=pass smtp.mailfrom=linux.intel.com;\n dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com\n header.b=mRrFMRXW; arc=none smtp.client-ip=192.198.163.14","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple;\n  d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n  t=1776075783; x=1807611783;\n  h=from:date:to:cc:subject:in-reply-to:message-id:\n   references:mime-version:content-id;\n  bh=ogwRpu0Eo//vWBMhvJ2k0elopZSZSmZeRbxPPtzbJHM=;\n  b=mRrFMRXW7IdN73HUr4fg3NnFWRMOhWAbiQgpZNLoFwHCkdEcG/gq79DN\n   yZOdZv/0NCnyp35r8mT/PMXDH9C1li1HuXKwGUbZqec/5toMa3FeNkN22\n   1ec8MhIutTEd39FrVR62bRWR6FgMecAAY4Vq9XIUKhgO99topRSoHDrBe\n   Wy5Lno3NEJsCCop+J8khRIlbQtjz5vFlqvJT10mzaWp7w7oHtfdbMKM75\n   I0PRLOC7wgjZzjUmg6qKEw7ihGZeLANMPrEsNhLDDY3+0JGJk26CGuJF4\n   sV5CSj4G0IQHsqf63iB5ZCDS+g7yAqTIdLbDHYHFCyjGTuzD79jziPsxY\n   g==;","X-CSE-ConnectionGUID":["krUDlqiXSIeHkJ3y8ZifxQ==","WCZqVdyoRvykj8MqurICXA=="],"X-CSE-MsgGUID":["CPjVdaFiSlKMgff3HPqdqw==","UfQuY95oSneQXCFfpFmdBA=="],"X-IronPort-AV":["E=McAfee;i=\"6800,10657,11757\"; a=\"77076876\"","E=Sophos;i=\"6.23,177,1770624000\";\n   d=\"scan'208\";a=\"77076876\""],"X-ExtLoop1":"1","From":"=?utf-8?q?Ilpo_J=C3=A4rvinen?= <ilpo.jarvinen@linux.intel.com>","Date":"Mon, 13 Apr 2026 13:22:54 +0300 (EEST)","To":"Geramy Loveless <gloveless@jqluv.com>","cc":"linux-pci@vger.kernel.org, Cristian Cocos <cristi@ieee.org>,\n\t=?iso-8859-15?q?Christian_K=F6nig?= <christian.koenig@amd.com>","Subject":"Re: [PATCH] PCI: release empty sibling bridge resources during window\n resize","In-Reply-To":"<20260410191037.782121-1-gloveless@jqluv.com>","Message-ID":"<f8c3aa99-ab27-e316-8449-27b0049893a9@linux.intel.com>","References":"<ec0d287c884cbdd5131e1b09147b9b3cd56faf1d.camel@ieee.org>\n <20260410191037.782121-1-gloveless@jqluv.com>","Precedence":"bulk","X-Mailing-List":"linux-pci@vger.kernel.org","List-Id":"<linux-pci.vger.kernel.org>","List-Subscribe":"<mailto:linux-pci+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:linux-pci+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","Content-Type":"multipart/mixed; BOUNDARY=\"8323328-991176471-1776073353=:962\"","Content-ID":"<54d984ff-7230-2655-46aa-9f6d5ba305ee@linux.intel.com>"}}]