2022-03-21 22:24:02

by Marc Zyngier

[permalink] [raw]
Subject: [PATCH v2 0/2] PCI: xgene: Restore working PCIe functionnality

Since 6dce5aa59e0b ("PCI: xgene: Use inbound resources for setup") was
merged in the 5.5 time frame, PCIe on the venerable XGene platform has
been unusable: 6dce5aa59e0b broke both XGene-1 (Mustang and m400) and
XGene-2 (Merlin), while the addition of c7a75d07827a ("PCI: xgene: Fix
IB window setup") fixed XGene-2, but left the rest of the zoo
unusable.

It is understood that this systems come with "creative" DTs that don't
match the expectations of modern kernels. However, there is little to
be gained by forcing these changes on users -- the firmware is not
upgradable, and the current owner of the IP will deny that these
machines have ever existed.

Given that, revert both changes and let people enjoy their XGene boxes
once again.

* From v1 [1]:
- Also revert c7a75d07827a ("PCI: xgene: Fix IB window setup")

[1] https://lore.kernel.org/r/[email protected]

Marc Zyngier (2):
PCI: xgene: Revert "PCI: xgene: Use inbound resources for setup"
PCI: xgene: Revert "PCI: xgene: Fix IB window setup"

drivers/pci/controller/pci-xgene.c | 35 ++++++++++++++++++++----------
1 file changed, 23 insertions(+), 12 deletions(-)

--
2.34.1


2022-03-21 22:32:49

by Lorenzo Pieralisi

[permalink] [raw]
Subject: Re: [PATCH v2 0/2] PCI: xgene: Restore working PCIe functionnality

On Mon, 21 Mar 2022 10:48:41 +0000, Marc Zyngier wrote:
> Since 6dce5aa59e0b ("PCI: xgene: Use inbound resources for setup") was
> merged in the 5.5 time frame, PCIe on the venerable XGene platform has
> been unusable: 6dce5aa59e0b broke both XGene-1 (Mustang and m400) and
> XGene-2 (Merlin), while the addition of c7a75d07827a ("PCI: xgene: Fix
> IB window setup") fixed XGene-2, but left the rest of the zoo
> unusable.
>
> [...]

Applied to pci/xgene, thanks!

[1/2] PCI: xgene: Revert "PCI: xgene: Use inbound resources for setup"
https://git.kernel.org/lpieralisi/pci/c/1874b6d7ab
[2/2] PCI: xgene: Revert "PCI: xgene: Fix IB window setup"
https://git.kernel.org/lpieralisi/pci/c/825da4e9ce

Thanks,
Lorenzo

2022-03-21 22:34:49

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH v2 0/2] PCI: xgene: Restore working PCIe functionnality

On Mon, Mar 21, 2022 at 5:49 AM Marc Zyngier <[email protected]> wrote:
>
> Since 6dce5aa59e0b ("PCI: xgene: Use inbound resources for setup") was
> merged in the 5.5 time frame, PCIe on the venerable XGene platform has
> been unusable: 6dce5aa59e0b broke both XGene-1 (Mustang and m400) and
> XGene-2 (Merlin), while the addition of c7a75d07827a ("PCI: xgene: Fix
> IB window setup") fixed XGene-2, but left the rest of the zoo
> unusable.
>
> It is understood that this systems come with "creative" DTs that don't
> match the expectations of modern kernels. However, there is little to
> be gained by forcing these changes on users -- the firmware is not
> upgradable, and the current owner of the IP will deny that these
> machines have ever existed.

The gain for fixing this properly is not having drivers do their own
dma-ranges parsing. We've seen what happens when drivers do their own
parsing of standard properties (e.g. interrupt-map). Currently, we
don't have any drivers doing their own parsing:

$ git grep of_pci_dma_range_parser_init
drivers/of/address.c:int of_pci_dma_range_parser_init(struct
of_pci_range_parser *parser,
drivers/of/address.c:EXPORT_SYMBOL_GPL(of_pci_dma_range_parser_init);
drivers/of/address.c:#define of_dma_range_parser_init
of_pci_dma_range_parser_init
drivers/of/unittest.c: if (of_pci_dma_range_parser_init(&parser, np)) {
drivers/pci/of.c: err = of_pci_dma_range_parser_init(&parser, dev_node);
include/linux/of_address.h:extern int
of_pci_dma_range_parser_init(struct of_pci_range_parser *parser,
include/linux/of_address.h:static inline int
of_pci_dma_range_parser_init(struct of_pci_range_parser *parser,

And we can probably further refactor this to be private to drivers/pci/of.c.

For XGene-2 the issue is simply that the driver depends on the order
of dma-ranges entries.

For XGene-1, I'd still like to understand what the issue is. Reverting
the first fix and fixing 'dma-ranges' should have fixed it. I need a
dump of how the IB registers are initialized in both cases. I'm not
saying changing 'dma-ranges' in the firmware is going to be required
here. There's a couple of other ways we could fix that without a
firmware change, but first I need to understand why it broke.

Rob

P.S. We're carrying ACPI and DT support for these platforms. It seems
the few users are using DT, so can we drop the ACPI support? Or do I
need to break it first and wait a year? ;)

2022-03-21 22:36:07

by Marc Zyngier

[permalink] [raw]
Subject: [PATCH v2 1/2] PCI: xgene: Revert "PCI: xgene: Use inbound resources for setup"

Commit 6dce5aa59e0b ("PCI: xgene: Use inbound resources for setup")
killed PCIe on my XGene-1 box (a Mustang board). The machine itself
is still alive, but half of its storage (over NVMe) is gone, and the
NVMe driver just times out.

Note that this machine boots with a device tree provided by the
UEFI firmware (2016 vintage), which could well be non conformant
with the spec, hence the breakage.

With the patch reverted, the box boots 5.17-rc8 with flying colors.

Cc: Rob Herring <[email protected]>
Cc: Toan Le <[email protected]>
Cc: Lorenzo Pieralisi <[email protected]>
Cc: Krzysztof Wilczyński <[email protected]>
Cc: Bjorn Helgaas <[email protected]>
Cc: Stéphane Graber <[email protected]>
Cc: dann frazier <[email protected]>
Cc: [email protected]
Signed-off-by: Marc Zyngier <[email protected]>
Fixes: 6dce5aa59e0b ("PCI: xgene: Use inbound resources for setup")
Link: https://lore.kernel.org/all/[email protected]
---
drivers/pci/controller/pci-xgene.c | 33 ++++++++++++++++++++----------
1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/drivers/pci/controller/pci-xgene.c b/drivers/pci/controller/pci-xgene.c
index 0d5acbfc7143..aa41ceaf031f 100644
--- a/drivers/pci/controller/pci-xgene.c
+++ b/drivers/pci/controller/pci-xgene.c
@@ -479,28 +479,27 @@ static int xgene_pcie_select_ib_reg(u8 *ib_reg_mask, u64 size)
}

static void xgene_pcie_setup_ib_reg(struct xgene_pcie *port,
- struct resource_entry *entry,
- u8 *ib_reg_mask)
+ struct of_pci_range *range, u8 *ib_reg_mask)
{
void __iomem *cfg_base = port->cfg_base;
struct device *dev = port->dev;
void __iomem *bar_addr;
u32 pim_reg;
- u64 cpu_addr = entry->res->start;
- u64 pci_addr = cpu_addr - entry->offset;
- u64 size = resource_size(entry->res);
+ u64 cpu_addr = range->cpu_addr;
+ u64 pci_addr = range->pci_addr;
+ u64 size = range->size;
u64 mask = ~(size - 1) | EN_REG;
u32 flags = PCI_BASE_ADDRESS_MEM_TYPE_64;
u32 bar_low;
int region;

- region = xgene_pcie_select_ib_reg(ib_reg_mask, size);
+ region = xgene_pcie_select_ib_reg(ib_reg_mask, range->size);
if (region < 0) {
dev_warn(dev, "invalid pcie dma-range config\n");
return;
}

- if (entry->res->flags & IORESOURCE_PREFETCH)
+ if (range->flags & IORESOURCE_PREFETCH)
flags |= PCI_BASE_ADDRESS_MEM_PREFETCH;

bar_low = pcie_bar_low_val((u32)cpu_addr, flags);
@@ -531,13 +530,25 @@ static void xgene_pcie_setup_ib_reg(struct xgene_pcie *port,

static int xgene_pcie_parse_map_dma_ranges(struct xgene_pcie *port)
{
- struct pci_host_bridge *bridge = pci_host_bridge_from_priv(port);
- struct resource_entry *entry;
+ struct device_node *np = port->node;
+ struct of_pci_range range;
+ struct of_pci_range_parser parser;
+ struct device *dev = port->dev;
u8 ib_reg_mask = 0;

- resource_list_for_each_entry(entry, &bridge->dma_ranges)
- xgene_pcie_setup_ib_reg(port, entry, &ib_reg_mask);
+ if (of_pci_dma_range_parser_init(&parser, np)) {
+ dev_err(dev, "missing dma-ranges property\n");
+ return -EINVAL;
+ }
+
+ /* Get the dma-ranges from DT */
+ for_each_of_pci_range(&parser, &range) {
+ u64 end = range.cpu_addr + range.size - 1;

+ dev_dbg(dev, "0x%08x 0x%016llx..0x%016llx -> 0x%016llx\n",
+ range.flags, range.cpu_addr, end, range.pci_addr);
+ xgene_pcie_setup_ib_reg(port, &range, &ib_reg_mask);
+ }
return 0;
}

--
2.34.1

2022-03-22 16:37:11

by Robin Murphy

[permalink] [raw]
Subject: Re: [PATCH v2 0/2] PCI: xgene: Restore working PCIe functionnality

On 2022-03-22 14:39, Rob Herring wrote:
> On Tue, Mar 22, 2022 at 01:16:35PM +0000, Robin Murphy wrote:
>> On 2022-03-21 20:06, Robin Murphy wrote:
>>> On 2022-03-21 19:21, Marc Zyngier wrote:
>>>> On Mon, 21 Mar 2022 18:03:27 +0000,
>>>> Rob Herring <[email protected]> wrote:
>>>>>
>>>>> On Mon, Mar 21, 2022 at 11:36 AM Marc Zyngier <[email protected]> wrote:
>>>>>>
>>>>>> On Mon, 21 Mar 2022 15:17:34 +0000,
>>>>>> Rob Herring <[email protected]> wrote:
>>>>>>>
>>>>>>> On Mon, Mar 21, 2022 at 5:49 AM Marc Zyngier <[email protected]> wrote:
>>>>>>>>
>>>>>>> For XGene-1, I'd still like to understand what the issue is. Reverting
>>>>>>> the first fix and fixing 'dma-ranges' should have fixed it. I need a
>>>>>>> dump of how the IB registers are initialized in both cases. I'm not
>>>>>>> saying changing 'dma-ranges' in the firmware is going to be required
>>>>>>> here. There's a couple of other ways we could fix that without a
>>>>>>> firmware change, but first I need to understand why it broke.
>>>>>>
>>>>>> Reverting 6dce5aa59e0b was enough for me, without changing anything
>>>>>> else.
>>>>>
>>>>> Meaning c7a75d07827a didn't matter for you. I'm not sure that it would.
>>>>>
>>>>> Can you tell me what 'dma-ranges' contains on your system?
>>>>
>>>> Each pcie node (all 5 of them) has:
>>>>
>>>> dma-ranges = <0x42000000 0x80 0x00 0x80 0x00 0x00 0x80000000
>>>> �������������� 0x42000000 0x00 0x00 0x00 0x00 0x80 0x00>;
>
> This is the same as what St�phane has for Merlin. So c7a75d07827a ("PCI:
> xgene: Fix IB window setup") should have fixed Mustang.

Unless XGene 1 has some weird implicit requirement on the order in which
the registers are programmed, that XGene 2 doesn't. And from looking at
the code, I don't see any obvious less-mad possibility to explain the
breakage.

>>> Hmm, is there anyone other than iommu-dma who actually depends on the
>>> resource list being sorted in ascending order of bus address? I recall
>>> at the time I pushed for creating the list in sorted order as it was the
>>> simplest and most efficient option, but there's no technical reason we
>>> couldn't create it in as-found order and defer the sorting until
>>> iova_reserve_pci_windows() (at worst that could even operate on a
>>> temporary copy if need be). It's just more code, which didn't need to
>>> exist without a good reason, but if this is one then exist it certainly
>>> may.
>>
>> Taking a closer look, the Cadence driver is already re-sorting the list
>> for its own setup, so iommu-dma can't assume the initial sort is
>> preserved and needs to do its own anyway. Does the (untested) diff below
>> end up helping X-Gene also?
>
> There's no IOMMU on X-Gene 1 or 2 based on the upstream dts files, so
> how would this matter?

Because devm_of_pci_get_host_bridge_resources() is forcing the
dma_ranges list to be in a different order from the original DT for
iommu-dma's benefit, but whether iommu-dma actually consumes it or not
later is immaterial.

Robin.

2022-03-22 17:53:54

by Marc Zyngier

[permalink] [raw]
Subject: Re: [PATCH v2 0/2] PCI: xgene: Restore working PCIe functionnality

On Tue, 22 Mar 2022 14:39:43 +0000,
Rob Herring <[email protected]> wrote:
>
> On Tue, Mar 22, 2022 at 01:16:35PM +0000, Robin Murphy wrote:
> > On 2022-03-21 20:06, Robin Murphy wrote:
> > > On 2022-03-21 19:21, Marc Zyngier wrote:
> > > > On Mon, 21 Mar 2022 18:03:27 +0000,
> > > > Rob Herring <[email protected]> wrote:
> > > > >
> > > > > On Mon, Mar 21, 2022 at 11:36 AM Marc Zyngier <[email protected]> wrote:
> > > > > >
> > > > > > On Mon, 21 Mar 2022 15:17:34 +0000,
> > > > > > Rob Herring <[email protected]> wrote:
> > > > > > >
> > > > > > > On Mon, Mar 21, 2022 at 5:49 AM Marc Zyngier <[email protected]> wrote:
> > > > > > > >
> > > > > > > For XGene-1, I'd still like to understand what the issue is. Reverting
> > > > > > > the first fix and fixing 'dma-ranges' should have fixed it. I need a
> > > > > > > dump of how the IB registers are initialized in both cases. I'm not
> > > > > > > saying changing 'dma-ranges' in the firmware is going to be required
> > > > > > > here. There's a couple of other ways we could fix that without a
> > > > > > > firmware change, but first I need to understand why it broke.
> > > > > >
> > > > > > Reverting 6dce5aa59e0b was enough for me, without changing anything
> > > > > > else.
> > > > >
> > > > > Meaning c7a75d07827a didn't matter for you. I'm not sure that it would.
> > > > >
> > > > > Can you tell me what 'dma-ranges' contains on your system?
> > > >
> > > > Each pcie node (all 5 of them) has:
> > > >
> > > > dma-ranges = <0x42000000 0x80 0x00 0x80 0x00 0x00 0x80000000
> > > >                0x42000000 0x00 0x00 0x00 0x00 0x80 0x00>;
>
> This is the same as what Stéphane has for Merlin. So c7a75d07827a ("PCI:
> xgene: Fix IB window setup") should have fixed Mustang.

Should, but didn't. The DT also carries additional properties:

ib-ranges = <0x42000000 0x40 0x00 0x40 0x00 0x40 0x00
0x00 0x00 0x79000000 0x00 0x79000000 0x00 0x800000>;

which the driver ignores, but that could be relevant. FWIW, I've
stashed the DT at [1].

M.

[1] http://www.loen.fr/tmp/mustang.dts

--
Without deviation from the norm, progress is not possible.

2022-03-23 09:22:02

by dann frazier

[permalink] [raw]
Subject: Re: [PATCH v2 0/2] PCI: xgene: Restore working PCIe functionnality

On Tue, Mar 22, 2022 at 04:00:22PM -0500, Rob Herring wrote:
> On Mon, Mar 21, 2022 at 04:32:40PM -0600, dann frazier wrote:
> > On Mon, Mar 21, 2022 at 11:08:20AM -0500, Rob Herring wrote:
> > > On Mon, Mar 21, 2022 at 09:50:24AM -0600, dann frazier wrote:
> > > > On Mon, Mar 21, 2022 at 10:17:34AM -0500, Rob Herring wrote:
> > > > > On Mon, Mar 21, 2022 at 5:49 AM Marc Zyngier <[email protected]> wrote:
> > > > > >
> > > > > > Since 6dce5aa59e0b ("PCI: xgene: Use inbound resources for setup") was
> > > > > > merged in the 5.5 time frame, PCIe on the venerable XGene platform has
> > > > > > been unusable: 6dce5aa59e0b broke both XGene-1 (Mustang and m400) and
> > > > > > XGene-2 (Merlin), while the addition of c7a75d07827a ("PCI: xgene: Fix
> > > > > > IB window setup") fixed XGene-2, but left the rest of the zoo
> > > > > > unusable.
> > > > > >
> > > > > > It is understood that this systems come with "creative" DTs that don't
> > > > > > match the expectations of modern kernels. However, there is little to
> > > > > > be gained by forcing these changes on users -- the firmware is not
> > > > > > upgradable, and the current owner of the IP will deny that these
> > > > > > machines have ever existed.
> > > > >
> > > > > The gain for fixing this properly is not having drivers do their own
> > > > > dma-ranges parsing. We've seen what happens when drivers do their own
> > > > > parsing of standard properties (e.g. interrupt-map). Currently, we
> > > > > don't have any drivers doing their own parsing:
> > > > >
> > > > > $ git grep of_pci_dma_range_parser_init
> > > > > drivers/of/address.c:int of_pci_dma_range_parser_init(struct
> > > > > of_pci_range_parser *parser,
> > > > > drivers/of/address.c:EXPORT_SYMBOL_GPL(of_pci_dma_range_parser_init);
> > > > > drivers/of/address.c:#define of_dma_range_parser_init
> > > > > of_pci_dma_range_parser_init
> > > > > drivers/of/unittest.c: if (of_pci_dma_range_parser_init(&parser, np)) {
> > > > > drivers/pci/of.c: err = of_pci_dma_range_parser_init(&parser, dev_node);
> > > > > include/linux/of_address.h:extern int
> > > > > of_pci_dma_range_parser_init(struct of_pci_range_parser *parser,
> > > > > include/linux/of_address.h:static inline int
> > > > > of_pci_dma_range_parser_init(struct of_pci_range_parser *parser,
> > > > >
> > > > > And we can probably further refactor this to be private to drivers/pci/of.c.
> > > > >
> > > > > For XGene-2 the issue is simply that the driver depends on the order
> > > > > of dma-ranges entries.
> > > > >
> > > > > For XGene-1, I'd still like to understand what the issue is. Reverting
> > > > > the first fix and fixing 'dma-ranges' should have fixed it. I need a
> > > > > dump of how the IB registers are initialized in both cases.
> > > >
> > > > Happy to provide that for the m400 if told how :)
> > >
> > > Something like the below patch. This should be with the 'dma-ranges'
> > > DT change and only c7a75d07827a reverted.
> >
> > https://paste.ubuntu.com/p/RHzBd5jT6v/
> >
> > Note that networking does come up with this setup. That surprised me
> > because I thought I'd tested this combo before, but apparently what
> > I'd tested before was 6dce5aa59e0b reverted + the dtb change:
> > https://lore.kernel.org/linux-pci/[email protected]/
>
> That doesn't make sense. I just noticed there's an error in what I
> told you to do for dma-ranges. I fixed the wrong cell as it should be:
>
> - dma-ranges = <0x42000000 0x40 0x00 0x40 0x00 0x40 0x00 0x00 0x00 0x79000000 0x00 0x79000000 0x00 0x800000>;
> + dma-ranges = <0x42000000 0x40 0x00 0x40 0x00 0x40 0x00 0x42000000 0x00 0x79000000 0x00 0x79000000 0x00 0x800000>;

OK, thanks Rob. Here's an updated log:

https://paste.ubuntu.com/p/FmSTbM6Zq3/

-dann