<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Series is:</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Reviewed-by: Alex Deucher <alexander.deucher@amd.com><br>
</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> amd-gfx <amd-gfx-bounces@lists.freedesktop.org> on behalf of Christian König <ckoenig.leichtzumerken@gmail.com><br>
<b>Sent:</b> Monday, October 28, 2019 11:14 AM<br>
<b>To:</b> amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org><br>
<b>Subject:</b> [PATCH 2/2] drm/amdgpu: add independent DMA-buf import v9</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">Instead of relying on the DRM functions just implement our own import<br>
functions. This prepares support for taking care of unpinned DMA-buf.<br>
<br>
v2: enable for all exporters, not just amdgpu, fix invalidation<br>
    handling, lock reservation object while setting callback<br>
v3: change to new dma_buf attach interface<br>
v4: split out from unpinned DMA-buf work<br>
v5: rebased and cleanup on new DMA-buf interface<br>
v6: squash with invalidation callback change,<br>
    stop using _(map|unmap)_locked<br>
v7: drop invalidations when the BO is already in system domain<br>
v8: rebase on new DMA-buf patch and drop move notification<br>
v9: cleanup comments<br>
<br>
Signed-off-by: Christian König <christian.koenig@amd.com><br>
---<br>
 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 43 ++++++++++++---------<br>
 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h |  4 --<br>
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c     |  1 -<br>
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c     | 32 ++++++++++++---<br>
 4 files changed, 52 insertions(+), 28 deletions(-)<br>
<br>
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c<br>
index f14b52cc7205..d5bcdfefbad6 100644<br>
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c<br>
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c<br>
@@ -370,31 +370,28 @@ struct dma_buf *amdgpu_gem_prime_export(struct drm_gem_object *gobj,<br>
 }<br>
 <br>
 /**<br>
- * amdgpu_gem_prime_import_sg_table - &drm_driver.gem_prime_import_sg_table<br>
- * implementation<br>
+ * amdgpu_dma_buf_create_obj - create BO for DMA-buf import<br>
+ *<br>
  * @dev: DRM device<br>
- * @attach: DMA-buf attachment<br>
- * @sg: Scatter/gather table<br>
+ * @dma_buf: DMA-buf<br>
  *<br>
- * Imports shared DMA buffer memory exported by another device.<br>
+ * Creates an empty SG BO for DMA-buf import.<br>
  *<br>
  * Returns:<br>
  * A new GEM BO of the given DRM device, representing the memory<br>
  * described by the given DMA-buf attachment and scatter/gather table.<br>
  */<br>
-struct drm_gem_object *<br>
-amdgpu_gem_prime_import_sg_table(struct drm_device *dev,<br>
-                                struct dma_buf_attachment *attach,<br>
-                                struct sg_table *sg)<br>
+static struct drm_gem_object *<br>
+amdgpu_dma_buf_create_obj(struct drm_device *dev, struct dma_buf *dma_buf)<br>
 {<br>
-       struct dma_resv *resv = attach->dmabuf->resv;<br>
+       struct dma_resv *resv = dma_buf->resv;<br>
         struct amdgpu_device *adev = dev->dev_private;<br>
         struct amdgpu_bo *bo;<br>
         struct amdgpu_bo_param bp;<br>
         int ret;<br>
 <br>
         memset(&bp, 0, sizeof(bp));<br>
-       bp.size = attach->dmabuf->size;<br>
+       bp.size = dma_buf->size;<br>
         bp.byte_align = PAGE_SIZE;<br>
         bp.domain = AMDGPU_GEM_DOMAIN_CPU;<br>
         bp.flags = 0;<br>
@@ -405,11 +402,9 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev,<br>
         if (ret)<br>
                 goto error;<br>
 <br>
-       bo->tbo.sg = sg;<br>
-       bo->tbo.ttm->sg = sg;<br>
         bo->allowed_domains = AMDGPU_GEM_DOMAIN_GTT;<br>
         bo->preferred_domains = AMDGPU_GEM_DOMAIN_GTT;<br>
-       if (attach->dmabuf->ops != &amdgpu_dmabuf_ops)<br>
+       if (dma_buf->ops != &amdgpu_dmabuf_ops)<br>
                 bo->prime_shared_count = 1;<br>
 <br>
         dma_resv_unlock(resv);<br>
@@ -425,15 +420,15 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev,<br>
  * @dev: DRM device<br>
  * @dma_buf: Shared DMA buffer<br>
  *<br>
- * The main work is done by the &drm_gem_prime_import helper, which in turn<br>
- * uses &amdgpu_gem_prime_import_sg_table.<br>
+ * Import a dma_buf into a the driver and potentially create a new GEM object.<br>
  *<br>
  * Returns:<br>
  * GEM BO representing the shared DMA buffer for the given device.<br>
  */<br>
 struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev,<br>
-                                           struct dma_buf *dma_buf)<br>
+                                              struct dma_buf *dma_buf)<br>
 {<br>
+       struct dma_buf_attachment *attach;<br>
         struct drm_gem_object *obj;<br>
 <br>
         if (dma_buf->ops == &amdgpu_dmabuf_ops) {<br>
@@ -448,5 +443,17 @@ struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev,<br>
                 }<br>
         }<br>
 <br>
