From: Jiang Liu <jiang.liu@linux.intel.com>
To: "Rafael J. Wysocki" <rjw@rjwysocki.net>,
Bjorn Helgaas <bhelgaas@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
x86@kernel.org, Len Brown <lenb@kernel.org>,
Lv Zheng <lv.zheng@intel.com>,
LKML <linux-kernel@vger.kernel.org>,
linux-pci@vger.kernel.org, linux-acpi@vger.kernel.org
Subject: Re: [Bugfix v3] x86/PCI/ACPI: Fix regression caused by commit 63f1789ec716
Date: Wed, 08 Apr 2015 13:48:46 +0800 [thread overview]
Message-ID: <5524C13E.3060101@linux.intel.com> (raw)
In-Reply-To: <1832914.AK2bZGkVxq@vostro.rjw.lan>
On 2015/4/7 8:28, Rafael J. Wysocki wrote:
> On Friday, April 03, 2015 10:04:11 PM Bjorn Helgaas wrote:
>> Hi Jiang,
<snip>
>>> Currently acpi_dev_filter_resource_type() is only used by ACPI pci
>>> host bridge and IOAPIC driver, so it shouldn't affect other drivers.
>>
>> We should assume it will eventually be used for all ACPI devices,
>> shouldn't we?
>
> I'm not sure about that, really. In fact, I'd restrict its use to devices
> types that actually can "produce" resources (ie. do not require the resources
> to be provided by their ancestors or to be available from a global pool).
>
> Otherwise we're pretty much guaranteed to get into trouble.
>
> And all of the above rules need to be documented in the kernel source tree
> or people will get confused.
Hi Rafael,
How about following comments for acpi_dev_filter_resource_type()?
Thanks!
Gerry
--------------------------------------------------------------------
/**
* According to ACPI specifications, Consumer/Producer flag in ACPI resource
* descriptor means:
* 1(CONSUMER): This device consumes this resource
* 0(PRODUCER): This device produces and consumes this resource
* But for ACPI PCI host bridge, it is interpreted in another way:
* 1(CONSUMER): PCI host bridge itself consumes the resource, such as
* IOPORT 0xCF8-0xCFF to access PCI configuraiton space.
* 0(PRODUCER): PCI host bridge provides this resource to its child
* bus and devices.
*
* So this is a specially designed helper function to support ACPI PCI host
* bridge and ACPI IOAPIC, and its usage should be limited to those specific
* scenarioso only. It filters ACPI resource descriptors as below:
* 1) If flag IORESOURCE_WINDOW is not specified, it's querying resources
* consumed by device. That is to return:
* a) ACPI resources without producer_consumer flag
* b) ACPI resources with producer_consumer flag setting to CONSUMER.
* 2) If flag IORESOURCE_WINDOW is specified, it's querying resources
provided
* by device. That is to return:
* a) ACPI resources with producer_consumer flag setting to PRODUCER.
* 3) But there's an exception. Some platforms, such as PC Engines APU.1C,
* report PCI host bridge resource provision by Memory32Fixed().
* Please refer to https://bugzilla.kernel.org/show_bug.cgi?id=94221
* So a special flag IORESOURCE_MEM_8AND16BIT is used to work around this
* BIOS issue.
*/
>
>>> Another possible fix is to only ignore IO resource consumed by host
>>> bridge and keep IOMEM resource consumed by host bridge, please refer to:
>>> http://www.spinics.net/lists/linux-pci/msg39706.html
>>>
>>> Sample ACPI table are archived at:
>>> https://bugzilla.kernel.org/show_bug.cgi?id=94221
>>>
>>> V2->V3:
>>> Refine function acpi_dev_match_producer_consumer() as suggested by Rafael
>>>
>>> Fixes: 63f1789ec716("Ignore resources consumed by host bridge itself")
>>> Reported-and-Tested-by: Bernhard Thaler <bernhard.thaler@wvnet.at>
>>> Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
>>> ---
>>> arch/x86/pci/acpi.c | 5 ++---
>>> drivers/acpi/resource.c | 33 +++++++++++++++++++++++++++++----
>>> 2 files changed, 31 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
>>> index e4695985f9de..8c4b1201f340 100644
>>> --- a/arch/x86/pci/acpi.c
>>> +++ b/arch/x86/pci/acpi.c
>>> @@ -337,7 +337,7 @@ static void probe_pci_root_info(struct pci_root_info *info,
>>> info->bridge = device;
>>> ret = acpi_dev_get_resources(device, list,
>>> acpi_dev_filter_resource_type_cb,
>>> - (void *)(IORESOURCE_IO | IORESOURCE_MEM));
>>> + (void *)(IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_WINDOW));
>>> if (ret < 0)
>>> dev_warn(&device->dev,
>>> "failed to parse _CRS method, error code %d\n", ret);
>>> @@ -346,8 +346,7 @@ static void probe_pci_root_info(struct pci_root_info *info,
>>> "no IO and memory resources present in _CRS\n");
>>> else
>>> resource_list_for_each_entry_safe(entry, tmp, list) {
>>> - if ((entry->res->flags & IORESOURCE_WINDOW) == 0 ||
>>> - (entry->res->flags & IORESOURCE_DISABLED))
>>> + if (entry->res->flags & IORESOURCE_DISABLED)
>>> resource_list_destroy_entry(entry);
>>> else
>>> entry->res->name = info->name;
>>> diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
>>> index 5589a6e2a023..e761a868bdba 100644
>>> --- a/drivers/acpi/resource.c
>>> +++ b/drivers/acpi/resource.c
>>> @@ -567,6 +567,12 @@ int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
>>> }
>>> EXPORT_SYMBOL_GPL(acpi_dev_get_resources);
>>>
>>> +static bool acpi_dev_match_producer_consumer(unsigned long types, int producer)
>>> +{
>>> + return ((types & IORESOURCE_WINDOW) && producer == ACPI_PRODUCER) ||
>>> + ((types & IORESOURCE_WINDOW) == 0 && producer == ACPI_CONSUMER);
>>> +}
>>> +
>>> /**
>>> * acpi_dev_filter_resource_type - Filter ACPI resource according to resource
>>> * types
>>> @@ -585,27 +591,46 @@ int acpi_dev_filter_resource_type(struct acpi_resource *ares,
>>> case ACPI_RESOURCE_TYPE_MEMORY24:
>>> case ACPI_RESOURCE_TYPE_MEMORY32:
>>> case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
>>> + /*
>>> + * These types of resource descriptor should be used to
>>> + * describe resource consumption instead of resource provision.
>>> + * But some platforms, such as PC Engines APU.1C, reports
>>> + * resource provision by Memory32Fixed(). Please refer to:
>>> + * https://bugzilla.kernel.org/show_bug.cgi?id=94221
>>> + * So accept it no matter IORESOURCE_WINDOW is specified or not.
>>> + */
>>> type = IORESOURCE_MEM;
>>
>> I think this means these resources will be accepted regardless of whether
>> the caller is looking for Consumer or Producer resources. To preserve the
>> behavior I added with 66528fdd45b0, we might be forced to do that for PCI
>> host bridges (or maybe we could just add a quirk for the PC Engines BIOS).
>>
>> But I don't think it matches the ACPI spec intent, so I'm not sure it's
>> right to do it for all devices.
>
> No, it isn't, which is why acpi_dev_filter_resource_type() should not be used
> for all devices.
>
>>> break;
>>> case ACPI_RESOURCE_TYPE_IO:
>>> case ACPI_RESOURCE_TYPE_FIXED_IO:
>>> - type = IORESOURCE_IO;
>>> + if (acpi_dev_match_producer_consumer(types, ACPI_CONSUMER))
>>> + type = IORESOURCE_IO;
>>> break;
>>> case ACPI_RESOURCE_TYPE_IRQ:
>>> + if (acpi_dev_match_producer_consumer(types, ACPI_CONSUMER))
>>> + type = IORESOURCE_IRQ;
>>> + break;
>>> case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
>>> - type = IORESOURCE_IRQ;
>>> + if (acpi_dev_match_producer_consumer(types,
>>> + ares->data.extended_irq.producer_consumer))
>>> + type = IORESOURCE_IRQ;
>>> break;
>>> case ACPI_RESOURCE_TYPE_DMA:
>>> case ACPI_RESOURCE_TYPE_FIXED_DMA:
>>> - type = IORESOURCE_DMA;
>>> + if (acpi_dev_match_producer_consumer(types, ACPI_CONSUMER))
>>> + type = IORESOURCE_DMA;
>>> break;
>>> case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
>>> - type = IORESOURCE_REG;
>>> + if (acpi_dev_match_producer_consumer(types, ACPI_CONSUMER))
>>> + type = IORESOURCE_REG;
>>> break;
>>> case ACPI_RESOURCE_TYPE_ADDRESS16:
>>> case ACPI_RESOURCE_TYPE_ADDRESS32:
>>> case ACPI_RESOURCE_TYPE_ADDRESS64:
>>> case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
>>> + if (!acpi_dev_match_producer_consumer(types,
>>> + ares->data.address.producer_consumer))
>>> + break;
>>> if (ares->data.address.resource_type == ACPI_MEMORY_RANGE)
>>> type = IORESOURCE_MEM;
>>> else if (ares->data.address.resource_type == ACPI_IO_RANGE)
>> --
>> 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
>
next prev parent reply other threads:[~2015-04-08 5:48 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-03-30 2:40 [Bugfix v3] x86/PCI/ACPI: Fix regression caused by commit 63f1789ec716 Jiang Liu
2015-04-03 11:49 ` Rafael J. Wysocki
2015-04-04 3:04 ` Bjorn Helgaas
2015-04-07 0:28 ` Rafael J. Wysocki
2015-04-07 13:30 ` Jiang Liu
2015-04-08 5:48 ` Jiang Liu [this message]
2015-04-08 23:44 ` Rafael J. Wysocki
2015-04-09 2:50 ` Jiang Liu
2015-04-09 21:37 ` Rafael J. Wysocki
2015-04-09 22:00 ` Bjorn Helgaas
2015-04-09 22:37 ` Rafael J. Wysocki
2015-04-10 0:28 ` Rafael J. Wysocki
2015-04-13 4:31 ` Jiang Liu
2015-04-13 6:38 ` [Bugfix v5] " Jiang Liu
2015-04-13 6:56 ` Ingo Molnar
2015-04-13 12:05 ` Rafael J. Wysocki
2015-04-13 12:04 ` [Bugfix v3] " Rafael J. Wysocki
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=5524C13E.3060101@linux.intel.com \
--to=jiang.liu@linux.intel.com \
--cc=bhelgaas@google.com \
--cc=hpa@zytor.com \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lv.zheng@intel.com \
--cc=mingo@redhat.com \
--cc=rjw@rjwysocki.net \
--cc=tglx@linutronix.de \
--cc=x86@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.