[PATCH kernel] powerpc/npu: Do not try invalidating 32bit table when 64bit table is enabled
Alexey Kardashevskiy
aik at ozlabs.ru
Wed Mar 14 13:49:30 AEDT 2018
On 7/3/18 2:40 pm, Alexey Kardashevskiy wrote:
> 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?
Anyone? Alistair? :)
>
>
>
>>
>>
>> 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