{"id":2229937,"url":"http://patchwork.ozlabs.org/api/1.1/patches/2229937/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/patch/20260428225532.3108047-1-gloveless@jqluv.com/","project":{"id":28,"url":"http://patchwork.ozlabs.org/api/1.1/projects/28/?format=json","name":"Linux PCI development","link_name":"linux-pci","list_id":"linux-pci.vger.kernel.org","list_email":"linux-pci@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null},"msgid":"<20260428225532.3108047-1-gloveless@jqluv.com>","date":"2026-04-28T22:55:32","name":"[v3,RESEND] PCI: release empty sibling bridge windows during window resize","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"dbc6ad169052d29076d20543a8ecd1325f855237","submitter":{"id":93094,"url":"http://patchwork.ozlabs.org/api/1.1/people/93094/?format=json","name":"Geramy Loveless","email":"gloveless@jqluv.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-pci/patch/20260428225532.3108047-1-gloveless@jqluv.com/mbox/","series":[{"id":501947,"url":"http://patchwork.ozlabs.org/api/1.1/series/501947/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/list/?series=501947","date":"2026-04-28T22:55:32","name":"[v3,RESEND] PCI: release empty sibling bridge windows during window resize","version":3,"mbox":"http://patchwork.ozlabs.org/series/501947/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2229937/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2229937/checks/","tags":{},"headers":{"Return-Path":"\n <linux-pci+bounces-53361-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=jqluv-com.20251104.gappssmtp.com\n header.i=@jqluv-com.20251104.gappssmtp.com header.a=rsa-sha256\n header.s=20251104 header.b=oNF26PNT;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c0a:e001:db::12fc:5321; helo=sea.lore.kernel.org;\n envelope-from=linux-pci+bounces-53361-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=jqluv-com.20251104.gappssmtp.com\n header.i=@jqluv-com.20251104.gappssmtp.com header.b=\"oNF26PNT\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=209.85.214.172","smtp.subspace.kernel.org;\n dmarc=none (p=none dis=none) header.from=jqluv.com","smtp.subspace.kernel.org;\n spf=none smtp.mailfrom=jqluv.com"],"Received":["from sea.lore.kernel.org (sea.lore.kernel.org\n [IPv6:2600:3c0a:e001:db::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 4g4wm13Wwlz1yHv\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 29 Apr 2026 08:56:33 +1000 (AEST)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id 31FA7301BF7D\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 28 Apr 2026 22:55:44 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 72F832BFC85;\n\tTue, 28 Apr 2026 22:55:43 +0000 (UTC)","from mail-pl1-f172.google.com (mail-pl1-f172.google.com\n [209.85.214.172])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id DE79E344DAB\n\tfor <linux-pci@vger.kernel.org>; Tue, 28 Apr 2026 22:55:41 +0000 (UTC)","by mail-pl1-f172.google.com with SMTP id\n d9443c01a7336-2a871daa98fso78233595ad.1\n        for <linux-pci@vger.kernel.org>; Tue, 28 Apr 2026 15:55:41 -0700 (PDT)","from geramyl-MS-S1-MAX.. ([2601:201:8080:e5c0:4857:38db:7c94:21e1])\n        by smtp.gmail.com with ESMTPSA id\n d9443c01a7336-2b98898ff65sm2518875ad.78.2026.04.28.15.55.40\n        (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n        Tue, 28 Apr 2026 15:55:40 -0700 (PDT)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1777416943; cv=none;\n b=SCfrhSmcp6Dqq0D230XHZZJvGbBCIgp36eYgxOp9b39dmp9FK8OflObIWFk8ycQJpDeq1SbW/CB1AZxdWcdUZzFXwvbosjSd3pfhm1RFD25dLwxVrqIenXW4cQNiIBnv105/GaIRS4tdGgkYxmwL/vTEB0fXVQY+liWMlfht4NI=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1777416943; c=relaxed/simple;\n\tbh=w92j1+KGo6D2kBLTSJDqU4ABcn9vG3xGdTKg2rNKn1s=;\n\th=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type;\n b=ps5uqJSZxTJ3wcase9g607Yhzt4+9rdza+EzTpKieSHFpiDw47FhjKe8tMnQwGzovpA9O642EFSMyjC5IP6fwwIZ6B6haitzkhbiZILZHCIU+Mt3hXMpJOL6KooKQwDccWd67WAEQDYDSwCSVq533L2a+H9YrcyPGM8yoaudJG4=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dmarc=none (p=none dis=none) header.from=jqluv.com;\n spf=none smtp.mailfrom=jqluv.com;\n dkim=pass (2048-bit key) header.d=jqluv-com.20251104.gappssmtp.com\n header.i=@jqluv-com.20251104.gappssmtp.com header.b=oNF26PNT;\n arc=none smtp.client-ip=209.85.214.172","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n        d=jqluv-com.20251104.gappssmtp.com; s=20251104; t=1777416941;\n x=1778021741; darn=vger.kernel.org;\n        h=content-transfer-encoding:mime-version:message-id:date:subject:cc\n         :to:from:from:to:cc:subject:date:message-id:reply-to;\n        bh=SXh1sIdWXyFAkS1VJdBRbGA0VRROpFm5fAuvzlWqXxk=;\n        b=oNF26PNTJ3480BvVU+dlzEHLF6/6disZ9nACXdtQsMMCua2YpwkN0NLWPcsvyns5uj\n         5FrPrAU3xktZBtAaGH3/eMAKrPNinzwkSSvxHJmz9OP4uUsF1ZSCOpxLCm32bFMbkWKj\n         GWOR6E4gaoCZRc3V8KjaHFJQybrdw7+EtmL9JGfmCo2s8D+56iPeQoWaceSbCK0EeVdl\n         +PBo14Lxh84ZANg+6FCJMoeh8XzAtcoHHjWhaSceTUfxvteGyK2Wzf/Z/vIjeaggz8Oj\n         glhMs6UTmf9tLP5vzGMoEaUYJFvRaBO1JYgSnXGdTpXN06EaCrqxjfdp9zVhm4ah2P8a\n         13TQ==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n        d=1e100.net; s=20251104; t=1777416941; x=1778021741;\n        h=content-transfer-encoding:mime-version:message-id:date:subject:cc\n         :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date\n         :message-id:reply-to;\n        bh=SXh1sIdWXyFAkS1VJdBRbGA0VRROpFm5fAuvzlWqXxk=;\n        b=Vqk9W72zf8MmsJQIw+Xck+8AHOvp3eR2JQ4vqYm1oyzOaI4cnBa48604o9Z6m2LDKQ\n         l6IoV7qfEutzsSeAXq6pErGPW1flxUOIUeM5jTaL0q99qSvci5T9Enp7AqzXHJzJY2gU\n         H8S7JAwG2Dr3j5KyQJAkeFrnAsup37DiYHPOh1qvXar95KKSPZoZFFNcTtJEi9os3MlJ\n         cH2XeQ5jvNR3Y3FWaryutelKLykStoyfF6furTaI8oUx1brwSx8C1264KIMGUVHmkLh7\n         u+B4+UOCTvfUWx/iKVBYVH/PXL0pAlm7wUqU3ZEU89AEZDSXxdm8vO41dd4joeuqCOcX\n         J9Nw==","X-Forwarded-Encrypted":"i=1;\n AFNElJ9vYBJZJBvO85TzkkmYvsPJYBbrwJnEem9Q/LtmdX2eZ1AmXa/jlURHVikWW0KyMG2tTM5BbpYcPU0=@vger.kernel.org","X-Gm-Message-State":"AOJu0Yy99JaWgQzSVRQk9qUUMHsDdDM9XWzSKNHAXVQ20E5nDqL8reUV\n\tGPQlAZ+F3CTM9gaQFfVGwMDjuys+LpMWrHK6GVKzVY8axujzMGVps4ez4mPYQkC4VMc=","X-Gm-Gg":"AeBDievbgLQKhr2d/4/XPROEl+sfMp9N4B08hkgA+1OiF4zFvE6lfg3/ffvlLdbZcHA\n\t6gkICcGUhRTJKMEobvC9GHGb4R4BPrW6bYfQyd3cS5icvuRMBKdtHXGQD5IReTfSeApAFoMSLaa\n\teAJeHbduYWftJPQLliSfjIInxiopORd6cvlmoMKScCUnBi9C/+vBL5Tub3UrpgU4QAwn+ud80x0\n\tbdliXAtKbABj9ektbq6ULle5+oRsU3LRXVEMX67ClL3jKDDVnz/+fcRfRLhCWW7ubealXQYYn/b\n\tneYVfdgJRB+CNkAguFsQ/HKTqWUEp9YXl0LHJfvsp36HVivlyhIYzjXI8pOPtQyFWBSaXucSroQ\n\tzlph3FVS2dcel806KxvV7ol+5acGDU5Q1qr/Utqz+03B3U/5x97lvYJc+a7elFDa2OgCTack1SO\n\t9xMFJGM8i8B1qnj0bsMw8oR9kXYFYchKXU9Jnp6K8oX0iUrHU=","X-Received":"by 2002:a17:903:2411:b0:2b0:67a7:5c4b with SMTP id\n d9443c01a7336-2b97c47b4c3mr50187205ad.28.1777416941276;\n        Tue, 28 Apr 2026 15:55:41 -0700 (PDT)","From":"Geramy Loveless <gloveless@jqluv.com>","To":"=?utf-8?q?Ilpo_J=C3=A4rvinen?= <ilpo.jarvinen@linux.intel.com>","Cc":"Cristian Cocos <cristi@ieee.org>,\n =?utf-8?q?Christian_K=C3=B6nig?= <christian.koenig@amd.com>,\n linux-pci@vger.kernel.org, Geramy Loveless <gloveless@jqluv.com>","Subject":"[PATCH v3 RESEND] PCI: release empty sibling bridge windows during\n window resize","Date":"Tue, 28 Apr 2026 15:55:32 -0700","Message-ID":"<20260428225532.3108047-1-gloveless@jqluv.com>","X-Mailer":"git-send-email 2.43.0","Precedence":"bulk","X-Mailing-List":"linux-pci@vger.kernel.org","List-Id":"<linux-pci.vger.kernel.org>","List-Subscribe":"<mailto:linux-pci+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:linux-pci+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit"},"content":"pbus_reassign_bridge_resources() refuses to release bridge windows that\nhave child resources. On multi-port PCIe switches (e.g. Thunderbolt\ndocks), empty sibling downstream ports hold small reservations that\nprevent the parent window from being freed and re-sized for rebar.\n\nWalk descendants of the target window depth-first, saving and freeing\neach empty bridge window so the parent can then be released and grown.\n\nWithout this change, attempts to grow a window deep below a switch\nfabric leave nested empty windows pinning the ancestor:\n\n  pcieport 0000:65:00.0: bridge window [mem 0x8880000000-0x98800fffff\n    64bit pref]: not released, active children present\n  pcieport 0000:00:03.2: bridge window [mem 0x8880000000-0x98800fffff\n    64bit pref]: not released, active children present\n\nWith the bottom-up walk and upstream ancestry check, the chain unwinds\nand the rebar succeeds:\n\n  pcieport 0000:96:00.0: bridge window [...]: releasing\n  pcieport 0000:95:00.0: bridge window [...]: releasing\n  pcieport 0000:94:00.0: bridge window [...]: releasing\n  pcieport 0000:65:00.0: bridge window [...]: releasing\n  amdgpu 0000:97:00.0: BAR 0 [mem 0x9000000000-0x97ffffffff 64bit pref]:\n    assigned\n\nSuggested-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>\nSigned-off-by: Geramy Loveless <gloveless@jqluv.com>\n---\nRESEND: my earlier v3 (Message-ID 20260428225146.3104063-1-gloveless@jqluv.com)\nwas sent with stale code — the diff was byte-identical to v2 because the\nv3 edits weren't staged before commit --amend. This resend contains the\nactual v3 content described below. Apologies for the noise.\n\nv3:\n - Restructure helper: outer loop only recurses; inner iterates bus\n   resources via pci_bus_for_each_resource(). The release path is now\n   unified, so the caller-side block in pbus_reassign_bridge_resources()\n   is gone.\n - Walk the resource tree upstream when checking ancestry of @b_win,\n   so descendants in nested topologies are also released (Ilpo).\n - Drop pci_resource_is_bridge_win() filter; bus resources are\n   inherently bridge windows.\n - Rename pci_bus_release_empty_bridge_resources() to\n   pbus_release_empty_bridge_resources().\n - Drop misleading \"Uses PCI bus/device iterators...\" paragraph from\n   commit message.\n - Kerneldoc tweaks per Ilpo's review.\n\nv2:\n - Use PCI bus/device iterators instead of walking raw resource tree.\n - Save released resources to rollback list.\n - Filter via pci_resource_is_bridge_win() (now removed in v3).\n - Call release before the !res->child check.\n - Check bridge->subordinate before recursion.\n---\n drivers/pci/setup-bus.c | 78 ++++++++++++++++++++++++++++++++---------\n 1 file changed, 61 insertions(+), 17 deletions(-)","diff":"diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c\nindex 4cf120ebe5a..b47dc1a2925 100644\n--- a/drivers/pci/setup-bus.c\n+++ b/drivers/pci/setup-bus.c\n@@ -2292,6 +2292,63 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)\n }\n EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);\n \n+/*\n+ * pbus_release_empty_bridge_resources - Bottom-up release of bridge windows\n+ * in empty subtrees.\n+ * @bus: PCI bus whose child bridges to process\n+ * @b_win: Ancestor bridge window; only resources that are (grand)parented\n+ *\t   by @b_win are released\n+ * @saved: List to store released resources into for rollback\n+ *\n+ * Recurses depth-first into subordinate buses, then releases bridge windows\n+ * that are (grand)parented by @b_win on the way back up. Each resource is\n+ * stored into @saved before release so the entire operation can be rolled\n+ * back.\n+ */\n+static void pbus_release_empty_bridge_resources(struct pci_bus *bus,\n+\t\t\t\t\t\tstruct resource *b_win,\n+\t\t\t\t\t\tstruct list_head *saved)\n+{\n+\tstruct pci_dev *dev;\n+\tstruct resource *r;\n+\tunsigned int i;\n+\n+\tlist_for_each_entry(dev, &bus->devices, bus_list) {\n+\t\tif (dev->subordinate)\n+\t\t\tpbus_release_empty_bridge_resources(dev->subordinate,\n+\t\t\t\t\t\t\t    b_win, saved);\n+\t}\n+\n+\tpci_bus_for_each_resource(bus, r, i) {\n+\t\tstruct resource *p;\n+\t\tunsigned int idx;\n+\n+\t\tif (!r || !resource_assigned(r))\n+\t\t\tcontinue;\n+\n+\t\t/* Walk upstream to confirm r descends from (or equals) b_win */\n+\t\tfor (p = r; p && p != b_win; p = p->parent)\n+\t\t\t;\n+\t\tif (!p)\n+\t\t\tcontinue;\n+\n+\t\tidx = pci_resource_num(bus->self, r);\n+\n+\t\tif (r->child) {\n+\t\t\tconst char *res_name = pci_resource_name(bus->self, idx);\n+\n+\t\t\tpci_info(bus->self, \"%s %pR: not released, active children present\\n\",\n+\t\t\t\t res_name, r);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tif (pci_dev_res_add_to_list(saved, bus->self, r, 0, 0))\n+\t\t\tcontinue;\n+\n+\t\tpci_release_resource(bus->self, idx);\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@@ -2305,7 +2362,6 @@ static int pbus_reassign_bridge_resources(struct pci_bus *bus, struct resource *\n \tstruct pci_dev *bridge = NULL;\n \tLIST_HEAD(added);\n \tLIST_HEAD(failed);\n-\tunsigned int i;\n \tint ret = 0;\n \n \twhile (!pci_is_root_bus(bus)) {\n@@ -2314,22 +2370,10 @@ static int pbus_reassign_bridge_resources(struct pci_bus *bus, struct resource *\n \t\tif (!res)\n \t\t\tbreak;\n \n-\t\ti = pci_resource_num(bridge, res);\n-\n-\t\t/* Ignore BARs 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-\t\t\t\treturn ret;\n-\n-\t\t\tpci_release_resource(bridge, i);\n-\t\t} else {\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 res_name, res);\n-\t\t}\n+\t\t/* Release this bridge window and any empty descendants bottom-up */\n+\t\tif (bridge->subordinate)\n+\t\t\tpbus_release_empty_bridge_resources(bridge->subordinate,\n+\t\t\t\t\t\t\t    res, saved);\n \n \t\tbus = bus->parent;\n \t}\n","prefixes":["v3","RESEND"]}