Instead of relying on the DRM functions just implement our own import
functions. This prepares support for taking care of unpinned DMA-buf.

v2: enable for all exporters, not just amdgpu, fix invalidation
    handling, lock reservation object while setting callback
v3: change to new dma_buf attach interface
v4: split out from unpinned DMA-buf work
v5: rebased and cleanup on new DMA-buf interface
v6: squash with invalidation callback change,
    stop using _(map|unmap)_locked

Signed-off-by: Christian König <christian.koe...@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 65 ++++++++++++++++-----
 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h |  4 --
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c     |  1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c  |  6 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c     | 32 ++++++++--
 5 files changed, 83 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
index 579e33b31f2d..31511d7de8a0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -424,31 +424,28 @@ struct dma_buf *amdgpu_gem_prime_export(struct drm_device 
*dev,
 }
 
 /**
- * amdgpu_gem_prime_import_sg_table - &drm_driver.gem_prime_import_sg_table
- * implementation
+ * amdgpu_dma_buf_create_obj - create BO for DMA-buf import
+ *
  * @dev: DRM device
- * @attach: DMA-buf attachment
- * @sg: Scatter/gather table
+ * @dma_buf: DMA-buf
  *
- * Imports shared DMA buffer memory exported by another device.
+ * Creates an empty SG BO for DMA-buf import.
  *
  * Returns:
  * A new GEM BO of the given DRM device, representing the memory
  * described by the given DMA-buf attachment and scatter/gather table.
  */
-struct drm_gem_object *
-amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
-                                struct dma_buf_attachment *attach,
-                                struct sg_table *sg)
+static struct drm_gem_object *
+amdgpu_dma_buf_create_obj(struct drm_device *dev, struct dma_buf *dma_buf)
 {
-       struct reservation_object *resv = attach->dmabuf->resv;
+       struct reservation_object *resv = dma_buf->resv;
        struct amdgpu_device *adev = dev->dev_private;
        struct amdgpu_bo *bo;
        struct amdgpu_bo_param bp;
        int ret;
 
        memset(&bp, 0, sizeof(bp));
-       bp.size = attach->dmabuf->size;
+       bp.size = dma_buf->size;
        bp.byte_align = PAGE_SIZE;
        bp.domain = AMDGPU_GEM_DOMAIN_CPU;
        bp.flags = 0;
@@ -459,11 +456,9 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
        if (ret)
                goto error;
 
-       bo->tbo.sg = sg;
-       bo->tbo.ttm->sg = sg;
        bo->allowed_domains = AMDGPU_GEM_DOMAIN_GTT;
        bo->preferred_domains = AMDGPU_GEM_DOMAIN_GTT;
-       if (attach->dmabuf->ops != &amdgpu_dmabuf_ops)
+       if (dma_buf->ops != &amdgpu_dmabuf_ops)
                bo->prime_shared_count = 1;
 
        ww_mutex_unlock(&resv->lock);
@@ -474,6 +469,32 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
        return ERR_PTR(ret);
 }
 
+/**
+ * amdgpu_gem_prime_invalidate_mappings - &attach.invalidate implementation
+ *
+ * @attach: the DMA-buf attachment
+ *
+ * Invalidate the DMA-buf attachment, making sure that the we re-create the
+ * mapping before the next use.
+ */
+static void
+amdgpu_gem_prime_invalidate_mappings(struct dma_buf_attachment *attach)
+{
+       struct ttm_operation_ctx ctx = { false, false };
+       struct drm_gem_object *obj = attach->importer_priv;
+       struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
+       struct ttm_placement placement = {};
+       int r;
+
+       r = ttm_bo_validate(&bo->tbo, &placement, &ctx);
+       if (r)
+               DRM_ERROR("Failed to invalidate DMA-buf import (%d))\n", r);
+}
+
+static const struct dma_buf_attach_ops amdgpu_dma_buf_attach_ops = {
+       .invalidate = amdgpu_gem_prime_invalidate_mappings
+};
+
 /**
  * amdgpu_gem_prime_import - &drm_driver.gem_prime_import implementation
  * @dev: DRM device
@@ -488,6 +509,7 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
 struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev,
                                            struct dma_buf *dma_buf)
 {
+       struct dma_buf_attachment *attach;
        struct drm_gem_object *obj;
 
        if (dma_buf->ops == &amdgpu_dmabuf_ops) {
@@ -502,5 +524,18 @@ struct drm_gem_object *amdgpu_gem_prime_import(struct 
drm_device *dev,
                }
        }
 
-       return drm_gem_prime_import(dev, dma_buf);
+       obj = amdgpu_dma_buf_create_obj(dev, dma_buf);
+       if (IS_ERR(obj))
+               return obj;
+
+       attach = dma_buf_dynamic_attach(dma_buf, dev->dev,
+                                       &amdgpu_dma_buf_attach_ops, obj);
+       if (IS_ERR(attach)) {
+               drm_gem_object_put(obj);
+               return ERR_CAST(attach);
+       }
+
+       get_dma_buf(dma_buf);
+       obj->import_attach = attach;
+       return obj;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h
index f1522292814c..2765413770b9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h
@@ -25,10 +25,6 @@
 
 #include <drm/drm_gem.h>
 
-struct drm_gem_object *
-amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
-                                struct dma_buf_attachment *attach,
-                                struct sg_table *sg);
 struct dma_buf *amdgpu_gem_prime_export(struct drm_device *dev,
                                        struct drm_gem_object *gobj,
                                        int flags);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 5f3b7cab8390..76d445916c9a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -1334,7 +1334,6 @@ static struct drm_driver kms_driver = {
        .gem_prime_export = amdgpu_gem_prime_export,
        .gem_prime_import = amdgpu_gem_prime_import,
        .gem_prime_res_obj = amdgpu_gem_prime_res_obj,
-       .gem_prime_import_sg_table = amdgpu_gem_prime_import_sg_table,
        .gem_prime_vmap = amdgpu_gem_prime_vmap,
        .gem_prime_vunmap = amdgpu_gem_prime_vunmap,
        .gem_prime_mmap = amdgpu_gem_prime_mmap,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 7843b3c6ca54..99bcf6e710a7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -850,6 +850,9 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 
domain,
                return 0;
        }
 
+       if (bo->gem_base.import_attach)
+               dma_buf_pin(bo->gem_base.import_attach);
+
        bo->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
        /* force to pin into visible video ram */
        if (!(bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS))
