@@ -529,6 +529,16 @@ kfd_mem_dmamap_userptr(struct kgd_mem *mem,
529
529
return ret ;
530
530
}
531
531
532
+ static int
533
+ kfd_mem_dmamap_dmabuf (struct kfd_mem_attachment * attachment )
534
+ {
535
+ struct ttm_operation_ctx ctx = {.interruptible = true};
536
+ struct amdgpu_bo * bo = attachment -> bo_va -> base .bo ;
537
+
538
+ amdgpu_bo_placement_from_domain (bo , AMDGPU_GEM_DOMAIN_GTT );
539
+ return ttm_bo_validate (& bo -> tbo , & bo -> placement , & ctx );
540
+ }
541
+
532
542
static int
533
543
kfd_mem_dmamap_attachment (struct kgd_mem * mem ,
534
544
struct kfd_mem_attachment * attachment )
@@ -538,6 +548,8 @@ kfd_mem_dmamap_attachment(struct kgd_mem *mem,
538
548
return 0 ;
539
549
case KFD_MEM_ATT_USERPTR :
540
550
return kfd_mem_dmamap_userptr (mem , attachment );
551
+ case KFD_MEM_ATT_DMABUF :
552
+ return kfd_mem_dmamap_dmabuf (attachment );
541
553
default :
542
554
WARN_ON_ONCE (1 );
543
555
}
@@ -567,6 +579,19 @@ kfd_mem_dmaunmap_userptr(struct kgd_mem *mem,
567
579
ttm -> sg = NULL ;
568
580
}
569
581
582
+ static void
583
+ kfd_mem_dmaunmap_dmabuf (struct kfd_mem_attachment * attachment )
584
+ {
585
+ struct ttm_operation_ctx ctx = {.interruptible = true};
586
+ struct amdgpu_bo * bo = attachment -> bo_va -> base .bo ;
587
+
588
+ amdgpu_bo_placement_from_domain (bo , AMDGPU_GEM_DOMAIN_CPU );
589
+ ttm_bo_validate (& bo -> tbo , & bo -> placement , & ctx );
590
+ /* FIXME: This does not guarantee that amdgpu_ttm_tt_unpopulate is
591
+ * called
592
+ */
593
+ }
594
+
570
595
static void
571
596
kfd_mem_dmaunmap_attachment (struct kgd_mem * mem ,
572
597
struct kfd_mem_attachment * attachment )
@@ -577,6 +602,9 @@ kfd_mem_dmaunmap_attachment(struct kgd_mem *mem,
577
602
case KFD_MEM_ATT_USERPTR :
578
603
kfd_mem_dmaunmap_userptr (mem , attachment );
579
604
break ;
605
+ case KFD_MEM_ATT_DMABUF :
606
+ kfd_mem_dmaunmap_dmabuf (attachment );
607
+ break ;
580
608
default :
581
609
WARN_ON_ONCE (1 );
582
610
}
@@ -610,6 +638,38 @@ kfd_mem_attach_userptr(struct amdgpu_device *adev, struct kgd_mem *mem,
610
638
return 0 ;
611
639
}
612
640
641
+ static int
642
+ kfd_mem_attach_dmabuf (struct amdgpu_device * adev , struct kgd_mem * mem ,
643
+ struct amdgpu_bo * * bo )
644
+ {
645
+ struct drm_gem_object * gobj ;
646
+
647
+ if (!mem -> dmabuf ) {
648
+ mem -> dmabuf = amdgpu_gem_prime_export (& mem -> bo -> tbo .base ,
649
+ mem -> alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE ?
650
+ DRM_RDWR : 0 );
651
+ if (IS_ERR (mem -> dmabuf )) {
652
+ mem -> dmabuf = NULL ;
653
+ return PTR_ERR (mem -> dmabuf );
654
+ }
655
+ }
656
+
657
+ gobj = amdgpu_gem_prime_import (& adev -> ddev , mem -> dmabuf );
658
+ if (IS_ERR (gobj ))
659
+ return PTR_ERR (gobj );
660
+
661
+ /* Import takes an extra reference on the dmabuf. Drop it now to
662
+ * avoid leaking it. We only need the one reference in
663
+ * kgd_mem->dmabuf.
664
+ */
665
+ dma_buf_put (mem -> dmabuf );
666
+
667
+ * bo = gem_to_amdgpu_bo (gobj );
668
+ (* bo )-> parent = amdgpu_bo_ref (mem -> bo );
669
+
670
+ return 0 ;
671
+ }
672
+
613
673
/* kfd_mem_attach - Add a BO to a VM
614
674
*
615
675
* Everything that needs to bo done only once when a BO is first added
@@ -667,8 +727,20 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem,
667
727
ret = kfd_mem_attach_userptr (adev , mem , & bo [i ]);
668
728
if (ret )
669
729
goto unwind ;
730
+ } else if (mem -> domain == AMDGPU_GEM_DOMAIN_GTT &&
731
+ mem -> bo -> tbo .type != ttm_bo_type_sg ) {
732
+ /* GTT BOs use DMA-mapping ability of dynamic-attach
733
+ * DMA bufs. TODO: The same should work for VRAM on
734
+ * large-BAR GPUs.
735
+ */
736
+ attachment [i ]-> type = KFD_MEM_ATT_DMABUF ;
737
+ ret = kfd_mem_attach_dmabuf (adev , mem , & bo [i ]);
738
+ if (ret )
739
+ goto unwind ;
670
740
} else {
671
- /* FIXME: Need to DMA-map other BO types */
741
+ /* FIXME: Need to DMA-map other BO types:
742
+ * large-BAR VRAM, doorbells, MMIO remap
743
+ */
672
744
attachment [i ]-> type = KFD_MEM_ATT_SHARED ;
673
745
bo [i ] = mem -> bo ;
674
746
drm_gem_object_get (& bo [i ]-> tbo .base );
@@ -1527,6 +1599,8 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
1527
1599
1528
1600
/* Free the BO*/
1529
1601
drm_vma_node_revoke (& mem -> bo -> tbo .base .vma_node , drm_priv );
1602
+ if (mem -> dmabuf )
1603
+ dma_buf_put (mem -> dmabuf );
1530
1604
drm_gem_object_put (& mem -> bo -> tbo .base );
1531
1605
mutex_destroy (& mem -> lock );
1532
1606
kfree (mem );
0 commit comments