All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andreas Noever <andreas.noever@gmail.com>
To: linux-kernel@vger.kernel.org, Bjorn Helgaas <bhelgaas@google.com>,
	linux-pci@vger.kernel.org
Cc: Andreas Noever <andreas.noever@gmail.com>
Subject: [PATCH] PCI: Do not touch siblings in pci_assign_unassigned_bridge_resources
Date: Mon,  9 Jun 2014 22:45:30 +0200	[thread overview]
Message-ID: <1402346730-2508-1-git-send-email-andreas.noever@gmail.com> (raw)

pci_assign_unassigned_bridge_resources is used to assign resources below
a hotplug bridge. If the first attempt fails it will release some
resources and try again. If a resource allocation on the hotplug bridge
itself fails then pci_assign_unassigned_bridge_resources will invoke
pci_bus_release_bridge_resources on the parent bus of the hotplug
bridge. This in turn will release resources assigned to siblings of the
hotplug bridge which may already be in use.

This patch checks for this case and prevents
pci_bus_release_bridge_resources to be invoked on the parent bus.

The problem can be reproduced by having two sibling hotplug bridges A
and B. The problem will occour if the parent of A and B does not have
enough resources to satisfy window allocations for B during a hotplug
event.

Signed-off-by: Andreas Noever <andreas.noever@gmail.com>
---

I must admit that I do not fully understand how
pci_assign_unassigned_bridge_resources works. Under which scenario would the
second allocation attempt be successful?

Thanks,
Andreas

 drivers/pci/setup-bus.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 138bdd6..2e418d6 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1560,6 +1560,12 @@ void __init pci_assign_unassigned_resources(void)
 		pci_assign_unassigned_root_bus_resources(root_bus);
 }
 
+/**
+ * pci_assign_unassigned_bridge_resources - greenfield resource allocation
+ *
+ * Try to assign io and memory resources on and below @bridge. The caller must
+ * ensure that no device below @bridge is active.
+ */
 void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
 {
 	struct pci_bus *parent = bridge->subordinate;
@@ -1567,7 +1573,7 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
 					want additional resources */
 	int tried_times = 0;
 	LIST_HEAD(fail_head);
-	struct pci_dev_resource *fail_res;
+	struct pci_dev_resource *fail_res, *tmp;
 	int retval;
 	unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
 				  IORESOURCE_PREFETCH;
@@ -1594,10 +1600,21 @@ again:
 	 * Try to release leaf bridge's resources that doesn't fit resource of
 	 * child device under that bridge
 	 */
-	list_for_each_entry(fail_res, &fail_head, list)
+	list_for_each_entry_safe(fail_res, tmp, &fail_head, list) {
+		 /*
+		  * The allocation of the mem/io window of the top level bridge
+		  * can fail.  Without the following check we would release our
+		  * siblings' resources.
+		  */
+		if (fail_res->dev == bridge) {
+			list_del(&fail_res->list);
+			kfree(fail_res);
+			continue;
+		}
 		pci_bus_release_bridge_resources(fail_res->dev->bus,
 						 fail_res->flags & type_mask,
 						 whole_subtree);
+	}
 
 	/* restore size and flags */
 	list_for_each_entry(fail_res, &fail_head, list) {
-- 
2.0.0


             reply	other threads:[~2014-06-09 20:45 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-09 20:45 Andreas Noever [this message]
2014-06-17 22:16 ` [PATCH] PCI: Do not touch siblings in pci_assign_unassigned_bridge_resources Bjorn Helgaas
2014-06-17 23:39   ` Yinghai Lu
2014-06-18 22:40     ` Andreas Noever
2014-06-19  4:41       ` Yinghai Lu
2014-06-30 22:47         ` Bjorn Helgaas
2014-07-01 18:35           ` Yinghai Lu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1402346730-2508-1-git-send-email-andreas.noever@gmail.com \
    --to=andreas.noever@gmail.com \
    --cc=bhelgaas@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.