+ abo = ttm_to_amdgpu_bo(vma->vm_private_data);
+
+ if (offset)
+ *offset = addr - vma->vm_start;
+
+ if (adev)
+ *adev = amdgpu_ttm_adev(abo->tbo.bdev);
+exit:
+ mmap_read_unlock(mm);
+ return abo;
+}
+#else
+struct amdgpu_bo *amdgpu_bo_from_address(struct mm_struct *mm,
+ unsigned long addr,
+ unsigned long *offset,
+ struct amdgpu_device
**adev)
+{
+ pr_err("BO from address look-up not supported\n");
+ return NULL;
+}
#endif /* HAVE_STRUCT_DRM_DRV_GEM_OPEN_OBJECT_CALLBACK */
+
+
int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
uint64_t dst_offset, uint32_t byte_count,
struct dma_resv *resv,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
index 747c9669069a..9fbff8dec861 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
@@ -175,6 +175,11 @@ int amdgpu_ttm_init(struct amdgpu_device *adev);
void amdgpu_ttm_fini(struct amdgpu_device *adev);
void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev,
bool enable);
+
+struct amdgpu_bo *amdgpu_bo_from_address(struct mm_struct *mm,
+ unsigned long addr, unsigned long
*offset,
+ struct amdgpu_device **adev);
+
int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
uint64_t dst_offset, uint32_t byte_count,
struct dma_resv *resv,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_peerdirect.c
b/drivers/gpu/drm/amd/amdkfd/kfd_peerdirect.c
index ed93247d83ca..3341f40f2a23 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_peerdirect.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_peerdirect.c
@@ -170,9 +170,13 @@ static int amd_acquire(unsigned long addr, size_t size,
void *peer_mem_private_data,
char *peer_mem_name, void **client_context)
{
- struct kfd_process *p;
- struct kfd_bo *buf_obj;
struct amd_mem_context *mem_context;
+ struct kfd_process *p;
+ struct kfd_bo *buf_obj = NULL;
+ struct kfd_node *dev = NULL;
+ struct amdgpu_bo *bo = NULL;
+ unsigned long offset = 0;
+ uint32_t flags = 0;
if (peer_mem_name == rdma_name) {
p = peer_mem_private_data;
@@ -187,34 +191,44 @@ static int amd_acquire(unsigned long addr, size_t size,
align_addr_size(&addr, &size);
mutex_lock(&p->mutex);
- buf_obj = kfd_process_find_bo_from_interval(p, addr,
- addr + size - 1);
- if (!buf_obj) {
- pr_debug("Cannot find a kfd_bo for the range\n");
- goto out_unlock;
+ buf_obj = kfd_process_find_bo_from_interval(p, addr, addr + size - 1);
+ if (buf_obj) {
+ offset = addr - buf_obj->it.start;
+ bo = amdgpu_amdkfd_gpuvm_get_bo_ref(buf_obj->mem, &flags);
+
+ dev = buf_obj->dev;
+ } else {
+ struct amdgpu_device *adev;
+ /* Memory was allocated via KFD without address, then mapped
later */
+ bo = amdgpu_bo_from_address(p->mm, addr, &offset, &adev);
+ if (!bo)
+ goto out_unlock;
+
+ flags = bo->kfd_bo->alloc_flags;
+ dev = adev->kfd.dev->nodes[bo->xcp_id];
+ drm_gem_object_get(&bo->tbo.base);
}
- /* Initialize context used for operation with given address */
mem_context = kzalloc(sizeof(*mem_context), GFP_KERNEL);
- if (!mem_context)
- goto out_unlock;
+ if (unlikely(!mem_context)) {
+ if (buf_obj)
+ amdgpu_amdkfd_gpuvm_put_bo_ref(bo);
+ else
+ drm_gem_object_put(&bo->tbo.base);
- mem_context->pid = p->lead_thread->pid;
-
- pr_debug("addr: %#lx, size: %#lx, pid: %d\n",
- addr, size, mem_context->pid);
-
- mem_context->va = addr;
- mem_context->size = size;
- mem_context->offset = addr - buf_obj->it.start;
-
- mem_context->bo = amdgpu_amdkfd_gpuvm_get_bo_ref(buf_obj->mem,
- &mem_context->flags);
- mem_context->dev = buf_obj->dev;
+ goto out_unlock;
+ }
mutex_unlock(&p->mutex);
+ pr_debug("addr: %#lx, size: %#lx, pid: %d\n", addr, size,
mem_context->pid);
- pr_debug("Client context: 0x%p\n", mem_context);
+ mem_context->pid = p->lead_thread->pid;
+ mem_context->va = addr;
+ mem_context->size = size;
+ mem_context->dev = dev;
+ mem_context->offset = offset;
+ mem_context->bo = bo;
+ mem_context->flags = flags;
/* Return pointer to allocated context */
*client_context = mem_context;
@@ -223,7 +237,6 @@ static int amd_acquire(unsigned long addr, size_t size,
* by AMD GPU driver
*/
return 1;
-
out_unlock:
mutex_unlock(&p->mutex);
return 0;