标签: pci-e

如何确定PCI/PCIe BAR尺寸?

我知道PCI配置空间中的基地址寄存器(BAR)定义了PCI地址的起始位置,但该区域的大小是如何建立的?

当然这是硬件的属性,因为它只知道它可以处理的地址空间有多远.但是,我似乎无法在PCI配置结构中看到BAR大小字段.

pci pci-e

9
推荐指数
2
解决办法
2万
查看次数

pci_alloc_consistent和dma_alloc_coherent之间的区别

我正在研究基于pcie的网络驱动程序.不同的示例使用pci_alloc_consistentdma_alloc_coherent之一来获取传输和接收描述符的内存.哪一个更好,如果有的话两者有什么区别?

network-programming driver linux-device-driver dma pci-e

9
推荐指数
1
解决办法
4879
查看次数

大型PCIe DMA Linux x86-64

我正在使用高速串行卡进行高速数据传输,从外部源到带有PCIe卡的Linux机箱.PCIe卡带有一些第三方驱动程序,它们使用dma_alloc_coherent分配dma缓冲区来接收数据.但是,由于Linux的限制,这种方法将数据传输限制为4MB.我一直在阅读并尝试多种方法来分配大型DMA缓冲区,并且无法使其工作.

这个系统有32GB的内存,并运行Red Hat,内核版本为3.10,我想为连续的DMA提供4GB的内存.我知道首选的方法是分散/聚集,但在我的情况下这是不可能的,因为有一个硬件芯片将串行协议转换为超出我的控制范围的DMA,我唯一可以控制的是向传入地址(即,从外部系统看到的地址零可以映射到本地总线上的地址0x700000000).

由于这是一次性实验室机器,我认为最快/最简单的方法是使用mem = 28GB启动配置参数.我有这个工作正常,但从虚拟空间访问该内存的下一步是我遇到问题.这是我的代码浓缩到相关组件:

在内核模块中:

size_t len = 0x100000000ULL; // 4GB
size_t phys = 0x700000000ULL; // 28GB
size_t virt = ioremap_nocache( phys, len ); // address not usable via direct reference
size_t bus = (size_t)virt_to_bus( (void*)virt ); // this should be the same as phys for x86-64, shouldn't it?

// OLD WAY
/*size_t len = 0x400000; // 4MB
size_t bus;
size_t virt = dma_alloc_coherent( devHandle, len, &bus, GFP_ATOMIC );
size_t phys = (size_t)virt_to_phys( (void*)virt );*/
Run Code Online (Sandbox Code Playgroud)

在申请中:

// Attempt …
Run Code Online (Sandbox Code Playgroud)

c++ linux redhat dma pci-e

9
推荐指数
1
解决办法
1166
查看次数

MMIO读/写延迟

我发现我的MMIO读/写延迟非常高.我希望有人能给我一些建议.

在内核空间中,我编写了一个简单的程序来读取PCIe设备的BAR0地址中的4字节值.该设备是PCIe Intel 10G NIC,并插在我的Xeon E5服务器上的PCIe x16总线上.我使用rdtsc来测量MMIO读取开始和结束之间的时间,代码片段如下所示:

vaddr = ioremap_nocache(0xf8000000, 128); // addr is the BAR0 of the device  
rdtscl(init); 
ret = readl(vaddr); 
rmb(); 
rdtscl(end);
Run Code Online (Sandbox Code Playgroud)

我期望(end,init)之间的经过时间小于1us,毕竟,遍历PCIe数据链路的数据应该只有几纳秒.但是,我的测试结果显示至少5.5用于执行MMIO PCIe设备读取.我想知道这是否合理.我将我的代码更改为远程内存屏障(rmb),但仍然可以获得大约5美分的延迟.

本文提到了PCIe延迟测量.通常它不到1us.www.cl.cam.ac.uk/~awm22/.../miller2009motivating.pdf我是否需要进行任何特殊配置(如内核或设备)才能获得更低的MMIO访问延迟?或者有没有人有过这样的经历?

