diff mbox

ACPI: Fix osc flag setup ordering to allow pcie hotplug use when available

Message ID 1377278379-9054-1-git-send-email-nhorman@tuxdriver.com (mailing list archive)
State Rejected, archived
Headers show

Commit Message

Neil Horman Aug. 23, 2013, 5:19 p.m. UTC
Somewhere between 3.9 and 3.10 it seems the order in which pcie and acpi probed
slots for hotplug capabilites got reversed.  While this isn't a big deal, it did
uncover a bug in the ACPI bus setup path.  Specifically, acpi_pci_root_add calls
pci_acpi_scan_root before setting the osc flags for the device handle.
pci_acpi_scan_root, among other things uses device_is_managed_by_native_pciehp()
to determine if a given slot has pcie hotplug capabilties, whcih checks the
devices OSC_PCI_EXPRESS_NATIVE_HP_CONTROL flag.  Since that flag is not set
until after pci_acpi_scan_root_completes, the acpi code never sees that pcie
slots are hotplug capable and configures them all to use acpi instead.

Fix is pretty simple, just defer the scan until after the osc flags have been
set on the device.  Tested by myself and it seems to work well.

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: Len Brown <lenb@kernel.org>
CC: "Rafael J. Wysocki" <rjw@sisk.pl>
CC: linux-acpi@vger.kernel.org
---
 drivers/acpi/pci_root.c | 41 ++++++++++++++++++++---------------------
 1 file changed, 20 insertions(+), 21 deletions(-)

Comments

Rafael Wysocki Aug. 23, 2013, 7:38 p.m. UTC | #1
[CCs added]

Please always send PCI-related material to linux-pci in the first place.

The change that broke things for you was actually intentional:

commit b8178f130e25c1bdac1c33e0996f1ff6e20ec08e
Author: Bjorn Helgaas <bhelgaas@google.com>
Date:   Mon Apr 1 15:47:39 2013 -0600

    Revert "PCI/ACPI: Request _OSC control before scanning PCI root bus"
    
    This reverts commit 8c33f51df406e1a1f7fa4e9b244845b7ebd61fa6.

so I think we'll need to clean up the ASMP initialization after all.

