* (no subject)
@ 2018-07-06 14:42 Christian König
2018-07-06 14:42 ` [PATCH 1/6] dma-buf: add caching of sg_table Christian König
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Christian König @ 2018-07-06 14:42 UTC (permalink / raw)
To: intel-gfx
Next try of prework for unpinned DMA-buf operation.
Only send to intel-gfx to trigger unit tests on the following patches.
Christian.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/6] dma-buf: add caching of sg_table
2018-07-06 14:42 (no subject) Christian König
@ 2018-07-06 14:42 ` Christian König
2018-07-06 14:42 ` [PATCH 2/6] drm: remove prime sg_table caching Christian König
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Christian König @ 2018-07-06 14:42 UTC (permalink / raw)
To: intel-gfx
To allow a smooth transition from pinning buffer objects to dynamic
invalidation we first start to cache the sg_table for an attachment
unless the driver explicitly says to not do so.
Signed-off-by: Christian König <christian.koenig@amd.com>
---
drivers/dma-buf/dma-buf.c | 24 ++++++++++++++++++++++++
include/linux/dma-buf.h | 11 +++++++++++
2 files changed, 35 insertions(+)
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 13884474d158..0bea5eecf554 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -574,6 +574,20 @@ struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
list_add(&attach->node, &dmabuf->attachments);
mutex_unlock(&dmabuf->lock);
+
+ if (!dmabuf->ops->no_sgt_cache) {
+ struct sg_table *sgt;
+
+ sgt = dmabuf->ops->map_dma_buf(attach, DMA_BIDIRECTIONAL);
+ if (!sgt)
+ sgt = ERR_PTR(-ENOMEM);
+ if (IS_ERR(sgt)) {
+ dma_buf_detach(dmabuf, attach);
+ return ERR_CAST(sgt);
+ }
+ attach->sgt = sgt;
+ }
+
return attach;
err_attach:
@@ -596,6 +610,10 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach)
if (WARN_ON(!dmabuf || !attach))
return;
+ if (attach->sgt)
+ dmabuf->ops->unmap_dma_buf(attach, attach->sgt,
+ DMA_BIDIRECTIONAL);
+
mutex_lock(&dmabuf->lock);
list_del(&attach->node);
if (dmabuf->ops->detach)
@@ -631,6 +649,9 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
if (WARN_ON(!attach || !attach->dmabuf))
return ERR_PTR(-EINVAL);
+ if (attach->sgt)
+ return attach->sgt;
+
sg_table = attach->dmabuf->ops->map_dma_buf(attach, direction);
if (!sg_table)
sg_table = ERR_PTR(-ENOMEM);
@@ -658,6 +679,9 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
if (WARN_ON(!attach || !attach->dmabuf || !sg_table))
return;
+ if (attach->sgt == sg_table)
+ return;
+
attach->dmabuf->ops->unmap_dma_buf(attach, sg_table,
direction);
}
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index 58725f890b5b..6534a6769e17 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -51,6 +51,16 @@ struct dma_buf_attachment;
* @vunmap: [optional] unmaps a vmap from the buffer
*/
struct dma_buf_ops {
+ /**
+ * @no_sgt_cache:
+ *
+ * Flag controlling the caching of the sg_table in the DMA-buf helpers.
+ * If not set the sg_table is created during device attaching, if set
+ * the sg_table is created dynamically when dma_buf_map_attachment() is
+ * called.
+ */
+ bool no_sgt_cache;
+
/**
* @attach:
*
@@ -323,6 +333,7 @@ struct dma_buf_attachment {
struct device *dev;
struct list_head node;
void *priv;
+ struct sg_table *sgt;
};
/**
--
2.14.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/6] drm: remove prime sg_table caching
2018-07-06 14:42 (no subject) Christian König
2018-07-06 14:42 ` [PATCH 1/6] dma-buf: add caching of sg_table Christian König
@ 2018-07-06 14:42 ` Christian König
2018-07-06 14:42 ` [PATCH 3/6] dma-buf: add dma_buf_(un)map_attachment_locked variants v3 Christian König
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Christian König @ 2018-07-06 14:42 UTC (permalink / raw)
To: intel-gfx
That is now done by the DMA-buf helpers instead.
Signed-off-by: Christian König <christian.koenig@amd.com>
---
drivers/gpu/drm/drm_prime.c | 78 +++++++++++----------------------------------
1 file changed, 18 insertions(+), 60 deletions(-)
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 186db2e4c57a..f6bd37eb2a72 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -86,11 +86,6 @@ struct drm_prime_member {
struct rb_node handle_rb;
};
-struct drm_prime_attachment {
- struct sg_table *sgt;
- enum dma_data_direction dir;
-};
-
static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv,
struct dma_buf *dma_buf, uint32_t handle)
{
@@ -188,26 +183,17 @@ static int drm_prime_lookup_buf_handle(struct drm_prime_file_private *prime_fpri
* @dma_buf: buffer to attach device to
* @attach: buffer attachment data
*
- * Allocates &drm_prime_attachment and calls &drm_driver.gem_prime_pin for
- * device specific attachment. This can be used as the &dma_buf_ops.attach
- * callback.
+ * Calls &drm_driver.gem_prime_pin for device specific handling. This can be
+ * used as the &dma_buf_ops.attach callback.
*
* Returns 0 on success, negative error code on failure.
*/
int drm_gem_map_attach(struct dma_buf *dma_buf,
struct dma_buf_attachment *attach)
{
- struct drm_prime_attachment *prime_attach;
struct drm_gem_object *obj = dma_buf->priv;
struct drm_device *dev = obj->dev;
- prime_attach = kzalloc(sizeof(*prime_attach), GFP_KERNEL);
- if (!prime_attach)
- return -ENOMEM;
-
- prime_attach->dir = DMA_NONE;
- attach->priv = prime_attach;
-
if (!dev->driver->gem_prime_pin)
return 0;
@@ -226,27 +212,9 @@ EXPORT_SYMBOL(drm_gem_map_attach);
void drm_gem_map_detach(struct dma_buf *dma_buf,
struct dma_buf_attachment *attach)
{
- struct drm_prime_attachment *prime_attach = attach->priv;
struct drm_gem_object *obj = dma_buf->priv;
struct drm_device *dev = obj->dev;
- if (prime_attach) {
- struct sg_table *sgt = prime_attach->sgt;
-
- if (sgt) {
- if (prime_attach->dir != DMA_NONE)
- dma_unmap_sg_attrs(attach->dev, sgt->sgl,
- sgt->nents,
- prime_attach->dir,
- DMA_ATTR_SKIP_CPU_SYNC);
- sg_free_table(sgt);
- }
-
- kfree(sgt);
- kfree(prime_attach);
- attach->priv = NULL;
- }
-
if (dev->driver->gem_prime_unpin)
dev->driver->gem_prime_unpin(obj);
}
@@ -292,36 +260,21 @@ void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpr
struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
enum dma_data_direction dir)
{
- struct drm_prime_attachment *prime_attach = attach->priv;
struct drm_gem_object *obj = attach->dmabuf->priv;
struct sg_table *sgt;
- if (WARN_ON(dir == DMA_NONE || !prime_attach))
+ if (WARN_ON(dir == DMA_NONE))
return ERR_PTR(-EINVAL);
- /* return the cached mapping when possible */
- if (prime_attach->dir == dir)
- return prime_attach->sgt;
-
- /*
- * two mappings with different directions for the same attachment are
- * not allowed
- */
- if (WARN_ON(prime_attach->dir != DMA_NONE))
- return ERR_PTR(-EBUSY);
-
sgt = obj->dev->driver->gem_prime_get_sg_table(obj);
+ if (IS_ERR(sgt))
+ return sgt;
- if (!IS_ERR(sgt)) {
- if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
- DMA_ATTR_SKIP_CPU_SYNC)) {
- sg_free_table(sgt);
- kfree(sgt);
- sgt = ERR_PTR(-ENOMEM);
- } else {
- prime_attach->sgt = sgt;
- prime_attach->dir = dir;
- }
+ if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
+ DMA_ATTR_SKIP_CPU_SYNC)) {
+ sg_free_table(sgt);
+ kfree(sgt);
+ sgt = ERR_PTR(-ENOMEM);
}
return sgt;
@@ -334,14 +287,19 @@ EXPORT_SYMBOL(drm_gem_map_dma_buf);
* @sgt: scatterlist info of the buffer to unmap
* @dir: direction of DMA transfer
*
- * Not implemented. The unmap is done at drm_gem_map_detach(). This can be
- * used as the &dma_buf_ops.unmap_dma_buf callback.
+ * This can be used as the &dma_buf_ops.unmap_dma_buf callback.
*/
void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
struct sg_table *sgt,
enum dma_data_direction dir)
{
- /* nothing to be done here */
+ if (!sgt)
+ return;
+
+ dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
+ DMA_ATTR_SKIP_CPU_SYNC);
+ sg_free_table(sgt);
+ kfree(sgt);
}
EXPORT_SYMBOL(drm_gem_unmap_dma_buf);
--
2.14.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/6] dma-buf: add dma_buf_(un)map_attachment_locked variants v3
2018-07-06 14:42 (no subject) Christian König
2018-07-06 14:42 ` [PATCH 1/6] dma-buf: add caching of sg_table Christian König
2018-07-06 14:42 ` [PATCH 2/6] drm: remove prime sg_table caching Christian König
@ 2018-07-06 14:42 ` Christian König
2018-07-06 14:42 ` [PATCH 4/6] dma-buf: lock the reservation object during (un)map_dma_buf v3 Christian König
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Christian König @ 2018-07-06 14:42 UTC (permalink / raw)
To: intel-gfx
Add function variants which can be called with the reservation lock
already held.
v2: reordered, add lockdep asserts, fix kerneldoc
v3: rebased on sgt caching
Signed-off-by: Christian König <christian.koenig@amd.com>
---
drivers/dma-buf/dma-buf.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/dma-buf.h | 5 ++++
2 files changed, 68 insertions(+)
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 0bea5eecf554..e68322c953a9 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -624,6 +624,43 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach)
}
EXPORT_SYMBOL_GPL(dma_buf_detach);
+/**
+ * dma_buf_map_attachment_locked - Maps the buffer into _device_ address space
+ * with the reservation lock held. Is a wrapper for map_dma_buf() of the
+ *
+ * Returns the scatterlist table of the attachment;
+ * dma_buf_ops.
+ * @attach: [in] attachment whose scatterlist is to be returned
+ * @direction: [in] direction of DMA transfer
+ *
+ * Returns sg_table containing the scatterlist to be returned; returns ERR_PTR
+ * on error. May return -EINTR if it is interrupted by a signal.
+ *
+ * A mapping must be unmapped by using dma_buf_unmap_attachment_locked(). Note
+ * that the underlying backing storage is pinned for as long as a mapping
+ * exists, therefore users/importers should not hold onto a mapping for undue
+ * amounts of time.
+ */
+struct sg_table *
+dma_buf_map_attachment_locked(struct dma_buf_attachment *attach,
+ enum dma_data_direction direction)
+{
+ struct sg_table *sg_table;
+
+ might_sleep();
+ reservation_object_assert_held(attach->dmabuf->resv);
+
+ if (attach->sgt)
+ return attach->sgt;
+
+ sg_table = attach->dmabuf->ops->map_dma_buf(attach, direction);
+ if (!sg_table)
+ sg_table = ERR_PTR(-ENOMEM);
+
+ return sg_table;
+}
+EXPORT_SYMBOL_GPL(dma_buf_map_attachment_locked);
+
/**
* dma_buf_map_attachment - Returns the scatterlist table of the attachment;
* mapped into _device_ address space. Is a wrapper for map_dma_buf() of the
@@ -660,6 +697,32 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
}
EXPORT_SYMBOL_GPL(dma_buf_map_attachment);
+/**
+ * dma_buf_unmap_attachment_locked - unmaps the buffer with reservation lock
+ * held, should deallocate the associated scatterlist. Is a wrapper for
+ * unmap_dma_buf() of dma_buf_ops.
+ * @attach: [in] attachment to unmap buffer from
+ * @sg_table: [in] scatterlist info of the buffer to unmap
+ * @direction: [in] direction of DMA transfer
+ *
+ * This unmaps a DMA mapping for @attached obtained by
+ * dma_buf_map_attachment_locked().
+ */
+void dma_buf_unmap_attachment_locked(struct dma_buf_attachment *attach,
+ struct sg_table *sg_table,
+ enum dma_data_direction direction)
+{
+ might_sleep();
+ reservation_object_assert_held(attach->dmabuf->resv);
+
+ if (attach->sgt == sg_table)
+ return;
+
+ attach->dmabuf->ops->unmap_dma_buf(attach, sg_table,
+ direction);
+}
+EXPORT_SYMBOL_GPL(dma_buf_unmap_attachment_locked);
+
/**
* dma_buf_unmap_attachment - unmaps and decreases usecount of the buffer;might
* deallocate the scatterlist associated. Is a wrapper for unmap_dma_buf() of
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index 6534a6769e17..a40f8f586a95 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -395,8 +395,13 @@ int dma_buf_fd(struct dma_buf *dmabuf, int flags);
struct dma_buf *dma_buf_get(int fd);
void dma_buf_put(struct dma_buf *dmabuf);
+struct sg_table *dma_buf_map_attachment_locked(struct dma_buf_attachment *,
+ enum dma_data_direction);
struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *,
enum dma_data_direction);
+void dma_buf_unmap_attachment_locked(struct dma_buf_attachment *,
+ struct sg_table *,
+ enum dma_data_direction);
void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *,
enum dma_data_direction);
int dma_buf_begin_cpu_access(struct dma_buf *dma_buf,
--
2.14.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/6] dma-buf: lock the reservation object during (un)map_dma_buf v3
2018-07-06 14:42 (no subject) Christian König
` (2 preceding siblings ...)
2018-07-06 14:42 ` [PATCH 3/6] dma-buf: add dma_buf_(un)map_attachment_locked variants v3 Christian König
@ 2018-07-06 14:42 ` Christian König
2018-07-06 14:42 ` [PATCH 5/6] drm/amdgpu: add independent DMA-buf export v3 Christian König
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Christian König @ 2018-07-06 14:42 UTC (permalink / raw)
To: intel-gfx
First step towards unpinned DMA buf operation.
I've checked the DRM drivers to potential locking of the reservation
object, but essentially we need to audit all implementations of the
dma_buf _ops for this to work.
v2: reordered
v3: rebased on sgt caching
Signed-off-by: Christian König <christian.koenig@amd.com>
---
drivers/dma-buf/dma-buf.c | 15 ++++++---------
include/linux/dma-buf.h | 6 ++++++
2 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index e68322c953a9..21608306349d 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -686,10 +686,9 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
if (WARN_ON(!attach || !attach->dmabuf))
return ERR_PTR(-EINVAL);
- if (attach->sgt)
- return attach->sgt;
-
- sg_table = attach->dmabuf->ops->map_dma_buf(attach, direction);
+ reservation_object_lock(attach->dmabuf->resv, NULL);
+ sg_table = dma_buf_map_attachment_locked(attach, direction);
+ reservation_object_unlock(attach->dmabuf->resv);
if (!sg_table)
sg_table = ERR_PTR(-ENOMEM);
@@ -742,11 +741,9 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
if (WARN_ON(!attach || !attach->dmabuf || !sg_table))
return;
- if (attach->sgt == sg_table)
- return;
-
- attach->dmabuf->ops->unmap_dma_buf(attach, sg_table,
- direction);
+ reservation_object_lock(attach->dmabuf->resv, NULL);
+ dma_buf_unmap_attachment_locked(attach, sg_table, direction);
+ reservation_object_unlock(attach->dmabuf->resv);
}
EXPORT_SYMBOL_GPL(dma_buf_unmap_attachment);
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index a40f8f586a95..e964077a7e7e 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -128,6 +128,9 @@ struct dma_buf_ops {
* any other kind of sharing that the exporter might wish to make
* available to buffer-users.
*
+ * This is always called with the dmabuf->resv object locked when
+ * no_sgt_cache is true.
+ *
* Returns:
*
* A &sg_table scatter list of or the backing storage of the DMA buffer,
@@ -148,6 +151,9 @@ struct dma_buf_ops {
* It should also unpin the backing storage if this is the last mapping
* of the DMA buffer, it the exporter supports backing storage
* migration.
+ *
+ * This is always called with the dmabuf->resv object locked when
+ * no_sgt_cache is true.
*/
void (*unmap_dma_buf)(struct dma_buf_attachment *,
struct sg_table *,
--
2.14.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5/6] drm/amdgpu: add independent DMA-buf export v3
2018-07-06 14:42 (no subject) Christian König
` (3 preceding siblings ...)
2018-07-06 14:42 ` [PATCH 4/6] dma-buf: lock the reservation object during (un)map_dma_buf v3 Christian König
@ 2018-07-06 14:42 ` Christian König
2018-07-06 14:42 ` [PATCH 6/6] drm/amdgpu: add independent DMA-buf import v4 Christian König
2018-07-06 16:02 ` ✗ Fi.CI.BAT: failure for series starting with [1/6] dma-buf: add caching of sg_table Patchwork
6 siblings, 0 replies; 8+ messages in thread
From: Christian König @ 2018-07-06 14:42 UTC (permalink / raw)
To: intel-gfx
The caching of SGT's is actually quite harmful and should probably removed
altogether when all drivers are audited.
Start by providing a separate DMA-buf export implementation in amdgpu. This is
also a prerequisite of unpinned DMA-buf handling.
v2: fix unintended recursion, remove debugging leftovers
v3: split out from unpinned DMA-buf work
v4: rebase on top of new no_sgt_cache flag
Signed-off-by: Christian König <christian.koenig@amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 -
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 1 -
drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c | 94 +++++++++++++------------------
3 files changed, 40 insertions(+), 56 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 8eaba0f4db10..269664fd00de 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -374,7 +374,6 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj,
void amdgpu_gem_object_close(struct drm_gem_object *obj,
struct drm_file *file_priv);
unsigned long amdgpu_gem_timeout(uint64_t timeout_ns);
-struct sg_table *amdgpu_gem_prime_get_sg_table(struct drm_gem_object *obj);
struct drm_gem_object *
amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
struct dma_buf_attachment *attach,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 06aede194bf8..04ef967e128c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -1138,7 +1138,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_get_sg_table = amdgpu_gem_prime_get_sg_table,
.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,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
index 3ed02f472003..75c70ddbc080 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
@@ -40,22 +40,6 @@
static const struct dma_buf_ops amdgpu_dmabuf_ops;
-/**
- * amdgpu_gem_prime_get_sg_table - &drm_driver.gem_prime_get_sg_table
- * implementation
- * @obj: GEM buffer object
- *
- * Returns:
- * A scatter/gather table for the pinned pages of the buffer object's memory.
- */
-struct sg_table *amdgpu_gem_prime_get_sg_table(struct drm_gem_object *obj)
-{
- struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
- int npages = bo->tbo.num_pages;
-
- return drm_prime_pages_to_sg(bo->tbo.ttm->pages, npages);
-}
-
/**
* amdgpu_gem_prime_vmap - &dma_buf_ops.vmap implementation
* @obj: GEM buffer object
@@ -189,34 +173,29 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
}
/**
- * amdgpu_gem_map_attach - &dma_buf_ops.attach implementation
- * @dma_buf: shared DMA buffer
+ * amdgpu_gem_map_dma_buf - &dma_buf_ops.map_dma_buf implementation
* @attach: DMA-buf attachment
+ * @dir: DMA direction
*
* Makes sure that the shared DMA buffer can be accessed by the target device.
* For now, simply pins it to the GTT domain, where it should be accessible by
* all DMA devices.
*
* Returns:
- * 0 on success or negative error code.
+ * sg_table filled with the DMA addresses to use or ERR_PRT with negative error
+ * code.
*/
-static int amdgpu_gem_map_attach(struct dma_buf *dma_buf,
- struct dma_buf_attachment *attach)
+static struct sg_table *
+amdgpu_gem_map_dma_buf(struct dma_buf_attachment *attach,
+ enum dma_data_direction dir)
{
+ struct dma_buf *dma_buf = attach->dmabuf;
struct drm_gem_object *obj = dma_buf->priv;
struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
+ struct sg_table *sgt;
long r;
- r = drm_gem_map_attach(dma_buf, attach);
- if (r)
- return r;
-
- r = amdgpu_bo_reserve(bo, false);
- if (unlikely(r != 0))
- goto error_detach;
-
-
if (attach->dev->driver != adev->dev->driver) {
/*
* Wait for all shared fences to complete before we switch to future
@@ -227,54 +206,62 @@ static int amdgpu_gem_map_attach(struct dma_buf *dma_buf,
MAX_SCHEDULE_TIMEOUT);
if (unlikely(r < 0)) {
DRM_DEBUG_PRIME("Fence wait failed: %li\n", r);
- goto error_unreserve;
+ return ERR_PTR(r);
}
}
/* pin buffer into GTT */
r = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT);
if (r)
- goto error_unreserve;
+ return ERR_PTR(r);
+
+ sgt = drm_prime_pages_to_sg(bo->tbo.ttm->pages, bo->tbo.num_pages);
+ if (IS_ERR(sgt))
+ return sgt;
+
+ if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
+ DMA_ATTR_SKIP_CPU_SYNC))
+ goto error_free;
if (attach->dev->driver != adev->dev->driver)
bo->prime_shared_count++;
-error_unreserve:
- amdgpu_bo_unreserve(bo);
+ return sgt;
-error_detach:
- if (r)
- drm_gem_map_detach(dma_buf, attach);
- return r;
+error_free:
+ sg_free_table(sgt);
+ kfree(sgt);
+ return ERR_PTR(-ENOMEM);
}
/**
- * amdgpu_gem_map_detach - &dma_buf_ops.detach implementation
- * @dma_buf: shared DMA buffer
+ * amdgpu_gem_unmap_dma_buf - &dma_buf_ops.unmap_dma_buf implementation
* @attach: DMA-buf attachment
+ * @sgt: sg_table to unmap
+ * @dir: DMA direction
*
* This is called when a shared DMA buffer no longer needs to be accessible by
* the other device. For now, simply unpins the buffer from GTT.
*/
-static void amdgpu_gem_map_detach(struct dma_buf *dma_buf,
- struct dma_buf_attachment *attach)
+static void amdgpu_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
+ struct sg_table *sgt,
+ enum dma_data_direction dir)
{
+ struct dma_buf *dma_buf = attach->dmabuf;
struct drm_gem_object *obj = dma_buf->priv;
struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
- int ret = 0;
-
- ret = amdgpu_bo_reserve(bo, true);
- if (unlikely(ret != 0))
- goto error;
amdgpu_bo_unpin(bo);
+
if (attach->dev->driver != adev->dev->driver && bo->prime_shared_count)
bo->prime_shared_count--;
- amdgpu_bo_unreserve(bo);
-error:
- drm_gem_map_detach(dma_buf, attach);
+ if (sgt) {
+ dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+ sg_free_table(sgt);
+ kfree(sgt);
+ }
}
/**
@@ -332,10 +319,9 @@ static int amdgpu_gem_begin_cpu_access(struct dma_buf *dma_buf,
}
static const struct dma_buf_ops amdgpu_dmabuf_ops = {
- .attach = amdgpu_gem_map_attach,
- .detach = amdgpu_gem_map_detach,
- .map_dma_buf = drm_gem_map_dma_buf,
- .unmap_dma_buf = drm_gem_unmap_dma_buf,
+ .no_sgt_cache = true,
+ .map_dma_buf = amdgpu_gem_map_dma_buf,
+ .unmap_dma_buf = amdgpu_gem_unmap_dma_buf,
.release = drm_gem_dmabuf_release,
.begin_cpu_access = amdgpu_gem_begin_cpu_access,
.map = drm_gem_dmabuf_kmap,
--
2.14.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6/6] drm/amdgpu: add independent DMA-buf import v4
2018-07-06 14:42 (no subject) Christian König
` (4 preceding siblings ...)
2018-07-06 14:42 ` [PATCH 5/6] drm/amdgpu: add independent DMA-buf export v3 Christian König
@ 2018-07-06 14:42 ` Christian König
2018-07-06 16:02 ` ✗ Fi.CI.BAT: failure for series starting with [1/6] dma-buf: add caching of sg_table Patchwork
6 siblings, 0 replies; 8+ messages in thread
From: Christian König @ 2018-07-06 14:42 UTC (permalink / raw)
To: intel-gfx
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
Signed-off-by: Christian König <christian.koenig@amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 ----
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 1 -
drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c | 38 +++++++++++++++++++------------
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 34 +++++++++++++++++++++++----
4 files changed, 52 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 269664fd00de..31c6edd77f2e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -374,10 +374,6 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj,
void amdgpu_gem_object_close(struct drm_gem_object *obj,
struct drm_file *file_priv);
unsigned long amdgpu_gem_timeout(uint64_t timeout_ns);
-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 04ef967e128c..c632e14257d2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -1138,7 +1138,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_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
index 75c70ddbc080..13033ff48cb1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
@@ -122,31 +122,28 @@ int amdgpu_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma
}
/**
- * amdgpu_gem_prime_import_sg_table - &drm_driver.gem_prime_import_sg_table
- * implementation
+ * amdgpu_gem_prime_create_obj - create BO for DMA-buf import
+ *
* @dev: DRM device
- * @attach: DMA-buf attachment
- * @sg: Scatter/gather table
+ * @dma_buf: DMA-buf
*
- * Import shared DMA buffer memory exported by another device.
+ * Creates an empty SG BO for DMA-buf import.
*
* Returns:
* A new GEM buffer object 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_gem_prime_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;
@@ -157,11 +154,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);
@@ -377,6 +372,7 @@ struct dma_buf *amdgpu_gem_prime_export(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) {
@@ -391,5 +387,17 @@ struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev,
}
}
- return drm_gem_prime_import(dev, dma_buf);
+ obj = amdgpu_gem_prime_create_obj(dev, dma_buf);
+ if (IS_ERR(obj))
+ return obj;
+
+ attach = dma_buf_attach(dma_buf, dev->dev);
+ 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_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 0e47f15b0f97..ee85e49e3b07 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -43,6 +43,7 @@
#include <linux/pagemap.h>
#include <linux/debugfs.h>
#include <linux/iommu.h>
+#include <linux/dma-buf.h>
#include "amdgpu.h"
#include "amdgpu_object.h"
#include "amdgpu_trace.h"
@@ -798,6 +799,7 @@ struct amdgpu_ttm_gup_task_list {
struct amdgpu_ttm_tt {
struct ttm_dma_tt ttm;
+ struct drm_gem_object *gobj;
u64 offset;
uint64_t userptr;
struct task_struct *usertask;
@@ -1222,6 +1224,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(>t->ttm, bo, page_flags)) {
@@ -1242,7 +1245,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) {
@@ -1255,7 +1257,20 @@ 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_locked(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);
@@ -1282,9 +1297,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);
@@ -1293,7 +1307,17 @@ 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_locked(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.14.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 8+ messages in thread
* ✗ Fi.CI.BAT: failure for series starting with [1/6] dma-buf: add caching of sg_table
2018-07-06 14:42 (no subject) Christian König
` (5 preceding siblings ...)
2018-07-06 14:42 ` [PATCH 6/6] drm/amdgpu: add independent DMA-buf import v4 Christian König
@ 2018-07-06 16:02 ` Patchwork
6 siblings, 0 replies; 8+ messages in thread
From: Patchwork @ 2018-07-06 16:02 UTC (permalink / raw)
To: Christian König; +Cc: intel-gfx
== Series Details ==
Series: series starting with [1/6] dma-buf: add caching of sg_table
URL : https://patchwork.freedesktop.org/series/46080/
State : failure
== Summary ==
Applying: dma-buf: add caching of sg_table
Applying: drm: remove prime sg_table caching
Applying: dma-buf: add dma_buf_(un)map_attachment_locked variants v3
Applying: dma-buf: lock the reservation object during (un)map_dma_buf v3
Applying: drm/amdgpu: add independent DMA-buf export v3
error: sha1 information is lacking or useless (drivers/gpu/drm/amd/amdgpu/amdgpu.h).
error: could not build fake ancestor
Patch failed at 0005 drm/amdgpu: add independent DMA-buf export v3
Use 'git am --show-current-patch' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2018-07-06 16:02 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-07-06 14:42 (no subject) Christian König
2018-07-06 14:42 ` [PATCH 1/6] dma-buf: add caching of sg_table Christian König
2018-07-06 14:42 ` [PATCH 2/6] drm: remove prime sg_table caching Christian König
2018-07-06 14:42 ` [PATCH 3/6] dma-buf: add dma_buf_(un)map_attachment_locked variants v3 Christian König
2018-07-06 14:42 ` [PATCH 4/6] dma-buf: lock the reservation object during (un)map_dma_buf v3 Christian König
2018-07-06 14:42 ` [PATCH 5/6] drm/amdgpu: add independent DMA-buf export v3 Christian König
2018-07-06 14:42 ` [PATCH 6/6] drm/amdgpu: add independent DMA-buf import v4 Christian König
2018-07-06 16:02 ` ✗ Fi.CI.BAT: failure for series starting with [1/6] dma-buf: add caching of sg_table Patchwork
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).