diff options
author | Alistair Popple <alistair@popple.id.au> | 2017-09-05 21:49:00 -0400 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2017-11-12 16:00:30 -0500 |
commit | 1b2c2b12386f9bb009a2249eca00e01a9d76d7c1 (patch) | |
tree | e521dd43b3565c4f3157f277a9b4647393b37ea4 | |
parent | 2a31ad093bb1b8c1f1e04cbe222ad17bc09c4534 (diff) |
powerpc/powernv/npu: Don't explicitly flush nmmu tlb
The nest mmu required an explicit flush as a tlbi would not flush it in the
same way as the core. However an alternate firmware fix exists which should
eliminate the need for this flush, so instead add a device-tree property
(ibm,nmmu-flush) on the NVLink2 PHB to enable it only if required.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
Reviewed-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r-- | arch/powerpc/platforms/powernv/npu-dma.c | 28 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/pci.h | 3 |
2 files changed, 26 insertions, 5 deletions
diff --git a/arch/powerpc/platforms/powernv/npu-dma.c b/arch/powerpc/platforms/powernv/npu-dma.c index 2fff9a65975b..f6cbc1a71472 100644 --- a/arch/powerpc/platforms/powernv/npu-dma.c +++ b/arch/powerpc/platforms/powernv/npu-dma.c | |||
@@ -395,6 +395,7 @@ struct npu_context { | |||
395 | struct pci_dev *npdev[NV_MAX_NPUS][NV_MAX_LINKS]; | 395 | struct pci_dev *npdev[NV_MAX_NPUS][NV_MAX_LINKS]; |
396 | struct mmu_notifier mn; | 396 | struct mmu_notifier mn; |
397 | struct kref kref; | 397 | struct kref kref; |
398 | bool nmmu_flush; | ||
398 | 399 | ||
399 | /* Callback to stop translation requests on a given GPU */ | 400 | /* Callback to stop translation requests on a given GPU */ |
400 | struct npu_context *(*release_cb)(struct npu_context *, void *); | 401 | struct npu_context *(*release_cb)(struct npu_context *, void *); |
@@ -545,11 +546,13 @@ static void mmio_invalidate(struct npu_context *npu_context, int va, | |||
545 | struct mmio_atsd_reg mmio_atsd_reg[NV_MAX_NPUS]; | 546 | struct mmio_atsd_reg mmio_atsd_reg[NV_MAX_NPUS]; |
546 | unsigned long pid = npu_context->mm->context.id; | 547 | unsigned long pid = npu_context->mm->context.id; |
547 | 548 | ||
548 | /* | 549 | if (npu_context->nmmu_flush) |
549 | * Unfortunately the nest mmu does not support flushing specific | 550 | /* |
550 | * addresses so we have to flush the whole mm. | 551 | * Unfortunately the nest mmu does not support flushing specific |
551 | */ | 552 | * addresses so we have to flush the whole mm once before |
552 | flush_all_mm(npu_context->mm); | 553 | * shooting down the GPU translation. |
554 | */ | ||
555 | flush_all_mm(npu_context->mm); | ||
553 | 556 | ||
554 | /* | 557 | /* |
555 | * Loop over all the NPUs this process is active on and launch | 558 | * Loop over all the NPUs this process is active on and launch |
@@ -722,6 +725,16 @@ struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev, | |||
722 | return ERR_PTR(-ENODEV); | 725 | return ERR_PTR(-ENODEV); |
723 | npu_context->npdev[npu->index][nvlink_index] = npdev; | 726 | npu_context->npdev[npu->index][nvlink_index] = npdev; |
724 | 727 | ||
728 | if (!nphb->npu.nmmu_flush) { | ||
729 | /* | ||
730 | * If we're not explicitly flushing ourselves we need to mark | ||
731 | * the thread for global flushes | ||
732 | */ | ||
733 | npu_context->nmmu_flush = false; | ||
734 | mm_context_add_copro(mm); | ||
735 | } else | ||
736 | npu_context->nmmu_flush = true; | ||
737 | |||
725 | return npu_context; | 738 | return npu_context; |
726 | } | 739 | } |
727 | EXPORT_SYMBOL(pnv_npu2_init_context); | 740 | EXPORT_SYMBOL(pnv_npu2_init_context); |
@@ -731,6 +744,9 @@ static void pnv_npu2_release_context(struct kref *kref) | |||
731 | struct npu_context *npu_context = | 744 | struct npu_context *npu_context = |
732 | container_of(kref, struct npu_context, kref); | 745 | container_of(kref, struct npu_context, kref); |
733 | 746 | ||
747 | if (!npu_context->nmmu_flush) | ||
748 | mm_context_remove_copro(npu_context->mm); | ||
749 | |||
734 | npu_context->mm->context.npu_context = NULL; | 750 | npu_context->mm->context.npu_context = NULL; |
735 | mmu_notifier_unregister(&npu_context->mn, | 751 | mmu_notifier_unregister(&npu_context->mn, |
736 | npu_context->mm); | 752 | npu_context->mm); |
@@ -819,6 +835,8 @@ int pnv_npu2_init(struct pnv_phb *phb) | |||
819 | static int npu_index; | 835 | static int npu_index; |
820 | uint64_t rc = 0; | 836 | uint64_t rc = 0; |
821 | 837 | ||
838 | phb->npu.nmmu_flush = | ||
839 | of_property_read_bool(phb->hose->dn, "ibm,nmmu-flush"); | ||
822 | for_each_child_of_node(phb->hose->dn, dn) { | 840 | for_each_child_of_node(phb->hose->dn, dn) { |
823 | gpdev = pnv_pci_get_gpu_dev(get_pci_dev(dn)); | 841 | gpdev = pnv_pci_get_gpu_dev(get_pci_dev(dn)); |
824 | if (gpdev) { | 842 | if (gpdev) { |
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 56d1f272d4ad..96151b3a2dd4 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h | |||
@@ -187,6 +187,9 @@ struct pnv_phb { | |||
187 | 187 | ||
188 | /* Bitmask for MMIO register usage */ | 188 | /* Bitmask for MMIO register usage */ |
189 | unsigned long mmio_atsd_usage; | 189 | unsigned long mmio_atsd_usage; |
190 | |||
191 | /* Do we need to explicitly flush the nest mmu? */ | ||
192 | bool nmmu_flush; | ||
190 | } npu; | 193 | } npu; |
191 | 194 | ||
192 | #ifdef CONFIG_CXL_BASE | 195 | #ifdef CONFIG_CXL_BASE |