Patchwork pci hotplug: rescan bridge after device hotplug

login
register
mail settings
Submitter Jason Baron
Date May 22, 2012, 8:11 p.m.
Message ID <201205222011.q4MKBcMo024624@int-mx02.intmail.prod.int.phx2.redhat.com>
Download mbox | patch
Permalink /patch/160735/
State Superseded
Headers show

Comments

Jason Baron - May 22, 2012, 8:11 p.m.
I'm tyring to support bridge hotplug and devices below it in qemu via acpi
hotplug. Currently only 1 level or 32 slots are supported. By allowing for a
second level, we will be able to support 32^2 devices.

If I first hotplug the bridge with no devices intially below it, the hotplug
code sets the bridge memory window to 0 and does not increase it when
subsequent devices are added below it.

Fix this, by calling pci_rescan_bus_bridge_resize(), on the bridge directly
below the root to re-size all the birdge windows that may have changed.

Signed-off-by: Jason Baron <jbaron@redhat.com>
---
 drivers/pci/hotplug/acpiphp_glue.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)
Yinghai Lu - May 22, 2012, 8:34 p.m.
On Tue, May 22, 2012 at 1:11 PM, Jason Baron <jbaron@redhat.com> wrote:
> I'm tyring to support bridge hotplug and devices below it in qemu via acpi
> hotplug. Currently only 1 level or 32 slots are supported. By allowing for a
> second level, we will be able to support 32^2 devices.
>
> If I first hotplug the bridge with no devices intially below it, the hotplug
> code sets the bridge memory window to 0 and does not increase it when
> subsequent devices are added below it.
>
> Fix this, by calling pci_rescan_bus_bridge_resize(), on the bridge directly
> below the root to re-size all the birdge windows that may have changed.
>
> Signed-off-by: Jason Baron <jbaron@redhat.com>

can you check patch in

http://git.kernel.org/?p=linux/kernel/git/yinghai/linux-yinghai.git;a=patch;h=174dfefc6066bf0af21e0989ad3aa7b1cc3cd46a

During checking acpiphp code, found following sequence:
        pci_bus_size_bridges(bus);
        pci_bus_assign_resources(bus);
	pci_enable_bridges(bus);

The problem is that when bus is not root bus, pci_bus_size_bridges
would also size
own pci bridge bus->self if that bridge resource is not inserted before.
but later pci_bus_assign_resources will not allocate those size bridge res.

So try make it less confusing, let it does not include self sizing.
and add with_self parameter info __pci_bus_size_bridge()

Fixes caller in pci hotplug componets.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/hotplug/acpiphp_glue.c |    3 ++-
 drivers/pci/setup-bus.c            |   24 +++++++++++++++---------
 include/linux/pci.h                |    1 +
 3 files changed, 18 insertions(+), 10 deletions(-)
..

it should address your problem.

Yinghai
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Yinghai Lu - May 22, 2012, 9:18 p.m.
On Tue, May 22, 2012 at 1:34 PM, Yinghai Lu <yinghai@kernel.org> wrote:
> On Tue, May 22, 2012 at 1:11 PM, Jason Baron <jbaron@redhat.com> wrote:
>> I'm tyring to support bridge hotplug and devices below it in qemu via acpi
>> hotplug. Currently only 1 level or 32 slots are supported. By allowing for a
>> second level, we will be able to support 32^2 devices.
>>
>> If I first hotplug the bridge with no devices intially below it, the hotplug
>> code sets the bridge memory window to 0 and does not increase it when
>> subsequent devices are added below it.
>>
>> Fix this, by calling pci_rescan_bus_bridge_resize(), on the bridge directly
>> below the root to re-size all the birdge windows that may have changed.
>>
>> Signed-off-by: Jason Baron <jbaron@redhat.com>
>
> can you check patch in
>
> http://git.kernel.org/?p=linux/kernel/git/yinghai/linux-yinghai.git;a=patch;h=174dfefc6066bf0af21e0989ad3aa7b1cc3cd46a
>
never mind, that seems another problem.

Yinghai
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Yinghai Lu - May 22, 2012, 9:21 p.m.
On Tue, May 22, 2012 at 1:11 PM, Jason Baron <jbaron@redhat.com> wrote:
> I'm tyring to support bridge hotplug and devices below it in qemu via acpi
> hotplug. Currently only 1 level or 32 slots are supported. By allowing for a
> second level, we will be able to support 32^2 devices.
>
> If I first hotplug the bridge with no devices intially below it, the hotplug
> code sets the bridge memory window to 0 and does not increase it when
> subsequent devices are added below it.
>
> Fix this, by calling pci_rescan_bus_bridge_resize(), on the bridge directly
> below the root to re-size all the birdge windows that may have changed.
>
> Signed-off-by: Jason Baron <jbaron@redhat.com>
> ---
>  drivers/pci/hotplug/acpiphp_glue.c |    8 ++++++++
>  1 files changed, 8 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
> index 806c44f..8960c1e 100644
> --- a/drivers/pci/hotplug/acpiphp_glue.c
> +++ b/drivers/pci/hotplug/acpiphp_glue.c
> @@ -792,6 +792,7 @@ static int __ref enable_device(struct acpiphp_slot *slot)
>  {
>        struct pci_dev *dev;
>        struct pci_bus *bus = slot->bridge->pci_bus;
> +       struct pci_bus *rescan_bus;
>        struct acpiphp_func *func;
>        int retval = 0;
>        int num, max, pass;
> @@ -821,6 +822,13 @@ static int __ref enable_device(struct acpiphp_slot *slot)
>                }
>        }
>
> +       /* Ensure we rescan/setup a bridge for new devs hanging off of it */
> +       rescan_bus = bus;
> +       while (rescan_bus->parent && rescan_bus->parent->self)
> +               rescan_bus = rescan_bus->parent;
> +       if (rescan_bus->self)
> +               pci_rescan_bus_bridge_resize(rescan_bus->self);
> +

No, you can not do that.  some parents bus could have other devices
and driver could be loaded for those devices.
so can not release resources that are used by those devices to resize
parent bridges.

>        list_for_each_entry(func, &slot->funcs, sibling)
>                acpiphp_bus_add(func);
>
> --
> 1.7.7.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 806c44f..8960c1e 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -792,6 +792,7 @@  static int __ref enable_device(struct acpiphp_slot *slot)
 {
 	struct pci_dev *dev;
 	struct pci_bus *bus = slot->bridge->pci_bus;
+	struct pci_bus *rescan_bus;
 	struct acpiphp_func *func;
 	int retval = 0;
 	int num, max, pass;
@@ -821,6 +822,13 @@  static int __ref enable_device(struct acpiphp_slot *slot)
 		}
 	}
 
+	/* Ensure we rescan/setup a bridge for new devs hanging off of it */
+	rescan_bus = bus;
+	while (rescan_bus->parent && rescan_bus->parent->self)
+		rescan_bus = rescan_bus->parent;
+	if (rescan_bus->self)
+		pci_rescan_bus_bridge_resize(rescan_bus->self);
+
 	list_for_each_entry(func, &slot->funcs, sibling)
 		acpiphp_bus_add(func);