aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu
diff options
context:
space:
mode:
authorFelix Kuehling <Felix.Kuehling@amd.com>2018-11-20 21:00:29 -0500
committerAlex Deucher <alexander.deucher@amd.com>2018-12-07 18:13:54 -0500
commit1dde0ea95b782425b95455d487cb44991525a1d1 (patch)
tree2033a93a0417699fca78f5e42f1a7512e80c5a76 /drivers/gpu/drm/amd/amdgpu
parent3704d56e1a64bb0e951815f91149ae7bb726aa76 (diff)
drm/amdkfd: Add DMABuf import functionality
This is used for interoperability between ROCm compute and graphics APIs. It allows importing graphics driver BOs into the ROCm SVM address space for zero-copy GPU access. The API is split into two steps (query and import) to allow user mode to manage the virtual address space allocation for the imported buffer. Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c57
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h11
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c55
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c4
5 files changed, 126 insertions, 3 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
index 68b29a210eaa..68e4cf1b655c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
@@ -26,6 +26,7 @@
26#include "amdgpu.h" 26#include "amdgpu.h"
27#include "amdgpu_gfx.h" 27#include "amdgpu_gfx.h"
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/dma-buf.h>
29 30
30const struct kgd2kfd_calls *kgd2kfd; 31const struct kgd2kfd_calls *kgd2kfd;
31 32
@@ -433,6 +434,62 @@ void amdgpu_amdkfd_get_cu_info(struct kgd_dev *kgd, struct kfd_cu_info *cu_info)
433 cu_info->lds_size = acu_info.lds_size; 434 cu_info->lds_size = acu_info.lds_size;
434} 435}
435 436
437int amdgpu_amdkfd_get_dmabuf_info(struct kgd_dev *kgd, int dma_buf_fd,
438 struct kgd_dev **dma_buf_kgd,
439 uint64_t *bo_size, void *metadata_buffer,
440 size_t buffer_size, uint32_t *metadata_size,
441 uint32_t *flags)
442{
443 struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
444 struct dma_buf *dma_buf;
445 struct drm_gem_object *obj;
446 struct amdgpu_bo *bo;
447 uint64_t metadata_flags;
448 int r = -EINVAL;
449
450 dma_buf = dma_buf_get(dma_buf_fd);
451 if (IS_ERR(dma_buf))
452 return PTR_ERR(dma_buf);
453
454 if (dma_buf->ops != &amdgpu_dmabuf_ops)
455 /* Can't handle non-graphics buffers */
456 goto out_put;
457
458 obj = dma_buf->priv;
459 if (obj->dev->driver != adev->ddev->driver)
460 /* Can't handle buffers from different drivers */
461 goto out_put;
462
463 adev = obj->dev->dev_private;
464 bo = gem_to_amdgpu_bo(obj);
465 if (!(bo->preferred_domains & (AMDGPU_GEM_DOMAIN_VRAM |
466 AMDGPU_GEM_DOMAIN_GTT)))
467 /* Only VRAM and GTT BOs are supported */
468 goto out_put;
469
470 r = 0;
471 if (dma_buf_kgd)
472 *dma_buf_kgd = (struct kgd_dev *)adev;
473 if (bo_size)
474 *bo_size = amdgpu_bo_size(bo);
475 if (metadata_size)
476 *metadata_size = bo->metadata_size;
477 if (metadata_buffer)
478 r = amdgpu_bo_get_metadata(bo, metadata_buffer, buffer_size,
479 metadata_size, &metadata_flags);
480 if (flags) {
481 *flags = (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) ?
482 ALLOC_MEM_FLAGS_VRAM : ALLOC_MEM_FLAGS_GTT;
483
484 if (bo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
485 *flags |= ALLOC_MEM_FLAGS_PUBLIC;
486 }
487
488out_put:
489 dma_buf_put(dma_buf);
490 return r;
491}
492
436uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd) 493uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd)
437{ 494{
438 struct amdgpu_device *adev = (struct amdgpu_device *)kgd; 495 struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
index 131c6e5e6f10..70429f7aa9a8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
@@ -149,6 +149,11 @@ uint64_t amdgpu_amdkfd_get_gpu_clock_counter(struct kgd_dev *kgd);
149 149
150uint32_t amdgpu_amdkfd_get_max_engine_clock_in_mhz(struct kgd_dev *kgd); 150uint32_t amdgpu_amdkfd_get_max_engine_clock_in_mhz(struct kgd_dev *kgd);
151void amdgpu_amdkfd_get_cu_info(struct kgd_dev *kgd, struct kfd_cu_info *cu_info); 151void amdgpu_amdkfd_get_cu_info(struct kgd_dev *kgd, struct kfd_cu_info *cu_info);
152int amdgpu_amdkfd_get_dmabuf_info(struct kgd_dev *kgd, int dma_buf_fd,
153 struct kgd_dev **dmabuf_kgd,
154 uint64_t *bo_size, void *metadata_buffer,
155 size_t buffer_size, uint32_t *metadata_size,
156 uint32_t *flags);
152uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd); 157uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd);
153uint64_t amdgpu_amdkfd_get_hive_id(struct kgd_dev *kgd); 158uint64_t amdgpu_amdkfd_get_hive_id(struct kgd_dev *kgd);
154 159
@@ -200,6 +205,12 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info,
200int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct kgd_dev *kgd, 205int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct kgd_dev *kgd,
201 struct kfd_vm_fault_info *info); 206 struct kfd_vm_fault_info *info);
202 207
208int amdgpu_amdkfd_gpuvm_import_dmabuf(struct kgd_dev *kgd,
209 struct dma_buf *dmabuf,
210 uint64_t va, void *vm,
211 struct kgd_mem **mem, uint64_t *size,
212 uint64_t *mmap_offset);
213
203void amdgpu_amdkfd_gpuvm_init_mem_limits(void); 214void amdgpu_amdkfd_gpuvm_init_mem_limits(void);
204void amdgpu_amdkfd_unreserve_memory_limit(struct amdgpu_bo *bo); 215void amdgpu_amdkfd_unreserve_memory_limit(struct amdgpu_bo *bo);
205 216
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index 5fb60e1d713a..a0a500d45886 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -25,6 +25,7 @@
25#include <linux/list.h> 25#include <linux/list.h>
26#include <linux/pagemap.h> 26#include <linux/pagemap.h>
27#include <linux/sched/mm.h> 27#include <linux/sched/mm.h>
28#include <linux/dma-buf.h>
28#include <drm/drmP.h> 29#include <drm/drmP.h>
29#include "amdgpu_object.h" 30#include "amdgpu_object.h"
30#include "amdgpu_vm.h" 31#include "amdgpu_vm.h"
@@ -1664,6 +1665,60 @@ int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct kgd_dev *kgd,
1664 return 0; 1665 return 0;
1665} 1666}
1666 1667
1668int amdgpu_amdkfd_gpuvm_import_dmabuf(struct kgd_dev *kgd,
1669 struct dma_buf *dma_buf,
1670 uint64_t va, void *vm,
1671 struct kgd_mem **mem, uint64_t *size,
1672 uint64_t *mmap_offset)
1673{
1674 struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
1675 struct drm_gem_object *obj;
1676 struct amdgpu_bo *bo;
1677 struct amdgpu_vm *avm = (struct amdgpu_vm *)vm;
1678
1679 if (dma_buf->ops != &amdgpu_dmabuf_ops)
1680 /* Can't handle non-graphics buffers */
1681 return -EINVAL;
1682
1683 obj = dma_buf->priv;
1684 if (obj->dev->dev_private != adev)
1685 /* Can't handle buffers from other devices */
1686 return -EINVAL;
1687
1688 bo = gem_to_amdgpu_bo(obj);
1689 if (!(bo->preferred_domains & (AMDGPU_GEM_DOMAIN_VRAM |
1690 AMDGPU_GEM_DOMAIN_GTT)))
1691 /* Only VRAM and GTT BOs are supported */
1692 return -EINVAL;
1693
1694 *mem = kzalloc(sizeof(struct kgd_mem), GFP_KERNEL);
1695 if (!*mem)
1696 return -ENOMEM;
1697
1698 if (size)
1699 *size = amdgpu_bo_size(bo);
1700
1701 if (mmap_offset)
1702 *mmap_offset = amdgpu_bo_mmap_offset(bo);
1703
1704 INIT_LIST_HEAD(&(*mem)->bo_va_list);
1705 mutex_init(&(*mem)->lock);
1706 (*mem)->mapping_flags =
1707 AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_WRITEABLE |
1708 AMDGPU_VM_PAGE_EXECUTABLE | AMDGPU_VM_MTYPE_NC;
1709
1710 (*mem)->bo = amdgpu_bo_ref(bo);
1711 (*mem)->va = va;
1712 (*mem)->domain = (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) ?
1713 AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT;
1714 (*mem)->mapped_to_gpu_memory = 0;
1715 (*mem)->process_info = avm->process_info;
1716 add_kgd_mem_to_kfd_bo_list(*mem, avm->process_info, false);
1717 amdgpu_sync_create(&(*mem)->sync);
1718
1719 return 0;
1720}
1721
1667/* Evict a userptr BO by stopping the queues if necessary 1722/* Evict a userptr BO by stopping the queues if necessary
1668 * 1723 *
1669 * Runs in MMU notifier, may be in RECLAIM_FS context. This means it 1724 * Runs in MMU notifier, may be in RECLAIM_FS context. This means it
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h
index d63daba9b17c..f1ddfc50bcc7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h
@@ -54,6 +54,8 @@ void *amdgpu_gem_prime_vmap(struct drm_gem_object *obj);
54void amdgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); 54void amdgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
55int amdgpu_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); 55int amdgpu_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
56 56
57extern const struct dma_buf_ops amdgpu_dmabuf_ops;
58
57/* 59/*
58 * GEM objects. 60 * GEM objects.
59 */ 61 */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
index 3e44d889f7af..71913a18d142 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
@@ -39,8 +39,6 @@
39#include <drm/amdgpu_drm.h> 39#include <drm/amdgpu_drm.h>
40#include <linux/dma-buf.h> 40#include <linux/dma-buf.h>
41 41
42static const struct dma_buf_ops amdgpu_dmabuf_ops;
43
44/** 42/**
45 * amdgpu_gem_prime_get_sg_table - &drm_driver.gem_prime_get_sg_table 43 * amdgpu_gem_prime_get_sg_table - &drm_driver.gem_prime_get_sg_table
46 * implementation 44 * implementation
@@ -332,7 +330,7 @@ static int amdgpu_gem_begin_cpu_access(struct dma_buf *dma_buf,
332 return ret; 330 return ret;
333} 331}
334 332
335static const struct dma_buf_ops amdgpu_dmabuf_ops = { 333const struct dma_buf_ops amdgpu_dmabuf_ops = {
336 .attach = amdgpu_gem_map_attach, 334 .attach = amdgpu_gem_map_attach,
337 .detach = amdgpu_gem_map_detach, 335 .detach = amdgpu_gem_map_detach,
338 .map_dma_buf = drm_gem_map_dma_buf, 336 .map_dma_buf = drm_gem_map_dma_buf,