From 609390990c039a76dac049350851b0e43d5e07e1 Mon Sep 17 00:00:00 2001 From: Philip Yang Date: Tue, 28 May 2024 11:20:53 -0400 Subject: [PATCH] rdmatest: Fix amdp2ptest driver mmap mmap system call parameter vma->vm_start, vm_end is mmap virtual address start, end, vma->vm_pgoff is rdma buffer GPU address, which is used to find the sg_table dma_address. Handle multiple sg table nents case because sg->length is limited to max 2GB. Change-Id: I677dd6662ee58f0b5c93f8eef32b7009e1e890d8 Signed-off-by: Philip Yang Signed-off-by: Chris Freehill [ROCm/ROCR-Runtime commit: 9d9fbceefb681c8951373b924b45a7c529c3b207] --- .../tests/rdma/simple/drv/amdp2ptest.c | 67 +++++++++---------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/projects/rocr-runtime/libhsakmt/tests/rdma/simple/drv/amdp2ptest.c b/projects/rocr-runtime/libhsakmt/tests/rdma/simple/drv/amdp2ptest.c index 868a3f8bcc..8df75d01b2 100644 --- a/projects/rocr-runtime/libhsakmt/tests/rdma/simple/drv/amdp2ptest.c +++ b/projects/rocr-runtime/libhsakmt/tests/rdma/simple/drv/amdp2ptest.c @@ -303,38 +303,27 @@ static int amdp2ptest_mmap(struct file *filp, struct vm_area_struct *vma) struct scatterlist *sg; struct va_pages_node *va_pages = NULL; struct amdp2ptest_pages_list *list = filp->private_data; - size_t size = vma->vm_end - vma->vm_start; struct list_head *p, *n; uint64_t gpu_va = vma->vm_pgoff << PAGE_SHIFT; MSG_INFO("Mapping to CPU user space\n"); - MSG_INFO("Begin vm_end 0x%lx, vm_start 0x%lx\n", vma->vm_end, - vma->vm_start); - MSG_INFO("vm_pgoff / pfn 0x%lx\n", vma->vm_pgoff); - MSG_INFO("gpu_va / phys. address 0x%llx\n", gpu_va); + MSG_INFO("Begin vm_start 0x%lx, vm_end 0x%lx\n", vma->vm_start, vma->vm_end); + MSG_INFO("vm_pgoff 0x%lx\n", vma->vm_pgoff); + MSG_INFO("gpu_va address 0x%llx\n", gpu_va); - if (size != PAGE_SIZE) { - MSG_ERR("Mapping works now only per page size=%ld", PAGE_SIZE); - return -EINVAL; - } - - /* This is the first very simple version of getting CPU pointer for - * the single page. - * The logic is the following: - * - We get GPU VA address and enumerate list to find "get_pages" - * node for such range - * - Then we enumerate sg table to find the correct dma_address - * - * NOTE/TODO: Assumption is that the page size is 4KB to allow testing - * of the basic logic. Eventually more complex logic must be added. - */ list_for_each_safe(p, n, &list->head) { + unsigned long addr = vma->vm_start; + long mmap_size = vma->vm_end - vma->vm_start; + long size; + int ret; + va_pages = list_entry(p, struct va_pages_node, node); - if (va_pages->pages->va >= gpu_va && - (va_pages->pages->va + va_pages->pages->size) - < vma->vm_end) { + MSG_INFO("node va 0x%llx size 0x%llx\n", va_pages->pages->va, + va_pages->pages->size); + if (gpu_va >= va_pages->pages->va && + gpu_va + size <= va_pages->pages->va + va_pages->pages->size) { MSG_INFO("Found node: va=0x%llx,size=0x%llx,nents %d\n", va_pages->pages->va, va_pages->pages->size, @@ -342,23 +331,29 @@ static int amdp2ptest_mmap(struct file *filp, struct vm_area_struct *vma) for_each_sg(va_pages->pages->pages->sgl, sg, va_pages->pages->pages->nents, i) { - if (va_pages->pages->va + (i * sg->length) == - gpu_va) { - MSG_INFO("Found page[%d]: dma 0x%llx\n", - i, sg->dma_address); + MSG_INFO("Found page[%d]: dma 0x%llx size 0x%x\n", + i, sg->dma_address, sg->length); - if (remap_pfn_range(vma, - vma->vm_start, - sg->dma_address, - size, - vma->vm_page_prot)) { - MSG_ERR("Failed remap_pfn()\n"); - return -EINVAL; - } - return 0; + size = min_t(unsigned long, sg->length, mmap_size); + MSG_INFO("remap_pfn range addr 0x%lx to dma_addr 0x%llx size 0x%lx\n", + addr, sg->dma_address, size); + ret = remap_pfn_range(vma, + addr, + sg->dma_address >> PAGE_SHIFT, + size, + vma->vm_page_prot); + if (ret) { + MSG_ERR("Failed remap_pfn() size 0x%lx ret %d\n", + size, ret); + return ret; } + addr += size; + mmap_size -= size; + if (mmap_size <= 0) + break; } + return 0; } }