ROCT内存申请、注册、映射

一、总览

1. CPU DDR物理内存对应的虚拟地址全部来自于SVM aperture

    GPU DDR物理内存对应的虚拟地址根据芯片系列决定来自于gpuvm_aperture或SVM aperture

2. 关于CPU DDR中的userptr区域给GPU访问的原理讨论

    1)userptr就是CPU已经申请的CPU DDR空间,现在要register给KFD,再映射给GPU访问

    2)register memory API调用过程 (上图的所有DDR处理路径,只有register路径会使用vm_object_t中的userptr成员来记录userptr的值<地址>,其他所有DDR处理路径vm_object_t->userptr都为空)

hsaKmtRegisterMemory
    fmm_register_memory
        object = vm_find_object(address, &aperture)
            vm_find_object_by_userptr
                vm_find_object_by_address_userptr
                    start = cur->userptr
        fmm_register_user_memory
            aperture = svm.dgpu_aperture;
            __fmm_allocate_device(aperture, &obj)
                aperture_allocate_area               //svm.dgpu_aperture中分出可用的VM
                fmm_allocate_memory_object
                    aperture_allcate_object
                        vm_create_and_init_object
                            object->start = start    //记录从svm.dgpu_aperture中分配的VM
                            //vm_object_t插入到aperture->user_tree
                            rbtree_insert(&aperture->user_tree, &obj->user_node) 
            obj->userptr = addr;                     //userptr

    3) 总结:a) 注册userptr到kfd的时候,从svm.dgpu_aperture中分出一块GPUVM,调用ioctl(AMDKFD_IOC_ALLOC_MEMORY_OF_GPU)接口将这个GPUVM注册到KFD,并基于该svm.aperture/GPUVM/kfd返回的handle创建vm_object_t结构,并将userptr记录到vm_object_t->user_ptr域。b) 基于userptr查找vm_object_t的时候,用传入的userptr挨个匹配系统所有aperture(为了兼容非userptr注册到kfd情况,vm_find_object所有DDR处理路径共用),显然是匹配不到任何aperture。于是,强制指定svm.dgpu_aperture作为vm_object_t的aperture。然后在aperture->user_tree(针对userptr的rbtree)中搜索该userptr对应的vm_object_t node(以userptr和size作为key来搜索rbtree),找到vm_object_t node后判断obj->userptr与传入的userptr是否相等以及obj->userptr_size与传入的size是否相等,若都相等,则返回找到的vm_object_t结构。

二、VM管理细节

大前提

GTT/HBM是以4KB为最小单元进行管理的,userptr和paged memory并不是以4KB为最小单元进行管理,可以很碎,所以在注册和映射userptr的时候一定要注意非页对齐和页对齐的转换,详见hsaKmtRegisterMemory分析。在申请paged memory的时候,我们在从SVM aperture中分配svm_addr的时候,已经确保了分配出来的svm_addr是page aligned,所以,不太需要对page_offset做特别处理

1、内存分配

1.调用mxkwAllocMemory分配paged-memory/GTT(non-paged memory)/HBM,CPUVM都来自于SVM aperture,GPUVM来自于GPUVM aperture中的一种。对于paged-memory,物理内存通过mmap匿名映射的方式分配;对于GTT/HBM,物理内存通过mmap(map_fd)的方式分配。

2、userptr注册

1).调用hsaKmtRegisterMemory将userptr注册给GPU,GPUVM来自SVM aperture。通过ioctl到KMD(AMDKFD_IOC_ALLOC_MEMORY_OF_GPU,args.va=svm_mem, args.mmap_offset=*mmap_offset<userptr页对齐处理后的地址——userptr注册到KMD,KMD会用GTT页表将这段内存管理起来,所以,这块内存站在CPU的角度,它是userptr内存,站在GPU的角度,他是GTT内存,GTT内存只能按页进行管理,所以这里要传入页对齐的aligned_addr>,该ioctl会在KMD创建BO)。然后,创建vm_object_t, obj->start=svm_mem,将obj插入SVM aperture->tree。最后,记录obj->userptr=userptr, obj->userptr_size=size,并将obj插入SVM aperture->user_tree。(一个obj记录了两个地址svm<GPU访问用的地址>和userptr)

2).调用hsaKmtMapMemoryToGPU(根据hsaKmtRegisterMemory创建的BO建立映射关系)。通过传入的userptr查找 SVM aperture的user_tree,返回vm_object_t,通过vm_object_t找到需要映射到svm_addr,通过userptr计算page_offset,返回映射到的地址svm_addr+page_offset(由于userptr map以后GTT内存只能按页来管理,所以SVM_addr是页对齐的,需要加上页内偏移,才能访问真实数据)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

denglin12315

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值