DMA over PCIe到其他设备

时间:2013-10-22 19:32:51

标签: linux cuda dma nic pci-e

我试图直接从Linux中的另一个PCIe设备访问NIC中的DMA地址。具体来说,我试图从NVIDIA GPU中读取它,以便一起绕过CPU。我已经研究过零拷贝网络和DMA到用户空间帖子,但他们要么没有回答问题,要么涉及从内核空间到用户空间的一些副本。我试图避免使用任何CPU时钟,因为与延迟不一致,我有非常严格的延迟要求。

我得到了我使用的intel卡(e1000e驱动程序)的NIC驱动程序,我找到了分配环缓冲区的地方。正如我从之前的一篇论文中所理解的那样,我会对dma_addr_t类型的描述符感兴趣。它们还有一个名为dma的rx_ring结构的成员。我使用ioctl调用传递了desc和dma成员,但除了零之外,我无法在GPU中获得任何内容。

GPU代码如下:

int *setup_gpu_dma(u64 addr)                                                     
{                                                                                
    // Allocate GPU memory                                                       
    int *gpu_ptr;                                                                
    cudaMalloc((void **) &gpu_ptr, MEM_SIZE);                                    

    // Allocate memory in user space to read the stuff back                      
    int *h_data;                                                                 
    cudaMallocHost((void **)&h_data, MEM_SIZE);                                  

    // Present FPGA memory to CUDA as CPU locked pages                           
    int error = cudaHostRegister((void **) &addr, MEM_SIZE,                      
        CU_MEMHOSTALLOC_DEVICEMAP);                                              
    cout << "Allocation error = " << error << endl;                              

    // DMA from GPU memory to FPGA memory                                        
    cudaMemcpy((void **) &gpu_ptr, (void **)&addr,   MEM_SIZE, cudaMemcpyHostToDevice);
    cudaMemcpy((void **) &h_data, (void **)&gpu_ptr, MEM_SIZE, cudaMemcpyDeviceToHost);

    // Print the data                                                            

    // Clean up 
}                        

我做错了什么?

1 个答案:

答案 0 :(得分:1)

cudaHostRegister()对已分配的主机内存进行操作,因此您必须传递addr,而不是&addr

如果addr不是主机指针,则不起作用。如果主机指针,那么您的函数接口应该使用void *,然后就不需要进行类型转换。