[Why]
Enable RDMA service when platform has IOMMU ON. The handle of device
to DMA map is available only in dma_map() call context.

[How]
Update implementation get_pages() such that it only Pins memory of a
buffer object. Update implementation dma_map() to use the handle of
DMA device in building an sg_table off of the buffer object

Signed-off-by: Ramesh Errabolu <[email protected]>
---
 drivers/gpu/drm/amd/amdkfd/kfd_peerdirect.c | 47 +++++++++++++++++++--
 drivers/gpu/drm/amd/amdkfd/kfd_rdma.c       | 26 +++++++-----
 2 files changed, 59 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_peerdirect.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_peerdirect.c
index 6d7340b101ba..86b4ee710629 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_peerdirect.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_peerdirect.c
@@ -54,7 +54,6 @@
 #include "kfd_priv.h"
 
 
-
 /* ----------------------- PeerDirect interface 
------------------------------*/
 
 /*
@@ -281,6 +280,14 @@ static int amd_get_pages(unsigned long addr, size_t size, 
int write, int force,
 static int amd_dma_map(struct sg_table *sg_head, void *client_context,
                        struct device *dma_device, int dmasync, int *nmap)
 {
+       struct sg_table *sg_table_tmp;
+       struct kfd_bo *buf_obj;
+       struct kfd_dev *dev;
+       struct kgd_mem *mem;
+       uint64_t offset;
+       uint64_t length;
+       int ret;
+
        /*
         * NOTE/TODO:
         * We could have potentially three cases for real memory
@@ -312,15 +319,33 @@ static int amd_dma_map(struct sg_table *sg_head, void 
*client_context,
                        mem_context->size);
 
        if (!mem_context->p2p_info) {
-               pr_err("No sg table were allocated\n");
+               pr_err("Buffer was not pinned\n");
                return -EINVAL;
        }
 
+       /* Retrieve the handle of buffer object embedded in amd_p2p_info */
+       buf_obj = mem_context->p2p_info->priv;
+       mem = buf_obj->mem;
+       dev = buf_obj->dev;
+       offset = mem_context->va - buf_obj->it.start;
+       length = mem_context->p2p_info->size;
+
+       /* Build sg_table for buffer being exported, including DMA mapping */
+       ret = amdgpu_amdkfd_gpuvm_get_sg_table(dev->kgd, mem,
+                       offset, length, &sg_table_tmp);
+       if (ret) {
+               pr_err("Building of sg_table failed\n");
+               return -EFAULT;
+       }
+
+       /* Maintain a copy of the handle to sg_table */
+       mem_context->p2p_info->pages = sg_table_tmp;
+
        /* Copy information about previosly allocated sg_table */
-       *sg_head = *mem_context->p2p_info->pages;
+       *sg_head = *sg_table_tmp;
 
        /* Return number of pages */
-       *nmap = mem_context->p2p_info->pages->nents;
+       *nmap = sg_table_tmp->nents;
 
        return 0;
 }
@@ -328,6 +353,7 @@ static int amd_dma_map(struct sg_table *sg_head, void 
*client_context,
 static int amd_dma_unmap(struct sg_table *sg_head, void *client_context,
                           struct device  *dma_device)
 {
+       struct sg_table *sg_table_tmp;
        struct amd_mem_context *mem_context =
                (struct amd_mem_context *)client_context;
 
@@ -339,6 +365,19 @@ static int amd_dma_unmap(struct sg_table *sg_head, void 
*client_context,
                        mem_context->va,
                        mem_context->size);
 
+       /* Determine if sg_table construction was successful */
+       if (!mem_context->p2p_info) {
+               pr_err("Buffer was not pinned\n");
+               return -EINVAL;
+       }
+
+       /* Free sg_table and its elements including DMA unmapping */
+       sg_table_tmp = mem_context->p2p_info->pages;
+       if (sg_table_tmp != NULL) {
+               mem_context->p2p_info->pages = NULL;
+               amdgpu_amdkfd_gpuvm_put_sg_table(sg_table_tmp);
+       }
+
        /* Assume success */
        return 0;
 }
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_rdma.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_rdma.c
index ec6435aa33bd..67a9213a40b3 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_rdma.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_rdma.c
@@ -66,7 +66,6 @@ static int get_pages(uint64_t address, uint64_t length, 
struct pid *pid,
 {
        struct kfd_bo *buf_obj;
        struct kgd_mem *mem;
-       struct sg_table *sg_table_tmp;
        struct kfd_dev *dev;
        uint64_t last = address + length - 1;
        uint64_t offset;
@@ -99,10 +98,9 @@ static int get_pages(uint64_t address, uint64_t length, 
struct pid *pid,
        dev = buf_obj->dev;
        offset = address - buf_obj->it.start;
 
-       ret = amdgpu_amdkfd_gpuvm_pin_get_sg_table(dev->kgd, mem,
-                       offset, length, &sg_table_tmp);
+       ret = amdgpu_amdkfd_gpuvm_pin_bo(mem);
        if (ret) {
-               pr_err("amdgpu_amdkfd_gpuvm_pin_get_sg_table failed.\n");
+               pr_err("Pinning of buffer failed.\n");
                *amd_p2p_data = NULL;
                goto free_mem;
        }
@@ -111,7 +109,6 @@ static int get_pages(uint64_t address, uint64_t length, 
struct pid *pid,
        rdma_cb_data->amd_p2p_data.size = length;
        rdma_cb_data->amd_p2p_data.pid = pid;
        rdma_cb_data->amd_p2p_data.priv = buf_obj;
-       rdma_cb_data->amd_p2p_data.pages = sg_table_tmp;
        rdma_cb_data->amd_p2p_data.kfd_proc = p;
 
        rdma_cb_data->free_callback = free_callback;
@@ -140,24 +137,33 @@ static int put_pages_helper(struct amd_p2p_info *p2p_data)
 {
        struct kfd_bo *buf_obj;
        struct kfd_dev *dev;
-       struct sg_table *sg_table_tmp;
        struct rdma_cb *rdma_cb_data;
+       struct sg_table *sg_table_tmp;
 
        if (!p2p_data) {
                pr_err("amd_p2p_info pointer is invalid.\n");
                return -EINVAL;
        }
 
-       rdma_cb_data = container_of(p2p_data, struct rdma_cb, amd_p2p_data);
+       /* Determine if sg_table been released */
+       sg_table_tmp = p2p_data->pages;
+       if (sg_table_tmp != NULL) {
+               p2p_data->pages = NULL;
+               amdgpu_amdkfd_gpuvm_put_sg_table(sg_table_tmp);
+       }
 
+       /* Unpin pages of buffer object */
        buf_obj = p2p_data->priv;
-       dev = buf_obj->dev;
-       sg_table_tmp = p2p_data->pages;
+       p2p_data->priv = NULL;
+       if (buf_obj != NULL)
+               amdgpu_amdkfd_gpuvm_unpin_bo(buf_obj->mem);
 
+        /* Remove callback info from list of callback objects */
+       rdma_cb_data = container_of(p2p_data, struct rdma_cb, amd_p2p_data);
        list_del(&rdma_cb_data->node);
        kfree(rdma_cb_data);
 
-       amdgpu_amdkfd_gpuvm_unpin_put_sg_table(buf_obj->mem, sg_table_tmp);
+       dev = buf_obj->dev;
        kfd_dec_compute_active(dev);
 
        return 0;
-- 
2.29.2

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to