[PATCH kernel] powerpc/npu: Do not try invalidating 32bit table when 64bit table is enabled
Alexey Kardashevskiy
aik at ozlabs.ru
Wed Mar 7 14:40:36 AEDT 2018
On 13/02/18 16:51, Alexey Kardashevskiy wrote:
> GPUs and the corresponding NVLink bridges get different PEs as they have
> separate translation validation entries (TVEs). We put these PEs to
> the same IOMMU group so they cannot be passed through separately.
> So the iommu_table_group_ops::set_window/unset_window for GPUs do set
> tables to the NPU PEs as well which means that iommu_table's list of
> attached PEs (iommu_table_group_link) has both GPU and NPU PEs linked.
> This list is used for TCE cache invalidation.
>
> The problem is that NPU PE has just a single TVE and can be programmed
> to point to 32bit or 64bit windows while GPU PE has two (as any other PCI
> device). So we end up having an 32bit iommu_table struct linked to both
> PEs even though only the 64bit TCE table cache can be invalidated on NPU.
> And a relatively recent skiboot detects this and prints errors.
>
> This changes GPU's iommu_table_group_ops::set_window/unset_window to make
> sure that NPU PE is only linked to the table actually used by the hardware.
> If there are two tables used by an IOMMU group, the NPU PE will use
> the last programmed one which with the current use scenarios is expected
> to be a 64bit one.
>
> Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
> --
>
> Do we need BUG_ON(IOMMU_TABLE_GROUP_MAX_TABLES != 2)?
Ping?
>
>
> This is an example for:
>
> 0004:04:00.0 3D: NVIDIA Corporation Device 1db1 (rev a1)
> 0006:00:00.0 Bridge: IBM Device 04ea (rev 01)
> 0006:00:00.1 Bridge: IBM Device 04ea (rev 01)
>
> Before the patch (npu2_tce_kill messages are from skiboot):
>
> pci 0004:04 : [PE# 00] Setting up window#0 0..3fffffff pg=1000
> pci 0006:00:00.0: [PE# 0d] Setting up window 0..3fffffff pg=1000
> pci 0004:04 : [PE# 00] Setting up window#1 800000000000000..8000000ffffffff pg=10000
> pci 0006:00:00.0: [PE# 0d] Setting up window 800000000000000..8000000ffffffff pg=10000
> NPU6: npu2_tce_kill: Unexpected TCE size (got 0x1000 expected 0x10000)
> NPU6: npu2_tce_kill: Unexpected TCE size (got 0x1000 expected 0x10000)
> NPU6: npu2_tce_kill: Unexpected TCE size (got 0x1000 expected 0x10000)
> NPU6: npu2_tce_kill: Unexpected TCE size (got 0x1000 expected 0x10000)
> NPU6: npu2_tce_kill: Unexpected TCE size (got 0x1000 expected 0x10000)
> ...
> pci 0004:04 : [PE# 00] Removing DMA window #0
> pci 0006:00:00.0: [PE# 0d] Removing DMA window
> pci 0004:04 : [PE# 00] Removing DMA window #1
> pci 0006:00:00.0: [PE# 0d] Removing DMA window
> pci 0004:04 : [PE# 00] Setting up window#0 0..3fffffff pg=1000
> pci 0006:00:00.0: [PE# 0d] Setting up window 0..3fffffff pg=1000
> pci 0004:04 : [PE# 00] Setting up window#1 800000000000000..8000000ffffffff pg=10000
> pci 0006:00:00.0: [PE# 0d] Setting up window 800000000000000..8000000ffffffff pg=10000
>
> After the patch (no errors here):
>
> pci 0004:04 : [PE# 00] Setting up window#0 0..3fffffff pg=1000
> pci 0006:00:00.0: [PE# 0d] Setting up window 0..3fffffff pg=1000
> pci 0004:04 : [PE# 00] Setting up window#1 800000000000000..8000000ffffffff pg=10000
> pci 0006:00:00.0: [PE# 0d] Removing DMA window
> pci 0006:00:00.0: [PE# 0d] Setting up window 800000000000000..8000000ffffffff pg=10000
> pci 0004:04 : [PE# 00] Removing DMA window #0
> pci 0004:04 : [PE# 00] Removing DMA window #1
> pci 0006:00:00.0: [PE# 0d] Removing DMA window
> pci 0004:04 : [PE# 00] Setting up window#0 0..3fffffff pg=1000
> pci 0006:00:00.0: [PE# 0d] Setting up window 0..3fffffff pg=1000
> pci 0004:04 : [PE# 00] Setting up window#1 800000000000000..8000000ffffffff pg=10000
> pci 0006:00:00.0: [PE# 0d] Removing DMA window
> pci 0006:00:00.0: [PE# 0d] Setting up window 800000000000000..8000000ffffffff pg=10000
> ---
> arch/powerpc/platforms/powernv/pci-ioda.c | 27 ++++++++++++++++++++++++---
> 1 file changed, 24 insertions(+), 3 deletions(-)
>
> diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
> index 496e476..2f91815 100644
> --- a/arch/powerpc/platforms/powernv/pci-ioda.c
> +++ b/arch/powerpc/platforms/powernv/pci-ioda.c
> @@ -2681,14 +2681,23 @@ static struct pnv_ioda_pe *gpe_table_group_to_npe(
> static long pnv_pci_ioda2_npu_set_window(struct iommu_table_group *table_group,
> int num, struct iommu_table *tbl)
> {
> + struct pnv_ioda_pe *npe = gpe_table_group_to_npe(table_group);
> + int num2 = (num == 0) ? 1 : 0;
> long ret = pnv_pci_ioda2_set_window(table_group, num, tbl);
>
> if (ret)
> return ret;
>
> - ret = pnv_npu_set_window(gpe_table_group_to_npe(table_group), num, tbl);
> - if (ret)
> + if (table_group->tables[num2])
> + pnv_npu_unset_window(npe, num2);
> +
> + ret = pnv_npu_set_window(npe, num, tbl);
> + if (ret) {
> pnv_pci_ioda2_unset_window(table_group, num);
> + if (table_group->tables[num2])
> + pnv_npu_set_window(npe, num2,
> + table_group->tables[num2]);
> + }
>
> return ret;
> }
> @@ -2697,12 +2706,24 @@ static long pnv_pci_ioda2_npu_unset_window(
> struct iommu_table_group *table_group,
> int num)
> {
> + struct pnv_ioda_pe *npe = gpe_table_group_to_npe(table_group);
> + int num2 = (num == 0) ? 1 : 0;
> long ret = pnv_pci_ioda2_unset_window(table_group, num);
>
> if (ret)
> return ret;
>
> - return pnv_npu_unset_window(gpe_table_group_to_npe(table_group), num);
> + if (!npe->table_group.tables[num])
> + return 0;
> +
> + ret = pnv_npu_unset_window(npe, num);
> + if (ret)
> + return ret;
> +
> + if (table_group->tables[num2])
> + ret = pnv_npu_set_window(npe, num2, table_group->tables[num2]);
> +
> + return ret;
> }
>
> static void pnv_ioda2_npu_take_ownership(struct iommu_table_group *table_group)
>
--
Alexey
More information about the Linuxppc-dev
mailing list