mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-26 14:17:26 -04:00
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@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/337948/
This commit is contained in:
parent
6e6db2722c
commit
a39414716c
4 changed files with 53 additions and 29 deletions
|
@ -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
|
* amdgpu_dma_buf_create_obj - create BO for DMA-buf import
|
||||||
* implementation
|
|
||||||
* @dev: DRM device
|
|
||||||
* @attach: DMA-buf attachment
|
|
||||||
* @sg: Scatter/gather table
|
|
||||||
*
|
*
|
||||||
* Imports shared DMA buffer memory exported by another device.
|
* @dev: DRM device
|
||||||
|
* @dma_buf: DMA-buf
|
||||||
|
*
|
||||||
|
* Creates an empty SG BO for DMA-buf import.
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* A new GEM BO of the given DRM device, representing the memory
|
* A new GEM BO of the given DRM device, representing the memory
|
||||||
* described by the given DMA-buf attachment and scatter/gather table.
|
* described by the given DMA-buf attachment and scatter/gather table.
|
||||||
*/
|
*/
|
||||||
struct drm_gem_object *
|
static struct drm_gem_object *
|
||||||
amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
|
amdgpu_dma_buf_create_obj(struct drm_device *dev, struct dma_buf *dma_buf)
|
||||||
struct dma_buf_attachment *attach,
|
|
||||||
struct sg_table *sg)
|
|
||||||
{
|
{
|
||||||
struct dma_resv *resv = attach->dmabuf->resv;
|
struct dma_resv *resv = dma_buf->resv;
|
||||||
struct amdgpu_device *adev = dev->dev_private;
|
struct amdgpu_device *adev = dev->dev_private;
|
||||||
struct amdgpu_bo *bo;
|
struct amdgpu_bo *bo;
|
||||||
struct amdgpu_bo_param bp;
|
struct amdgpu_bo_param bp;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
memset(&bp, 0, sizeof(bp));
|
memset(&bp, 0, sizeof(bp));
|
||||||
bp.size = attach->dmabuf->size;
|
bp.size = dma_buf->size;
|
||||||
bp.byte_align = PAGE_SIZE;
|
bp.byte_align = PAGE_SIZE;
|
||||||
bp.domain = AMDGPU_GEM_DOMAIN_CPU;
|
bp.domain = AMDGPU_GEM_DOMAIN_CPU;
|
||||||
bp.flags = 0;
|
bp.flags = 0;
|
||||||
|
@ -405,11 +402,9 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
bo->tbo.sg = sg;
|
|
||||||
bo->tbo.ttm->sg = sg;
|
|
||||||
bo->allowed_domains = AMDGPU_GEM_DOMAIN_GTT;
|
bo->allowed_domains = AMDGPU_GEM_DOMAIN_GTT;
|
||||||
bo->preferred_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;
|
bo->prime_shared_count = 1;
|
||||||
|
|
||||||
dma_resv_unlock(resv);
|
dma_resv_unlock(resv);
|
||||||
|
@ -425,15 +420,15 @@ error:
|
||||||
* @dev: DRM device
|
* @dev: DRM device
|
||||||
* @dma_buf: Shared DMA buffer
|
* @dma_buf: Shared DMA buffer
|
||||||
*
|
*
|
||||||
* The main work is done by the &drm_gem_prime_import helper, which in turn
|
* Import a dma_buf into a the driver and potentially create a new GEM object.
|
||||||
* uses &amdgpu_gem_prime_import_sg_table.
|
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* GEM BO representing the shared DMA buffer for the given device.
|
* GEM BO representing the shared DMA buffer for the given device.
|
||||||
*/
|
*/
|
||||||
struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev,
|
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;
|
struct drm_gem_object *obj;
|
||||||
|
|
||||||
if (dma_buf->ops == &amdgpu_dmabuf_ops) {
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,6 @@
|
||||||
|
|
||||||
#include <drm/drm_gem.h>
|
#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,
|
struct dma_buf *amdgpu_gem_prime_export(struct drm_gem_object *gobj,
|
||||||
int flags);
|
int flags);
|
||||||
struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev,
|
struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev,
|
||||||
|
|
|
@ -1445,7 +1445,6 @@ static struct drm_driver kms_driver = {
|
||||||
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
|
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
|
||||||
.gem_prime_export = amdgpu_gem_prime_export,
|
.gem_prime_export = amdgpu_gem_prime_export,
|
||||||
.gem_prime_import = amdgpu_gem_prime_import,
|
.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_vmap = amdgpu_gem_prime_vmap,
|
||||||
.gem_prime_vunmap = amdgpu_gem_prime_vunmap,
|
.gem_prime_vunmap = amdgpu_gem_prime_vunmap,
|
||||||
.gem_prime_mmap = amdgpu_gem_prime_mmap,
|
.gem_prime_mmap = amdgpu_gem_prime_mmap,
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/swap.h>
|
#include <linux/swap.h>
|
||||||
#include <linux/swiotlb.h>
|
#include <linux/swiotlb.h>
|
||||||
|
#include <linux/dma-buf.h>
|
||||||
|
|
||||||
#include <drm/ttm/ttm_bo_api.h>
|
#include <drm/ttm/ttm_bo_api.h>
|
||||||
#include <drm/ttm/ttm_bo_driver.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 amdgpu_ttm_tt {
|
||||||
struct ttm_dma_tt ttm;
|
struct ttm_dma_tt ttm;
|
||||||
|
struct drm_gem_object *gobj;
|
||||||
u64 offset;
|
u64 offset;
|
||||||
uint64_t userptr;
|
uint64_t userptr;
|
||||||
struct task_struct *usertask;
|
struct task_struct *usertask;
|
||||||
|
@ -1227,6 +1229,7 @@ static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_buffer_object *bo,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
gtt->ttm.ttm.func = &amdgpu_backend_func;
|
gtt->ttm.ttm.func = &amdgpu_backend_func;
|
||||||
|
gtt->gobj = &bo->base;
|
||||||
|
|
||||||
/* allocate space for the uninitialized page entries */
|
/* allocate space for the uninitialized page entries */
|
||||||
if (ttm_sg_tt_init(>t->ttm, bo, page_flags)) {
|
if (ttm_sg_tt_init(>t->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_device *adev = amdgpu_ttm_adev(ttm->bdev);
|
||||||
struct amdgpu_ttm_tt *gtt = (void *)ttm;
|
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() */
|
/* user pages are bound by amdgpu_ttm_tt_pin_userptr() */
|
||||||
if (gtt && gtt->userptr) {
|
if (gtt && gtt->userptr) {
|
||||||
|
@ -1260,7 +1262,19 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm,
|
||||||
return 0;
|
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,
|
drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
|
||||||
gtt->ttm.dma_address,
|
gtt->ttm.dma_address,
|
||||||
ttm->num_pages);
|
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)
|
static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev;
|
|
||||||
struct amdgpu_ttm_tt *gtt = (void *)ttm;
|
struct amdgpu_ttm_tt *gtt = (void *)ttm;
|
||||||
bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
|
struct amdgpu_device *adev;
|
||||||
|
|
||||||
if (gtt && gtt->userptr) {
|
if (gtt && gtt->userptr) {
|
||||||
amdgpu_ttm_tt_set_user_pages(ttm, NULL);
|
amdgpu_ttm_tt_set_user_pages(ttm, NULL);
|
||||||
|
@ -1298,7 +1311,16 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm)
|
||||||
return;
|
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;
|
return;
|
||||||
|
|
||||||
adev = amdgpu_ttm_adev(ttm->bdev);
|
adev = amdgpu_ttm_adev(ttm->bdev);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue