我正在尝试直接从 Linux 中的另一个 PCIe 设备访问 NIC 中的 DMA 地址。具体来说,我正在尝试从 NVIDIA GPU 读取它以绕过 CPU。我研究了零拷贝网络和 DMA 到用户空间的帖子,但他们要么没有回答问题,要么涉及从内核空间到用户空间的一些拷贝。由于延迟不一致,我试图避免使用任何 CPU 时钟,并且我有非常严格的延迟要求。
我获得了我使用的英特尔卡的 NIC 驱动程序(e1000e 驱动程序),并找到了分配环形缓冲区的位置。正如我从之前阅读的一篇论文中了解到的那样,我会对 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
}
我究竟做错了什么?