aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlistair Popple <alistair@popple.id.au>2017-09-05 21:49:00 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2017-11-12 16:00:30 -0500
commit1b2c2b12386f9bb009a2249eca00e01a9d76d7c1 (patch)
treee521dd43b3565c4f3157f277a9b4647393b37ea4
parent2a31ad093bb1b8c1f1e04cbe222ad17bc09c4534 (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.c28
-rw-r--r--arch/powerpc/platforms/powernv/pci.h3
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}
727EXPORT_SYMBOL(pnv_npu2_init_context); 740EXPORT_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