linux - MMIO 读/写延迟

标签 linux linux-device-driver pci-e pci-bus

我发现我的 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);

我希望 (end, init) 之间耗时小于 1us,毕竟穿越 PCIe 数据链路的数据应该只有几纳秒。但是,我的测试结果显示至少 5.5use 可以读取 MMIO PCIe 设备。我想知道这是否合理。我将我的代码更改为远程内存屏障 (rmb) ,但仍然有大约 5 us 的延迟。

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

最佳答案

5usec 太棒了!在统计上循环执行此操作,您可能会发现更大的值。

这有几个原因。 BAR 通常是不可缓存和不可预取的 - 使用 pci_resource_flags() 检查您的 BAR。如果 BAR 被标记为可缓存,那么缓存一致性——确保所有 CPU 缓存相同值的过程可能是一个问题。

其次,阅读 io 始终是非发布的事情。 CPU 必须停止,直到它获得在某些数据总线上进行通信的许可,然后再停止一点,直到数据到达所述总线。该总线看起来像内存,但实际上并非如此,停顿可能是不可中断的忙碌等待,但它仍然是非生产性的。因此,我预计即使在您开始考虑任务抢占之前,最坏情况下的延迟也会远高于 5us。

关于linux - MMIO 读/写延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17770823/

相关文章:

c++ - 如何将 C/C++ 插件安装到 Netbeans (linux)

mysql - 我如何告诉 linux bash 忽略反引号?

linux - 执行 modprobe 时未找到模块

基于 Linux 构建的 Android 内核

x86 - 从 x86 CPU 生成 64 字节读取 PCIe TLP

linux - 运行 nvme 测试用例时出错

linux - 用于获取 USB 信息的 udev/Bash 脚本

linux - 将列表转换为双引号逗号分隔的字符串

linux - u-boot 中的 uart 驱动程序将在哪个位置被删除并在引导时插入内核的 uart 驱动程序?

linux - 扇区大小不是 4096 的 xfs 文件系统导致英特尔 NVMe 驱动器性能下降