diff options
| -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 |
