Skip to contentSkip to conversation

Allocate resources for PHB DLPAR add

PATCH In review Nathan Fontenot 2 participants 2 messages Oct 24, 2008 PowerPC

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Allocate resources for PHB DLPAR add

Resources for PHB's that are DLPAR added to a system are not acquired. Not having these resources allocated causes an oops during DLPAR remove of the PHB when we try to release non-existant resources.

The patch appears a bit messy, this is mainly due to moving everything
one tab to the left in the pcibios_allocate_bus_resources routine. The
big functionality change in this routine is only that the list_for_each_entry() loop is pulled out and moved to the necessary calling routine.

---

arch/powerpc/kernel/pci-common.c +1 -1
Index: linux-2.6/arch/powerpc/kernel/pci-common.c
===================================================================
@@ -986,69 +986,66 @@
 *	    as well.
 */
 
-static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
+void pcibios_allocate_bus_resources(struct pci_bus *bus)

{
- struct pci_bus *bus;

+	struct pci_bus *b;
	int i;
	struct resource *res, *pr;

- /* Depth-First Search on bus tree */
- list_for_each_entry(bus, bus_list, node) {
- for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
- if ((res = bus->resource[i]) == NULL || !res->flags
- || res->start > res->end)
- continue;
- if (bus->parent == NULL)
- pr = (res->flags & IORESOURCE_IO) ?
- &ioport_resource : &iomem_resource;
- else {
- /* Don't bother with non-root busses when
- * re-assigning all resources. We clear the
- * resource flags as if they were colliding
- * and as such ensure proper re-allocation
- * later.
+ for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
+ if ((res = bus->resource[i]) == NULL || !res->flags
+ || res->start > res->end)
+ continue;
+ if (bus->parent == NULL)
+ pr = (res->flags & IORESOURCE_IO) ?
+ &ioport_resource : &iomem_resource;
+ else {
+ /* Don't bother with non-root busses when
+ * re-assigning all resources. We clear the
+ * resource flags as if they were colliding
+ * and as such ensure proper re-allocation
+ * later.
+ */
+ if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)
+ goto clear_resource;
+ pr = pci_find_parent_resource(bus->self, res);
+ if (pr == res) {
+ /* this happens when the generic PCI
+ * code (wrongly) decides that this
+ * bridge is transparent -- paulus

				 */

- if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)
- goto clear_resource;
- pr = pci_find_parent_resource(bus->self, res);
- if (pr == res) {
- /* this happens when the generic PCI
- * code (wrongly) decides that this
- * bridge is transparent -- paulus
- */
- continue;
- }

+				continue;
			}

+ }

- DBG("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx "

-			    "[0x%x], parent %p (%s)\n",
-			    bus->self ? pci_name(bus->self) : "PHB",
-			    bus->number, i,
-			    (unsigned long long)res->start,
-			    (unsigned long long)res->end,
-			    (unsigned int)res->flags,
-			    pr, (pr && pr->name) ? pr->name : "nil");

-
- if (pr && !(pr->flags & IORESOURCE_UNSET)) {
- if (request_resource(pr, res) == 0)
- continue;
- /*
- * Must be a conflict with an existing entry.
- * Move that entry (or entries) under the
- * bridge resource and try again.
- */
- if (reparent_resources(pr, res) == 0)
- continue;
- }
- printk(KERN_WARNING

-			       "PCI: Cannot allocate resource region "
-			       "%d of PCI bridge %d, will remap\n",
-			       i, bus->number);
-clear_resource:
-			res->flags = 0;
+		DBG("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx "
+		    "[0x%x], parent %p (%s)\n",
+		    bus->self ? pci_name(bus->self) : "PHB",
+		    bus->number, i,
+		    (unsigned long long)res->start,
+		    (unsigned long long)res->end,
+		    (unsigned int)res->flags,
+		    pr, (pr && pr->name) ? pr->name : "nil");

+
+ if (pr && !(pr->flags & IORESOURCE_UNSET)) {
+ if (request_resource(pr, res) == 0)
+ continue;
+ /*
+ * Must be a conflict with an existing entry.
+ * Move that entry (or entries) under the
+ * bridge resource and try again.
+ */
+ if (reparent_resources(pr, res) == 0)

+				continue;
		}

- pcibios_allocate_bus_resources(&bus->children);
+ printk(KERN_WARNING "PCI: Cannot allocate resource region "
+ "%d of PCI bridge %d, will remap\n", i, bus->number);
+clear_resource:

+		res->flags = 0;
	}

+
+ list_for_each_entry(b, &bus->children, node)
+ pcibios_allocate_bus_resources(b);
}

static inline void __devinit alloc_resource(struct pci_dev *dev, int idx) @@ -1119,10 +1116,13 @@

void __init pcibios_resource_survey(void)
{
+ struct pci_bus *b;
+

	/* Allocate and assign resources. If we re-assign everything, then
	 * we skip the allocate phase
	 */

- pcibios_allocate_bus_resources(&pci_root_buses);
+ list_for_each_entry(b, &pci_root_buses, node)
+ pcibios_allocate_bus_resources(b);

	if (!(ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)) {
		pcibios_allocate_resources(0);
arch/powerpc/include/asm/pci.h +0 -0
Index: linux-2.6/arch/powerpc/include/asm/pci.h
===================================================================
@@ -196,6 +196,8 @@
 

extern void pcibios_claim_one_bus(struct pci_bus *b);

+extern void pcibios_allocate_bus_resources(struct pci_bus *bus); +
extern void pcibios_resource_survey(void);

extern struct pci_controller *init_phb_dynamic(struct device_node *dn);

arch/powerpc/platforms/pseries/pci_dlpar.c +0 -0
Index: linux-2.6/arch/powerpc/platforms/pseries/pci_dlpar.c
===================================================================
@@ -189,6 +189,7 @@
{
	struct pci_controller *phb;
	int primary;

+ struct pci_bus *b;

	primary = list_empty(&hose_list);
	phb = pcibios_alloc_controller(dn);
@@ -203,6 +204,7 @@
		eeh_add_device_tree_early(dn);

	scan_phb(phb);
+	pcibios_allocate_bus_resources(phb->bus);
	pcibios_fixup_new_pci_devices(phb->bus);
	pci_bus_add_devices(phb->bus);
	eeh_add_device_tree_late(phb->bus);
#1 lore raw
Quoted 10 lines · Nathan Fontenot

Resources for PHB's that are DLPAR added to a system are not acquired. Not having these resources allocated causes an oops during DLPAR remove of the PHB when we try to release non-existant resources.

The patch appears a bit messy, this is mainly due to moving everything one tab to the left in the pcibios_allocate_bus_resources routine. The big functionality change in this routine is only that the list_for_each_entry() loop is pulled out and moved to the necessary calling routine.

Quoted 3 lines

---

Patch looks good.

I'll include it in the next batch hopefully along with a variant of another patch I'm working on to fix other issues I found with our PCI hotplug resource management.

Cheers,
Ben.