linux linux-device-driver pci-bus pci-e

8
推荐指数
1
解决办法
2216
查看次数

TensorFlow 中 CPU 到 GPU 的数据传输速度慢吗?

我已经使用 TensorFlow 测试了 CPU 到 GPU 的数据传输吞吐量,它似乎明显低于 PyTorch。对于大张量,速度要慢 2 倍到 5 倍。在 TF 中,我达到了 25MB 张量的最大速度(~4 GB/s),并且随着张量大小的增加,速度下降到 2 GB/s。PyTorch 数据传输速度随着张量大小而增长,并在 9 GB/s(25MB 张量)时饱和。该行为在 RTX 2080ti 和 GTX 1080ti 以及 TF 2.4 和 2.6 上是一致的。

难道我做错了什么?有什么方法可以匹配 PyTorch 的数据吞吐量吗?我不仅仅是想隐藏延迟,例如使用异步队列,而且我想获得完整的数据带宽。

TF 中批量 256x256x3 图像的结果(平均超过 100 次传输):

code: tf.cast(x, dtype=tf.float32)[0, 0]
Batch size 1; Batch time 0.0005; BPS 1851.8; FPS 1851.8; MB/S 364.1
Batch size 2; Batch time 0.0004; BPS 2223.5; FPS 4447.1; MB/S 874.3
Batch size 4; Batch time 0.0006; BPS 1555.2; FPS …
Run Code Online (Sandbox Code Playgroud)

python performance gpu pci-e tensorflow

8
推荐指数
1
解决办法
1541
查看次数

Linux设备驱动程序允许FPGA直接DMA到CPU RAM

我正在编写一个linux设备驱动程序,允许FPGA(目前通过PCI Express连接到PC)将DMA数据直接写入CPU RAM.这需要在没有任何交互的情况下发生,并且用户空间需要访问数据.一些细节: - 运行64位Fedora 14 - 系统有8GB的RAM - FPGA(Cyclone IV)在PCIe卡上

为了实现这一点,我执行了以下操作: - 使用memmap 6GB $ 2GB保留grub中的2GB内存(不启动是我添加mem = 2GB).我可以看到RAM的上部2GB保留在/ proc/meminfo中 - 映射BAR0以允许读取和写入FPGA寄存器(这完美地工作) - 在我的驱动程序中使用remap_pfn_range()实现了mmap函数 - 使用ioremap获取缓冲区的虚拟地址 - 添加了ioctl调用(用于测试)以将数据写入缓冲区 - 通过进行ioctl调用将数据写入缓冲区并通过用户空间验证数据是否在缓冲区中来测试mmap

我面临的问题是当FPGA开始将DMA数据发送到我提供的缓冲区地址时.我不断得到PTE错误(来自DMAR :)或使用下面的代码我得到以下错误:DMAR:[DMA Write]请求设备[01:00.0] fault addr 186dc5000
DMAR:[fault reason 01] root entry中的当前位是清除DRHD:处理故障状态reg 3

第一行中的地址每次基于来自FPGA的DMA递增0x1000

这是我的init()代码:

#define IMG_BUF_OFFSET     0x180000000UL // Location in RAM (6GB)
#define IMG_BUF_SIZE       0x80000000UL  // Size of the Buffer (2GB)

#define pci_dma_h(addr) ((addr >> 16) >> 16)
#define pci_dma_l(addr) (addr & 0xffffffffUL)