@@ -933,6 +936,9 @@ int amdgpu_bo_unpin(struct amdgpu_bo *bo)
 
        amdgpu_bo_subtract_pin_size(bo);
 
+       if (bo->gem_base.import_attach)
+               dma_buf_unpin(bo->gem_base.import_attach);
+
        for (i = 0; i < bo->placement.num_placement; i++) {
                bo->placements[i].lpfn = 0;
                bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index d81bebf76310..c89fa58a7914 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -39,6 +39,7 @@
 #include <linux/slab.h>
 #include <linux/swap.h>
 #include <linux/swiotlb.h>
+#include <linux/dma-buf.h>
 
 #include <drm/ttm/ttm_bo_api.h>
 #include <drm/ttm/ttm_bo_driver.h>
@@ -711,6 +712,7 @@ static unsigned long amdgpu_ttm_io_mem_pfn(struct 
ttm_buffer_object *bo,
  */
 struct amdgpu_ttm_tt {
        struct ttm_dma_tt       ttm;
+       struct drm_gem_object   *gobj;
        u64                     offset;
        uint64_t                userptr;
        struct task_struct      *usertask;
@@ -1198,6 +1200,7 @@ static struct ttm_tt *amdgpu_ttm_tt_create(struct 
ttm_buffer_object *bo,
                return NULL;
        }
        gtt->ttm.ttm.func = &amdgpu_backend_func;
+       gtt->gobj = &ttm_to_amdgpu_bo(bo)->gem_base;
 
        /* allocate space for the uninitialized page entries */
        if (ttm_sg_tt_init(&gtt->ttm, bo, page_flags)) {
@@ -1218,7 +1221,6 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm,
 {
        struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
        struct amdgpu_ttm_tt *gtt = (void *)ttm;
-       bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
 
        /* user pages are bound by amdgpu_ttm_tt_pin_userptr() */
        if (gtt && gtt->userptr) {
@@ -1231,7 +1233,19 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm,
                return 0;
        }
 
-       if (slave && ttm->sg) {
+       if (ttm->page_flags & TTM_PAGE_FLAG_SG) {
+               if (!ttm->sg) {
+                       struct dma_buf_attachment *attach;
+                       struct sg_table *sgt;
+
+                       attach = gtt->gobj->import_attach;
+                       sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
+                       if (IS_ERR(sgt))
+                               return PTR_ERR(sgt);
+
+                       ttm->sg = sgt;
+               }
+
                drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
                                                 gtt->ttm.dma_address,
                                                 ttm->num_pages);
@@ -1258,9 +1272,8 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm,
  */
 static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm)
 {
-       struct amdgpu_device *adev;
        struct amdgpu_ttm_tt *gtt = (void *)ttm;
-       bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
+       struct amdgpu_device *adev;
 
        if (gtt && gtt->userptr) {
                amdgpu_ttm_tt_set_user_pages(ttm, NULL);
@@ -1269,7 +1282,16 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm)
                return;
        }
 
-       if (slave)
+       if (ttm->sg && gtt->gobj->import_attach) {
+               struct dma_buf_attachment *attach;
+
+               attach = gtt->gobj->import_attach;
+               dma_buf_unmap_attachment(attach, ttm->sg, DMA_BIDIRECTIONAL);
+               ttm->sg = NULL;
+               return;
+       }
+
+       if (ttm->page_flags & TTM_PAGE_FLAG_SG)
                return;
 
        adev = amdgpu_ttm_adev(ttm->bdev);
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to