On Friday, August 23, 2013 01:19:39 PM Neil Horman wrote:
> Somewhere between 3.9 and 3.10 it seems the order in which pcie and acpi probed
> slots for hotplug capabilites got reversed.  While this isn't a big deal, it did
> uncover a bug in the ACPI bus setup path.  Specifically, acpi_pci_root_add calls
> pci_acpi_scan_root before setting the osc flags for the device handle.
> pci_acpi_scan_root, among other things uses device_is_managed_by_native_pciehp()
> to determine if a given slot has pcie hotplug capabilties, whcih checks the
> devices OSC_PCI_EXPRESS_NATIVE_HP_CONTROL flag.  Since that flag is not set
> until after pci_acpi_scan_root_completes, the acpi code never sees that pcie
> slots are hotplug capable and configures them all to use acpi instead.
> 
> Fix is pretty simple, just defer the scan until after the osc flags have been
> set on the device.  Tested by myself and it seems to work well.
> 
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> CC: Len Brown <lenb@kernel.org>
> CC: "Rafael J. Wysocki" <rjw@sisk.pl>
> CC: linux-acpi@vger.kernel.org
> ---
>  drivers/acpi/pci_root.c | 41 ++++++++++++++++++++---------------------
>  1 file changed, 20 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> index 5917839..a2c2661 100644
> --- a/drivers/acpi/pci_root.c
> +++ b/drivers/acpi/pci_root.c
> @@ -437,27 +437,6 @@ static int acpi_pci_root_add(struct acpi_device *device,
>  	flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
>  	acpi_pci_osc_support(root, flags);
>  
> -	/*
> -	 * TBD: Need PCI interface for enumeration/configuration of roots.
> -	 */
> -
> -	/*
> -	 * Scan the Root Bridge
> -	 * --------------------
> -	 * Must do this prior to any attempt to bind the root device, as the
> -	 * PCI namespace does not get created until this call is made (and
> -	 * thus the root bridge's pci_dev does not exist).
> -	 */
> -	root->bus = pci_acpi_scan_root(root);
> -	if (!root->bus) {
> -		dev_err(&device->dev,
> -			"Bus %04x:%02x not present in PCI namespace\n",
> -			root->segment, (unsigned int)root->secondary.start);
> -		result = -ENODEV;
> -		goto end;
> -	}
> -
> -	/* Indicate support for various _OSC capabilities. */
>  	if (pci_ext_cfg_avail())
>  		flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
>  	if (pcie_aspm_support_enabled()) {
> @@ -520,6 +499,26 @@ static int acpi_pci_root_add(struct acpi_device *device,
>  			 "(_OSC support mask: 0x%02x)\n", flags);
>  	}
>  
> +	/*
> +	 * TBD: Need PCI interface for enumeration/configuration of roots.
> +	 */
> +
> +	/*
> +	 * Scan the Root Bridge
> +	 * --------------------
> +	 * Must do this prior to any attempt to bind the root device, as the
> +	 * PCI namespace does not get created until this call is made (and
> +	 * thus the root bridge's pci_dev does not exist).
> +	 */
> +	root->bus = pci_acpi_scan_root(root);
> +	if (!root->bus) {
> +		dev_err(&device->dev,
> +			"Bus %04x:%02x not present in PCI namespace\n",
> +			root->segment, (unsigned int)root->secondary.start);
> +		result = -ENODEV;
> +		goto end;
> +	}
> +
>  	pci_acpi_add_bus_pm_notifier(device, root->bus);
>  	if (device->wakeup.flags.run_wake)
>  		device_set_run_wake(root->bus->bridge, true);
>
Neil Horman Aug. 23, 2013, 8:05 p.m. UTC | #2
On Fri, Aug 23, 2013 at 09:38:18PM +0200, Rafael J. Wysocki wrote:
> [CCs added]
> 
> Please always send PCI-related material to linux-pci in the first place.
> 
Sorry, I ran get_maintainers and it seemed to think linux-acpi was sufficient.

> The change that broke things for you was actually intentional:
> 
> commit b8178f130e25c1bdac1c33e0996f1ff6e20ec08e
> Author: Bjorn Helgaas <bhelgaas@google.com>
> Date:   Mon Apr 1 15:47:39 2013 -0600
> 
>     Revert "PCI/ACPI: Request _OSC control before scanning PCI root bus"
>     
>     This reverts commit 8c33f51df406e1a1f7fa4e9b244845b7ebd61fa6.
> 
> so I think we'll need to clean up the ASMP initialization after all.
> 
Crud.  Reading over the revert commit, it seems like the problem boils down to
the odering of checking aspm_disabled.  It seems to me that the simple fix is to
track the desire for acpi to disable aspm separately from the users desire to
disable aspm (aspm_disabled).  Then we just turn the points where we check the
aspm_disabled into the appropriate or of two variables, except for
pcie_asmp_sanity_check, which remains sensitive to just the user disable option.

Or is there more to this?

Neil

> On Friday, August 23, 2013 01:19:39 PM Neil Horman wrote:
> > Somewhere between 3.9 and 3.10 it seems the order in which pcie and acpi probed
> > slots for hotplug capabilites got reversed.  While this isn't a big deal, it did
> > uncover a bug in the ACPI bus setup path.  Specifically, acpi_pci_root_add calls
> > pci_acpi_scan_root before setting the osc flags for the device handle.
> > pci_acpi_scan_root, among other things uses device_is_managed_by_native_pciehp()
> > to determine if a given slot has pcie hotplug capabilties, whcih checks the
> > devices OSC_PCI_EXPRESS_NATIVE_HP_CONTROL flag.  Since that flag is not set
> > until after pci_acpi_scan_root_completes, the acpi code never sees that pcie
> > slots are hotplug capable and configures them all to use acpi instead.
> > 
> > Fix is pretty simple, just defer the scan until after the osc flags have been
> > set on the device.  Tested by myself and it seems to work well.
> > 
> > Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> > CC: Len Brown <lenb@kernel.org>
> > CC: "Rafael J. Wysocki" <rjw@sisk.pl>
> > CC: linux-acpi@vger.kernel.org
> > ---
> >  drivers/acpi/pci_root.c | 41 ++++++++++++++++++++---------------------
> >  1 file changed, 20 insertions(+), 21 deletions(-)
> > 
> > diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> > index 5917839..a2c2661 100644
> > --- a/drivers/acpi/pci_root.c
> > +++ b/drivers/acpi/pci_root.c
> > @@ -437,27 +437,6 @@ static int acpi_pci_root_add(struct acpi_device *device,
> >  	flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
> >  	acpi_pci_osc_support(root, flags);
> >  
> > -	/*
> > -	 * TBD: Need PCI interface for enumeration/configuration of roots.
> > -	 */
> > -
> > -	/*
> > -	 * Scan the Root Bridge
> > -	 * --------------------
> > -	 * Must do this prior to any attempt to bind the root device, as the
> > -	 * PCI namespace does not get created until this call is made (and
> > -	 * thus the root bridge's pci_dev does not exist).
> > -	 */
> > -	root->bus = pci_acpi_scan_root(root);
> > -	if (!root->bus) {
> > -		dev_err(&device->dev,
> > -			"Bus %04x:%02x not present in PCI namespace\n",
> > -			root->segment, (unsigned int)root->secondary.start);
> > -		result = -ENODEV;
> > -		goto end;
> > -	}
> > -
> > -	/* Indicate support for various _OSC capabilities. */
> >  	if (pci_ext_cfg_avail())
> >  		flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
> >  	if (pcie_aspm_support_enabled()) {
> > @@ -520,6 +499,26 @@ static int acpi_pci_root_add(struct acpi_device *device,
> >  			 "(_OSC support mask: 0x%02x)\n", flags);
> >  	}
> >  
> > +	/*
> > +	 * TBD: Need PCI interface for enumeration/configuration of roots.
> > +	 */
> > +
> > +	/*
> > +	 * Scan the Root Bridge
> > +	 * --------------------
> > +	 * Must do this prior to any attempt to bind the root device, as the
> > +	 * PCI namespace does not get created until this call is made (and
> > +	 * thus the root bridge's pci_dev does not exist).
> > +	 */
> > +	root->bus = pci_acpi_scan_root(root);
> > +	if (!root->bus) {
> > +		dev_err(&device->dev,
> > +			"Bus %04x:%02x not present in PCI namespace\n",
> > +			root->segment, (unsigned int)root->secondary.start);
> > +		result = -ENODEV;
> > +		goto end;
> > +	}
> > +
> >  	pci_acpi_add_bus_pm_notifier(device, root->bus);
> >  	if (device->wakeup.flags.run_wake)
> >  		device_set_run_wake(root->bus->bridge, true);
> > 
> -- 
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Bjorn Helgaas Aug. 23, 2013, 8:46 p.m. UTC | #3
On Fri, Aug 23, 2013 at 2:53 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Friday, August 23, 2013 04:05:11 PM Neil Horman wrote:
>> On Fri, Aug 23, 2013 at 09:38:18PM +0200, Rafael J. Wysocki wrote:
>> > [CCs added]
>> >
>> > Please always send PCI-related material to linux-pci in the first place.
>> >
>> Sorry, I ran get_maintainers and it seemed to think linux-acpi was sufficient.
>>
>> > The change that broke things for you was actually intentional:
>> >
>> > commit b8178f130e25c1bdac1c33e0996f1ff6e20ec08e
>> > Author: Bjorn Helgaas <bhelgaas@google.com>
>> > Date:   Mon Apr 1 15:47:39 2013 -0600
>> >
>> >     Revert "PCI/ACPI: Request _OSC control before scanning PCI root bus"
>> >
>> >     This reverts commit 8c33f51df406e1a1f7fa4e9b244845b7ebd61fa6.
>> >
>> > so I think we'll need to clean up the ASMP initialization after all.
>> >
>> Crud.  Reading over the revert commit, it seems like the problem boils down to
>> the odering of checking aspm_disabled.  It seems to me that the simple fix is to
>> track the desire for acpi to disable aspm separately from the users desire to
>> disable aspm (aspm_disabled).  Then we just turn the points where we check the
>> aspm_disabled into the appropriate or of two variables, except for
>> pcie_asmp_sanity_check, which remains sensitive to just the user disable option.
>>
>> Or is there more to this?
>
> No, I think you're right.
>
> Bjorn, what do you think?

My opinion is that the _OSC/ASPM state management is ridiculously
complicated already, and this would make it slightly more complicated.
 That's why my preference would be to attempt a more radical cleanup
and simplification instead of adding another wart.

But if you want to merge a patch along the lines of what Neil
proposes, I won't object.

Bjorn

>> > On Friday, August 23, 2013 01:19:39 PM Neil Horman wrote:
>> > > Somewhere between 3.9 and 3.10 it seems the order in which pcie and acpi probed
>> > > slots for hotplug capabilites got reversed.  While this isn't a big deal, it did
>> > > uncover a bug in the ACPI bus setup path.  Specifically, acpi_pci_root_add calls
>> > > pci_acpi_scan_root before setting the osc flags for the device handle.
>> > > pci_acpi_scan_root, among other things uses device_is_managed_by_native_pciehp()
>> > > to determine if a given slot has pcie hotplug capabilties, whcih checks the
>> > > devices OSC_PCI_EXPRESS_NATIVE_HP_CONTROL flag.  Since that flag is not set
>> > > until after pci_acpi_scan_root_completes, the acpi code never sees that pcie
>> > > slots are hotplug capable and configures them all to use acpi instead.
>> > >
>> > > Fix is pretty simple, just defer the scan until after the osc flags have been
>> > > set on the device.  Tested by myself and it seems to work well.
>> > >
>> > > Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
>> > > CC: Len Brown <lenb@kernel.org>
>> > > CC: "Rafael J. Wysocki" <rjw@sisk.pl>
>> > > CC: linux-acpi@vger.kernel.org
>> > > ---
>> > >  drivers/acpi/pci_root.c | 41 ++++++++++++++++++++---------------------
>> > >  1 file changed, 20 insertions(+), 21 deletions(-)
>> > >
>> > > diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
>> > > index 5917839..a2c2661 100644
>> > > --- a/drivers/acpi/pci_root.c
>> > > +++ b/drivers/acpi/pci_root.c
>> > > @@ -437,27 +437,6 @@ static int acpi_pci_root_add(struct acpi_device *device,
>> > >   flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
>> > >   acpi_pci_osc_support(root, flags);
>> > >
>> > > - /*
>> > > -  * TBD: Need PCI interface for enumeration/configuration of roots.
>> > > -  */
>> > > -
>> > > - /*
>> > > -  * Scan the Root Bridge
>> > > -  * --------------------
>> > > -  * Must do this prior to any attempt to bind the root device, as the
>> > > -  * PCI namespace does not get created until this call is made (and
>> > > -  * thus the root bridge's pci_dev does not exist).
>> > > -  */
>> > > - root->bus = pci_acpi_scan_root(root);
>> > > - if (!root->bus) {
>> > > -         dev_err(&device->dev,
>> > > -                 "Bus %04x:%02x not present in PCI namespace\n",
>> > > -                 root->segment, (unsigned int)root->secondary.start);
>> > > -         result = -ENODEV;
>> > > -         goto end;
>> > > - }
>> > > -
>> > > - /* Indicate support for various _OSC capabilities. */
>> > >   if (pci_ext_cfg_avail())
>> > >           flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
>> > >   if (pcie_aspm_support_enabled()) {
>> > > @@ -520,6 +499,26 @@ static int acpi_pci_root_add(struct acpi_device *device,
>> > >                    "(_OSC support mask: 0x%02x)\n", flags);
>> > >   }
>> > >
>> > > + /*
>> > > +  * TBD: Need PCI interface for enumeration/configuration of roots.
>> > > +  */
>> > > +
>> > > + /*
>> > > +  * Scan the Root Bridge
>> > > +  * --------------------
>> > > +  * Must do this prior to any attempt to bind the root device, as the
>> > > +  * PCI namespace does not get created until this call is made (and
>> > > +  * thus the root bridge's pci_dev does not exist).
>> > > +  */
>> > > + root->bus = pci_acpi_scan_root(root);
>> > > + if (!root->bus) {
>> > > +         dev_err(&device->dev,
>> > > +                 "Bus %04x:%02x not present in PCI namespace\n",
>> > > +                 root->segment, (unsigned int)root->secondary.start);
>> > > +         result = -ENODEV;
>> > > +         goto end;
>> > > + }
>> > > +
>> > >   pci_acpi_add_bus_pm_notifier(device, root->bus);
>> > >   if (device->wakeup.flags.run_wake)
>> > >           device_set_run_wake(root->bus->bridge, true);
>> > >
>>
> --
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rafael Wysocki Aug. 23, 2013, 8:53 p.m. UTC | #4
On Friday, August 23, 2013 04:05:11 PM Neil Horman wrote:
> On Fri, Aug 23, 2013 at 09:38:18PM +0200, Rafael J. Wysocki wrote:
> > [CCs added]
> > 
> > Please always send PCI-related material to linux-pci in the first place.
> > 
> Sorry, I ran get_maintainers and it seemed to think linux-acpi was sufficient.
> 
> > The change that broke things for you was actually intentional:
> > 
> > commit b8178f130e25c1bdac1c33e0996f1ff6e20ec08e
> > Author: Bjorn Helgaas <bhelgaas@google.com>
> > Date:   Mon Apr 1 15:47:39 2013 -0600
> > 
> >     Revert "PCI/ACPI: Request _OSC control before scanning PCI root bus"
> >     
> >     This reverts commit 8c33f51df406e1a1f7fa4e9b244845b7ebd61fa6.
> > 
> > so I think we'll need to clean up the ASMP initialization after all.
> > 
> Crud.  Reading over the revert commit, it seems like the problem boils down to
> the odering of checking aspm_disabled.  It seems to me that the simple fix is to
> track the desire for acpi to disable aspm separately from the users desire to
> disable aspm (aspm_disabled).  Then we just turn the points where we check the
> aspm_disabled into the appropriate or of two variables, except for
> pcie_asmp_sanity_check, which remains sensitive to just the user disable option.
> 
> Or is there more to this?

No, I think you're right.

Bjorn, what do you think?

Rafael


> > On Friday, August 23, 2013 01:19:39 PM Neil Horman wrote:
> > > Somewhere between 3.9 and 3.10 it seems the order in which pcie and acpi probed
> > > slots for hotplug capabilites got reversed.  While this isn't a big deal, it did
> > > uncover a bug in the ACPI bus setup path.  Specifically, acpi_pci_root_add calls
> > > pci_acpi_scan_root before setting the osc flags for the device handle.
> > > pci_acpi_scan_root, among other things uses device_is_managed_by_native_pciehp()
> > > to determine if a given slot has pcie hotplug capabilties, whcih checks the
> > > devices OSC_PCI_EXPRESS_NATIVE_HP_CONTROL flag.  Since that flag is not set
> > > until after pci_acpi_scan_root_completes, the acpi code never sees that pcie
> > > slots are hotplug capable and configures them all to use acpi instead.
> > > 
> > > Fix is pretty simple, just defer the scan until after the osc flags have been
> > > set on the device.  Tested by myself and it seems to work well.
> > > 
> > > Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> > > CC: Len Brown <lenb@kernel.org>
> > > CC: "Rafael J. Wysocki" <rjw@sisk.pl>
> > > CC: linux-acpi@vger.kernel.org
> > > ---
> > >  drivers/acpi/pci_root.c | 41 ++++++++++++++++++++---------------------
> > >  1 file changed, 20 insertions(+), 21 deletions(-)
> > > 
> > > diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> > > index 5917839..a2c2661 100644
> > > --- a/drivers/acpi/pci_root.c
> > > +++ b/drivers/acpi/pci_root.c
> > > @@ -437,27 +437,6 @@ static int acpi_pci_root_add(struct acpi_device *device,
> > >  	flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
> > >  	acpi_pci_osc_support(root, flags);
> > >  
> > > -	/*
> > > -	 * TBD: Need PCI interface for enumeration/configuration of roots.
> > > -	 */
> > > -
> > > -	/*
> > > -	 * Scan the Root Bridge
> > > -	 * --------------------
> > > -	 * Must do this prior to any attempt to bind the root device, as the
> > > -	 * PCI namespace does not get created until this call is made (and
> > > -	 * thus the root bridge's pci_dev does not exist).
> > > -	 */
> > > -	root->bus = pci_acpi_scan_root(root);
> > > -	if (!root->bus) {
> > > -		dev_err(&device->dev,
> > > -			"Bus %04x:%02x not present in PCI namespace\n",
> > > -			root->segment, (unsigned int)root->secondary.start);
> > > -		result = -ENODEV;
> > > -		goto end;
> > > -	}
> > > -
> > > -	/* Indicate support for various _OSC capabilities. */
> > >  	if (pci_ext_cfg_avail())
> > >  		flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
> > >  	if (pcie_aspm_support_enabled()) {
> > > @@ -520,6 +499,26 @@ static int acpi_pci_root_add(struct acpi_device *device,
> > >  			 "(_OSC support mask: 0x%02x)\n", flags);
> > >  	}
> > >  
> > > +	/*
> > > +	 * TBD: Need PCI interface for enumeration/configuration of roots.
> > > +	 */
> > > +
> > > +	/*
> > > +	 * Scan the Root Bridge
> > > +	 * --------------------
> > > +	 * Must do this prior to any attempt to bind the root device, as the
> > > +	 * PCI namespace does not get created until this call is made (and
> > > +	 * thus the root bridge's pci_dev does not exist).
> > > +	 */
> > > +	root->bus = pci_acpi_scan_root(root);
> > > +	if (!root->bus) {
> > > +		dev_err(&device->dev,
> > > +			"Bus %04x:%02x not present in PCI namespace\n",
> > > +			root->segment, (unsigned int)root->secondary.start);
> > > +		result = -ENODEV;
> > > +		goto end;
> > > +	}
> > > +
> > >  	pci_acpi_add_bus_pm_notifier(device, root->bus);
> > >  	if (device->wakeup.flags.run_wake)
> > >  		device_set_run_wake(root->bus->bridge, true);
> > > 
>
Rafael Wysocki Aug. 23, 2013, 9:40 p.m. UTC | #5
On Friday, August 23, 2013 02:46:23 PM Bjorn Helgaas wrote:
> On Fri, Aug 23, 2013 at 2:53 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Friday, August 23, 2013 04:05:11 PM Neil Horman wrote:
> >> On Fri, Aug 23, 2013 at 09:38:18PM +0200, Rafael J. Wysocki wrote:
> >> > [CCs added]
> >> >
> >> > Please always send PCI-related material to linux-pci in the first place.
> >> >
> >> Sorry, I ran get_maintainers and it seemed to think linux-acpi was sufficient.
> >>
> >> > The change that broke things for you was actually intentional:
> >> >
> >> > commit b8178f130e25c1bdac1c33e0996f1ff6e20ec08e
> >> > Author: Bjorn Helgaas <bhelgaas@google.com>
> >> > Date:   Mon Apr 1 15:47:39 2013 -0600
> >> >
> >> >     Revert "PCI/ACPI: Request _OSC control before scanning PCI root bus"
> >> >
> >> >     This reverts commit 8c33f51df406e1a1f7fa4e9b244845b7ebd61fa6.
> >> >
> >> > so I think we'll need to clean up the ASMP initialization after all.
> >> >
> >> Crud.  Reading over the revert commit, it seems like the problem boils down to
> >> the odering of checking aspm_disabled.  It seems to me that the simple fix is to
> >> track the desire for acpi to disable aspm separately from the users desire to
> >> disable aspm (aspm_disabled).  Then we just turn the points where we check the
> >> aspm_disabled into the appropriate or of two variables, except for
> >> pcie_asmp_sanity_check, which remains sensitive to just the user disable option.
> >>
> >> Or is there more to this?
> >
> > No, I think you're right.
> >
> > Bjorn, what do you think?
> 
> My opinion is that the _OSC/ASPM state management is ridiculously
> complicated already, and this would make it slightly more complicated.
>  That's why my preference would be to attempt a more radical cleanup
> and simplification instead of adding another wart.

Well, do you have anything specific in mind?

> But if you want to merge a patch along the lines of what Neil
> proposes, I won't object.

I'm not sure what to do really, so I'm asking. :-)

Rafael


> >> > On Friday, August 23, 2013 01:19:39 PM Neil Horman wrote:
> >> > > Somewhere between 3.9 and 3.10 it seems the order in which pcie and acpi probed
> >> > > slots for hotplug capabilites got reversed.  While this isn't a big deal, it did
> >> > > uncover a bug in the ACPI bus setup path.  Specifically, acpi_pci_root_add calls
> >> > > pci_acpi_scan_root before setting the osc flags for the device handle.
> >> > > pci_acpi_scan_root, among other things uses device_is_managed_by_native_pciehp()
> >> > > to determine if a given slot has pcie hotplug capabilties, whcih checks the
> >> > > devices OSC_PCI_EXPRESS_NATIVE_HP_CONTROL flag.  Since that flag is not set
> >> > > until after pci_acpi_scan_root_completes, the acpi code never sees that pcie
> >> > > slots are hotplug capable and configures them all to use acpi instead.
> >> > >
> >> > > Fix is pretty simple, just defer the scan until after the osc flags have been
> >> > > set on the device.  Tested by myself and it seems to work well.
> >> > >
> >> > > Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> >> > > CC: Len Brown <lenb@kernel.org>
> >> > > CC: "Rafael J. Wysocki" <rjw@sisk.pl>
> >> > > CC: linux-acpi@vger.kernel.org
> >> > > ---
> >> > >  drivers/acpi/pci_root.c | 41 ++++++++++++++++++++---------------------
> >> > >  1 file changed, 20 insertions(+), 21 deletions(-)
> >> > >
> >> > > diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> >> > > index 5917839..a2c2661 100644
> >> > > --- a/drivers/acpi/pci_root.c
> >> > > +++ b/drivers/acpi/pci_root.c
> >> > > @@ -437,27 +437,6 @@ static int acpi_pci_root_add(struct acpi_device *device,
> >> > >   flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
> >> > >   acpi_pci_osc_support(root, flags);
> >> > >
> >> > > - /*
> >> > > -  * TBD: Need PCI interface for enumeration/configuration of roots.
> >> > > -  */
> >> > > -
> >> > > - /*
> >> > > -  * Scan the Root Bridge
> >> > > -  * --------------------
> >> > > -  * Must do this prior to any attempt to bind the root device, as the
> >> > > -  * PCI namespace does not get created until this call is made (and
> >> > > -  * thus the root bridge's pci_dev does not exist).
> >> > > -  */
> >> > > - root->bus = pci_acpi_scan_root(root);
> >> > > - if (!root->bus) {
> >> > > -         dev_err(&device->dev,
> >> > > -                 "Bus %04x:%02x not present in PCI namespace\n",
> >> > > -                 root->segment, (unsigned int)root->secondary.start);
> >> > > -         result = -ENODEV;
> >> > > -         goto end;
> >> > > - }
> >> > > -
> >> > > - /* Indicate support for various _OSC capabilities. */
> >> > >   if (pci_ext_cfg_avail())
> >> > >           flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
> >> > >   if (pcie_aspm_support_enabled()) {
> >> > > @@ -520,6 +499,26 @@ static int acpi_pci_root_add(struct acpi_device *device,
> >> > >                    "(_OSC support mask: 0x%02x)\n", flags);
> >> > >   }
> >> > >
> >> > > + /*
> >> > > +  * TBD: Need PCI interface for enumeration/configuration of roots.
> >> > > +  */
> >> > > +
> >> > > + /*
> >> > > +  * Scan the Root Bridge
> >> > > +  * --------------------
> >> > > +  * Must do this prior to any attempt to bind the root device, as the
> >> > > +  * PCI namespace does not get created until this call is made (and
> >> > > +  * thus the root bridge's pci_dev does not exist).
> >> > > +  */
> >> > > + root->bus = pci_acpi_scan_root(root);
> >> > > + if (!root->bus) {
> >> > > +         dev_err(&device->dev,
> >> > > +                 "Bus %04x:%02x not present in PCI namespace\n",
> >> > > +                 root->segment, (unsigned int)root->secondary.start);
> >> > > +         result = -ENODEV;
> >> > > +         goto end;
> >> > > + }
> >> > > +
> >> > >   pci_acpi_add_bus_pm_notifier(device, root->bus);
> >> > >   if (device->wakeup.flags.run_wake)
> >> > >           device_set_run_wake(root->bus->bridge, true);
> >> > >
> >>
> > --
> > I speak only for myself.
> > Rafael J. Wysocki, Intel Open Source Technology Center.
Bjorn Helgaas Aug. 23, 2013, 10:04 p.m. UTC | #6
On Fri, Aug 23, 2013 at 3:40 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Friday, August 23, 2013 02:46:23 PM Bjorn Helgaas wrote:
>> On Fri, Aug 23, 2013 at 2:53 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>> > On Friday, August 23, 2013 04:05:11 PM Neil Horman wrote:
>> >> On Fri, Aug 23, 2013 at 09:38:18PM +0200, Rafael J. Wysocki wrote:
>> >> > [CCs added]
>> >> >
>> >> > Please always send PCI-related material to linux-pci in the first place.
>> >> >
>> >> Sorry, I ran get_maintainers and it seemed to think linux-acpi was sufficient.
>> >>
>> >> > The change that broke things for you was actually intentional:
>> >> >
>> >> > commit b8178f130e25c1bdac1c33e0996f1ff6e20ec08e
>> >> > Author: Bjorn Helgaas <bhelgaas@google.com>
>> >> > Date:   Mon Apr 1 15:47:39 2013 -0600
>> >> >
>> >> >     Revert "PCI/ACPI: Request _OSC control before scanning PCI root bus"
>> >> >
>> >> >     This reverts commit 8c33f51df406e1a1f7fa4e9b244845b7ebd61fa6.
>> >> >
>> >> > so I think we'll need to clean up the ASMP initialization after all.
>> >> >
>> >> Crud.  Reading over the revert commit, it seems like the problem boils down to
>> >> the odering of checking aspm_disabled.  It seems to me that the simple fix is to
>> >> track the desire for acpi to disable aspm separately from the users desire to
>> >> disable aspm (aspm_disabled).  Then we just turn the points where we check the
>> >> aspm_disabled into the appropriate or of two variables, except for
>> >> pcie_asmp_sanity_check, which remains sensitive to just the user disable option.
>> >>
>> >> Or is there more to this?
>> >
>> > No, I think you're right.
>> >
>> > Bjorn, what do you think?
>>
>> My opinion is that the _OSC/ASPM state management is ridiculously
>> complicated already, and this would make it slightly more complicated.
>>  That's why my preference would be to attempt a more radical cleanup
>> and simplification instead of adding another wart.
>
> Well, do you have anything specific in mind?

If I had a specific fix in mind, I would just post it, but I've never
had time to work through it all.  What I mean by complicated is that
every time I have to look at ASPM, I have to start by trying to figure
out the relationships between these variables:

    aspm_policy                 # default 0 (POLICY_DEFAULT)
                                  or POLICY_PERFORMANCE
                                  or POLICY_POWERSAVE depending on config
    aspm_disabled               # default 0
    aspm_force                  # default 0
    aspm_support_enabled        # default true

plus the _OSC-related code in acpi_pci_root_add(), which honestly is a
rat's nest.

It sounds like Neil's fix (while probably correct) would tangle that
nest a little more.  But I guess it would make sense to see the actual
patch and the justification (a regression fix, I suppose, but the
details weren't clear to me) before deciding.

>> >> > On Friday, August 23, 2013 01:19:39 PM Neil Horman wrote:
>> >> > > Somewhere between 3.9 and 3.10 it seems the order in which pcie and acpi probed
>> >> > > slots for hotplug capabilites got reversed.  While this isn't a big deal, it did
>> >> > > uncover a bug in the ACPI bus setup path.  Specifically, acpi_pci_root_add calls
>> >> > > pci_acpi_scan_root before setting the osc flags for the device handle.
>> >> > > pci_acpi_scan_root, among other things uses device_is_managed_by_native_pciehp()
>> >> > > to determine if a given slot has pcie hotplug capabilties, whcih checks the
>> >> > > devices OSC_PCI_EXPRESS_NATIVE_HP_CONTROL flag.  Since that flag is not set
>> >> > > until after pci_acpi_scan_root_completes, the acpi code never sees that pcie
>> >> > > slots are hotplug capable and configures them all to use acpi instead.
>> >> > >
>> >> > > Fix is pretty simple, just defer the scan until after the osc flags have been
>> >> > > set on the device.  Tested by myself and it seems to work well.
>> >> > >
>> >> > > Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
>> >> > > CC: Len Brown <lenb@kernel.org>
>> >> > > CC: "Rafael J. Wysocki" <rjw@sisk.pl>
>> >> > > CC: linux-acpi@vger.kernel.org
>> >> > > ---
>> >> > >  drivers/acpi/pci_root.c | 41 ++++++++++++++++++++---------------------
>> >> > >  1 file changed, 20 insertions(+), 21 deletions(-)
>> >> > >
>> >> > > diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
>> >> > > index 5917839..a2c2661 100644
>> >> > > --- a/drivers/acpi/pci_root.c
>> >> > > +++ b/drivers/acpi/pci_root.c
>> >> > > @@ -437,27 +437,6 @@ static int acpi_pci_root_add(struct acpi_device *device,
>> >> > >   flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
>> >> > >   acpi_pci_osc_support(root, flags);
>> >> > >
>> >> > > - /*
>> >> > > -  * TBD: Need PCI interface for enumeration/configuration of roots.
>> >> > > -  */
>> >> > > -
>> >> > > - /*
>> >> > > -  * Scan the Root Bridge
>> >> > > -  * --------------------
>> >> > > -  * Must do this prior to any attempt to bind the root device, as the
>> >> > > -  * PCI namespace does not get created until this call is made (and
>> >> > > -  * thus the root bridge's pci_dev does not exist).
>> >> > > -  */
>> >> > > - root->bus = pci_acpi_scan_root(root);
>> >> > > - if (!root->bus) {
>> >> > > -         dev_err(&device->dev,
>> >> > > -                 "Bus %04x:%02x not present in PCI namespace\n",
>> >> > > -                 root->segment, (unsigned int)root->secondary.start);
>> >> > > -         result = -ENODEV;
>> >> > > -         goto end;
>> >> > > - }
>> >> > > -
>> >> > > - /* Indicate support for various _OSC capabilities. */
>> >> > >   if (pci_ext_cfg_avail())
>> >> > >           flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
>> >> > >   if (pcie_aspm_support_enabled()) {
>> >> > > @@ -520,6 +499,26 @@ static int acpi_pci_root_add(struct acpi_device *device,
>> >> > >                    "(_OSC support mask: 0x%02x)\n", flags);
>> >> > >   }
>> >> > >
>> >> > > + /*
>> >> > > +  * TBD: Need PCI interface for enumeration/configuration of roots.
>> >> > > +  */
>> >> > > +
>> >> > > + /*
>> >> > > +  * Scan the Root Bridge
>> >> > > +  * --------------------
>> >> > > +  * Must do this prior to any attempt to bind the root device, as the
>> >> > > +  * PCI namespace does not get created until this call is made (and
>> >> > > +  * thus the root bridge's pci_dev does not exist).
>> >> > > +  */
>> >> > > + root->bus = pci_acpi_scan_root(root);
>> >> > > + if (!root->bus) {
>> >> > > +         dev_err(&device->dev,
>> >> > > +                 "Bus %04x:%02x not present in PCI namespace\n",
>> >> > > +                 root->segment, (unsigned int)root->secondary.start);
>> >> > > +         result = -ENODEV;
>> >> > > +         goto end;
>> >> > > + }
>> >> > > +
>> >> > >   pci_acpi_add_bus_pm_notifier(device, root->bus);
>> >> > >   if (device->wakeup.flags.run_wake)
>> >> > >           device_set_run_wake(root->bus->bridge, true);
>> >> > >
>> >>
>> > --
>> > I speak only for myself.
>> > Rafael J. Wysocki, Intel Open Source Technology Center.
> --
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Neil Horman Aug. 24, 2013, 1:57 a.m. UTC | #7
On Fri, Aug 23, 2013 at 04:04:59PM -0600, Bjorn Helgaas wrote:
> On Fri, Aug 23, 2013 at 3:40 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Friday, August 23, 2013 02:46:23 PM Bjorn Helgaas wrote:
> >> On Fri, Aug 23, 2013 at 2:53 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> >> > On Friday, August 23, 2013 04:05:11 PM Neil Horman wrote:
> >> >> On Fri, Aug 23, 2013 at 09:38:18PM +0200, Rafael J. Wysocki wrote:
> >> >> > [CCs added]
> >> >> >
> >> >> > Please always send PCI-related material to linux-pci in the first place.
> >> >> >
> >> >> Sorry, I ran get_maintainers and it seemed to think linux-acpi was sufficient.
> >> >>
> >> >> > The change that broke things for you was actually intentional:
> >> >> >
> >> >> > commit b8178f130e25c1bdac1c33e0996f1ff6e20ec08e
> >> >> > Author: Bjorn Helgaas <bhelgaas@google.com>
> >> >> > Date:   Mon Apr 1 15:47:39 2013 -0600
> >> >> >
> >> >> >     Revert "PCI/ACPI: Request _OSC control before scanning PCI root bus"
> >> >> >
> >> >> >     This reverts commit 8c33f51df406e1a1f7fa4e9b244845b7ebd61fa6.
> >> >> >
> >> >> > so I think we'll need to clean up the ASMP initialization after all.
> >> >> >
> >> >> Crud.  Reading over the revert commit, it seems like the problem boils down to
> >> >> the odering of checking aspm_disabled.  It seems to me that the simple fix is to
> >> >> track the desire for acpi to disable aspm separately from the users desire to
> >> >> disable aspm (aspm_disabled).  Then we just turn the points where we check the
> >> >> aspm_disabled into the appropriate or of two variables, except for
> >> >> pcie_asmp_sanity_check, which remains sensitive to just the user disable option.
> >> >>
> >> >> Or is there more to this?
> >> >
> >> > No, I think you're right.
> >> >
> >> > Bjorn, what do you think?
> >>
> >> My opinion is that the _OSC/ASPM state management is ridiculously
> >> complicated already, and this would make it slightly more complicated.
> >>  That's why my preference would be to attempt a more radical cleanup
> >> and simplification instead of adding another wart.
> >
> > Well, do you have anything specific in mind?
> 
> If I had a specific fix in mind, I would just post it, but I've never
> had time to work through it all.  What I mean by complicated is that
> every time I have to look at ASPM, I have to start by trying to figure
> out the relationships between these variables:
> 
>     aspm_policy                 # default 0 (POLICY_DEFAULT)
>                                   or POLICY_PERFORMANCE
>                                   or POLICY_POWERSAVE depending on config
>     aspm_disabled               # default 0
>     aspm_force                  # default 0
>     aspm_support_enabled        # default true
> 
> plus the _OSC-related code in acpi_pci_root_add(), which honestly is a
> rat's nest.
> 
I agree, I've only looked at it for an hour, and it looks pretty hairy.

> It sounds like Neil's fix (while probably correct) would tangle that
> nest a little more.  But I guess it would make sense to see the actual
No argument, it would add complexity to something thats already very complex.
That said, I think this needs to be fixed.  Currently there are several systems
that are reporting conflicts between ACPI and PCIE hotplug.  While that means
theres lots of griping, theres several people willing to test, so I think we
have an opportunity to fix this.

> patch and the justification (a regression fix, I suppose, but the
> details weren't clear to me) before deciding.
> 
Agreed.  A larger cleanup would be preferable at this point, but I'm not
sufficiently versed in the code to do that right now, so I'll try write an
appropriate for this particular bug, and see what you think on monday.


Regards
Neil

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 5917839..a2c2661 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -437,27 +437,6 @@  static int acpi_pci_root_add(struct acpi_device *device,
 	flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
 	acpi_pci_osc_support(root, flags);
 
-	/*
-	 * TBD: Need PCI interface for enumeration/configuration of roots.
-	 */
-
-	/*
-	 * Scan the Root Bridge
-	 * --------------------
-	 * Must do this prior to any attempt to bind the root device, as the
-	 * PCI namespace does not get created until this call is made (and
-	 * thus the root bridge's pci_dev does not exist).
-	 */
-	root->bus = pci_acpi_scan_root(root);
-	if (!root->bus) {
-		dev_err(&device->dev,
-			"Bus %04x:%02x not present in PCI namespace\n",
-			root->segment, (unsigned int)root->secondary.start);
-		result = -ENODEV;
-		goto end;
-	}
-
-	/* Indicate support for various _OSC capabilities. */
 	if (pci_ext_cfg_avail())
 		flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
 	if (pcie_aspm_support_enabled()) {
@@ -520,6 +499,26 @@  static int acpi_pci_root_add(struct acpi_device *device,
 			 "(_OSC support mask: 0x%02x)\n", flags);
 	}
 
+	/*
+	 * TBD: Need PCI interface for enumeration/configuration of roots.
+	 */
+
+	/*
+	 * Scan the Root Bridge
+	 * --------------------
+	 * Must do this prior to any attempt to bind the root device, as the
+	 * PCI namespace does not get created until this call is made (and
+	 * thus the root bridge's pci_dev does not exist).
+	 */
+	root->bus = pci_acpi_scan_root(root);
+	if (!root->bus) {
+		dev_err(&device->dev,
+			"Bus %04x:%02x not present in PCI namespace\n",
+			root->segment, (unsigned int)root->secondary.start);
+		result = -ENODEV;
+		goto end;
+	}
+
 	pci_acpi_add_bus_pm_notifier(device, root->bus);
 	if (device->wakeup.flags.run_wake)
 		device_set_run_wake(root->bus->bridge, true);