-       return drm_gem_prime_import(dev, dma_buf);<br>
+       obj = amdgpu_dma_buf_create_obj(dev, dma_buf);<br>
+       if (IS_ERR(obj))<br>
+               return obj;<br>
+<br>
+       attach = dma_buf_dynamic_attach(dma_buf, dev->dev, true);<br>
+       if (IS_ERR(attach)) {<br>
+               drm_gem_object_put(obj);<br>
+               return ERR_CAST(attach);<br>
+       }<br>
+<br>
+       get_dma_buf(dma_buf);<br>
+       obj->import_attach = attach;<br>
+       return obj;<br>
 }<br>
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h<br>
index ce1b3f017451..ec447a7b6b28 100644<br>
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h<br>
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h<br>
@@ -25,10 +25,6 @@<br>
 <br>
 #include <drm/drm_gem.h><br>
 <br>
-struct drm_gem_object *<br>
-amdgpu_gem_prime_import_sg_table(struct drm_device *dev,<br>
-                                struct dma_buf_attachment *attach,<br>
-                                struct sg_table *sg);<br>
 struct dma_buf *amdgpu_gem_prime_export(struct drm_gem_object *gobj,<br>
                                         int flags);<br>
 struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev,<br>
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c<br>
index 8805776c8c52..25adf2b847e8 100644<br>
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c<br>
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c<br>
@@ -1445,7 +1445,6 @@ static struct drm_driver kms_driver = {<br>
         .prime_fd_to_handle = drm_gem_prime_fd_to_handle,<br>
         .gem_prime_export = amdgpu_gem_prime_export,<br>
         .gem_prime_import = amdgpu_gem_prime_import,<br>
-       .gem_prime_import_sg_table = amdgpu_gem_prime_import_sg_table,<br>
         .gem_prime_vmap = amdgpu_gem_prime_vmap,<br>
         .gem_prime_vunmap = amdgpu_gem_prime_vunmap,<br>
         .gem_prime_mmap = amdgpu_gem_prime_mmap,<br>
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c<br>
index 8e867b8b432f..c19100ced040 100644<br>
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c<br>
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c<br>
@@ -39,6 +39,7 @@<br>
 #include <linux/slab.h><br>
 #include <linux/swap.h><br>
 #include <linux/swiotlb.h><br>
+#include <linux/dma-buf.h><br>
 <br>
 #include <drm/ttm/ttm_bo_api.h><br>
 #include <drm/ttm/ttm_bo_driver.h><br>
@@ -763,6 +764,7 @@ static unsigned long amdgpu_ttm_io_mem_pfn(struct ttm_buffer_object *bo,<br>
  */<br>
 struct amdgpu_ttm_tt {<br>
         struct ttm_dma_tt       ttm;<br>
+       struct drm_gem_object   *gobj;<br>
         u64                     offset;<br>
         uint64_t                userptr;<br>
         struct task_struct      *usertask;<br>
@@ -1227,6 +1229,7 @@ static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_buffer_object *bo,<br>
                 return NULL;<br>
         }<br>
         gtt->ttm.ttm.func = &amdgpu_backend_func;<br>
+       gtt->gobj = &bo->base;<br>
 <br>
         /* allocate space for the uninitialized page entries */<br>
         if (ttm_sg_tt_init(&gtt->ttm, bo, page_flags)) {<br>
@@ -1247,7 +1250,6 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm,<br>
 {<br>
         struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);<br>
         struct amdgpu_ttm_tt *gtt = (void *)ttm;<br>
-       bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);<br>
 <br>
         /* user pages are bound by amdgpu_ttm_tt_pin_userptr() */<br>
         if (gtt && gtt->userptr) {<br>
@@ -1260,7 +1262,19 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm,<br>
                 return 0;<br>
         }<br>
 <br>
-       if (slave && ttm->sg) {<br>
+       if (ttm->page_flags & TTM_PAGE_FLAG_SG) {<br>
+               if (!ttm->sg) {<br>
+                       struct dma_buf_attachment *attach;<br>
+                       struct sg_table *sgt;<br>
+<br>
+                       attach = gtt->gobj->import_attach;<br>
+                       sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);<br>
+                       if (IS_ERR(sgt))<br>
+                               return PTR_ERR(sgt);<br>
+<br>
+                       ttm->sg = sgt;<br>
+               }<br>
+<br>
                 drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,<br>
                                                  gtt->ttm.dma_address,<br>
                                                  ttm->num_pages);<br>
@@ -1287,9 +1301,8 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm,<br>
  */<br>
 static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm)<br>
 {<br>
-       struct amdgpu_device *adev;<br>
         struct amdgpu_ttm_tt *gtt = (void *)ttm;<br>
-       bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);<br>
+       struct amdgpu_device *adev;<br>
 <br>
         if (gtt && gtt->userptr) {<br>
                 amdgpu_ttm_tt_set_user_pages(ttm, NULL);<br>
@@ -1298,7 +1311,16 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm)<br>
                 return;<br>
         }<br>
 <br>
-       if (slave)<br>
+       if (ttm->sg && gtt->gobj->import_attach) {<br>
+               struct dma_buf_attachment *attach;<br>
+<br>
+               attach = gtt->gobj->import_attach;<br>
+               dma_buf_unmap_attachment(attach, ttm->sg, DMA_BIDIRECTIONAL);<br>
+               ttm->sg = NULL;<br>
+               return;<br>
+       }<br>
+<br>
+       if (ttm->page_flags & TTM_PAGE_FLAG_SG)<br>
                 return;<br>
 <br>
         adev = amdgpu_ttm_adev(ttm->bdev);<br>
-- <br>
2.17.1<br>
<br>
_______________________________________________<br>
amd-gfx mailing list<br>
amd-gfx@lists.freedesktop.org<br>
<a href="https://lists.freedesktop.org/mailman/listinfo/amd-gfx">https://lists.freedesktop.org/mailman/listinfo/amd-gfx</a></div>
</span></font></div>
</body>
</html>