[PATCH 2/2] drm/amdgpu: add independent DMA-buf import v9

Deucher, Alexander Alexander.Deucher at amd.com
Mon Oct 28 15:38:44 UTC 2019


Series is:
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
________________________________
From: amd-gfx <amd-gfx-bounces at lists.freedesktop.org> on behalf of Christian König <ckoenig.leichtzumerken at gmail.com>
Sent: Monday, October 28, 2019 11:14 AM
To: amd-gfx at lists.freedesktop.org <amd-gfx at lists.freedesktop.org>
Subject: [PATCH 2/2] drm/amdgpu: add independent DMA-buf import v9

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
v7: drop invalidations when the BO is already in system domain
v8: rebase on new DMA-buf patch and drop move notification
v9: cleanup comments

Signed-off-by: Christian König <christian.koenig at amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 43 ++++++++++++---------
 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_ttm.c     | 32 ++++++++++++---
 4 files changed, 52 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
index f14b52cc7205..d5bcdfefbad6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -370,31 +370,28 @@ struct dma_buf *amdgpu_gem_prime_export(struct drm_gem_object *gobj,
 }

 /**
- * 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 dma_resv *resv = attach->dmabuf->resv;
+       struct dma_resv *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;
@@ -405,11 +402,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;

         dma_resv_unlock(resv);
@@ -425,15 +420,15 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
  * @dev: DRM device
  * @dma_buf: Shared DMA buffer
  *
- * The main work is done by the &drm_gem_prime_import helper, which in turn
- * uses &amdgpu_gem_prime_import_sg_table.
+ * Import a dma_buf into a the driver and potentially create a new GEM object.
  *
  * Returns:
  * GEM BO representing the shared DMA buffer for the given device.
  */
 struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev,
-                                           struct dma_buf *dma_buf)
+                                              struct dma_buf *dma_buf)
 {
+       struct dma_buf_attachment *attach;
         struct drm_gem_object *obj;

         if (dma_buf->ops == &amdgpu_dmabuf_ops) {
@@ -448,5 +443,17 @@ 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, true);
+       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 ce1b3f017451..ec447a7b6b28 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_gem_object *gobj,
                                         int flags);
 struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 8805776c8c52..25adf2b847e8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -1445,7 +1445,6 @@ static struct drm_driver kms_driver = {
         .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
         .gem_prime_export = amdgpu_gem_prime_export,
         .gem_prime_import = amdgpu_gem_prime_import,
-       .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_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 8e867b8b432f..c19100ced040 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>
@@ -763,6 +764,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;
@@ -1227,6 +1229,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 = &bo->base;

         /* allocate space for the uninitialized page entries */
         if (ttm_sg_tt_init(&gtt->ttm, bo, page_flags)) {
@@ -1247,7 +1250,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) {
@@ -1260,7 +1262,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);
@@ -1287,9 +1301,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);
@@ -1298,7 +1311,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 at lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/amd-gfx/attachments/20191028/1984ebbc/attachment-0001.html>


More information about the amd-gfx mailing list