if((pdev = pci_get_device(FPGA_VEN_ID, FPGA_DEV_ID, NULL)))
{
    printk("FPGA …
Run Code Online (Sandbox Code Playgroud)

linux mmap driver dma pci-e

7
推荐指数
1
解决办法
8864
查看次数

如何为可缓存的PCIe BAR执行mmap

我正在尝试mmap()为PCIe BAR 编写一个带有自定义函数的驱动程序,目标是使这个BAR可以在处理器缓存中缓存.我知道这不是实现最高带宽的最佳方式,并且写入顺序是不可预测的(在这种情况下也不是问题).

这类似于如何阻止MMAP缓存值中描述的内容?

处理器是Sandy Bridge i7,PCIe器件是Altera Stratix IV dev.板.

首先,我尝试在CentOS 5(2.6.18)上进行.我改变了MTRR设置,以确保酒吧是不是不可缓存MTRR内,并使用io_remap_pfn_range()_PAGE_PCD_PAGE_PWT清除位.读取按预期工作:读取返回正确的值,第二次读取到同一地址不一定导致读取到PCIe(在FPGA中检查读取计数器).但是,写入导致系统冻结然后重新启动,而日志或屏幕上没有任何消息.

其次,我尝试在具有PAT支持的CentOS 6(2.6.32)上进行.结果是一样的:读取工作正常,写入会导致系统冻结并重新启动.有趣的是,非时间/写入组合完整高速缓存行写入(AVX/SSE)按预期工作,即它们总是进入FPGA并且FPGA观察完整的高速缓存行写入,读取之后返回正确的值.但是,简单的64位写入仍会导致系统冻结/重启.

我也尝试过ioremap_cache()然后iowrite32()在驱动程序代码中.结果是一样的.

我认为这是一个硬件问题,但如果有人可以分享有关正在发生的事情的任何想法,我将不胜感激.

编辑:我能够在CentOS 6上捕获MCE消息:机器检查异常:5 Bank 5:be2000000003110a.

我也尝试在2插槽Sandy Bridge(Romley)上使用相同的代码:读取和非临时写入行为是相同的,简单写入不会导致MCE /崩溃但对系统状态没有影响,即内存中的值不会改变.

此外,我在旧的2插槽Nehalem系统上尝试了相同的代码:简单的写入也会导致MCE,尽管代码不同.

caching mmap pci pci-e

7
推荐指数
1
解决办法
3576
查看次数

在Linux/x86上实现多消息MSI吗?

我正在研究一个FPGA端点的网络驱动程序,它支持PCIe总线上的多消息MSI中断(不是msix).主处理器是运行在CentOS上的x86 Intel i7 620LM,内核为4.2.

FPGA端点正确地在其MSI功能寄存器中公布多个msi向量(0x101 = 32个可能的总向量).

据我所知,内核4.2中添加了多消息功能.不幸的是,当我打电话pci_enable_msi_range(pdev, 1, 32);它只返回1.当我打电话给pci_msi_vec_count(pdev);它返回32.我能够在一个向量上请求一个irq处理程序,它可以按预期工作.

有谁知道在x86架构上的Linux中是否实际支持多消息MSI向量?

更新: 我能够使用不同的SBC和i7-4700EQ处理器启用所有32个MSI向量.这是一个4.4-rc1内核.

更新:也 适用于4.2.

更新: 在这种情况下,问题出在coreboot中.一旦电路板供应商提供更新,我就能够使多个矢量工作.

c interrupt linux-device-driver linux-kernel pci-e

7
推荐指数
2
解决办法
2210
查看次数

什么是Linux内核上下文中的DMA映射和DMA引擎?

什么是Linux内核上下文中的DMA映射和DMA引擎?什么时候可以在Linux设备驱动程序中使用DMA映射API和DMA引擎API?任何真正的Linux设备驱动程序示例作为参考都会很棒.

linux linux-device-driver linux-kernel dma pci-e

7
推荐指数
2
解决办法
7417
查看次数

如何使用 x86-64 和 Linux 在 PCIE 总线上生成零长度读取?

在 PCI Express Base 规范的第 2.2.5 节“第一个/最后一个 DW 字节启用规则”中,它说零长度读取可以用作刷新请求。但是,在 linux 内核文档中,大多数示例仅使用 1B 或 4B 读取请求:

独立于总线的设备访问

如何编写 Linux PCI 驱动程序

我想知道 x86-64 架构是否有可能生成导致 PCI 读取长度为零的指令,如果可以,是否有一些 linux 内核函数可以创建该指令。

linux x86 linux-device-driver linux-kernel pci-e

7
推荐指数
1
解决办法
229
查看次数