映射 MMIO 区域写回不起作用

2024-03-21

我希望对 PCIe 设备的所有读写请求都由 CPU 缓存进行缓存。然而,它并没有像我预期的那样工作。

这些是我对回写 MMIO 区域的假设。

  1. 对 PCIe 设备的写入仅在缓存回写时发生。
  2. TLP 有效负载的大小是缓存块大小 (64B)。

然而,捕获的 TLP 并不符合我的假设。

  1. 每次写入 MMIO 区域时都会写入 PCIe 设备。
  2. TLP 有效负载的大小为 1B。

我写了8个字节0xff使用以下用户空间程序和设备驱动程序连接到 MMIO 区域。

用户程序的一部分

struct pcie_ioctl ioctl_control;
ioctl_control.bar_select = BAR_ID;
ioctl_control.num_bytes_to_write = atoi(argv[1]);
if (ioctl(fd, IOCTL_WRITE_0xFF, &ioctl_control) < 0) {
    printf("ioctl failed\n");
}

设备驱动程序的一部分

case IOCTL_WRITE_0xFF:
{
    int i;
    char *buff;
    struct pci_cdev_struct *pci_cdev = pci_get_drvdata(fpga_pcie_dev.pci_device);
    copy_from_user(&ioctl_control, (void __user *)arg, sizeof(ioctl_control));
    buff = kmalloc(sizeof(char) * ioctl_control.num_bytes_to_write, GFP_KERNEL);
    for (i = 0; i < ioctl_control.num_bytes_to_write; i++) {
        buff[i] = 0xff;
    }
    memcpy(pci_cdev->bar[ioctl_control.bar_select], buff, ioctl_control.num_bytes_to_write);
    kfree(buff);
    break;
}

我修改了 MTRR 以进行相应的 MMIO 区域回写。 MMIO区域从0x0c7300000开始,长度为0x100000(1MB)。以下是cat /proc/mtrr不同政策的结果。请注意,我将每个区域设为独有。

不可缓存

reg00: base=0x080000000 ( 2048MB), size= 1024MB, count=1: uncachable
reg01: base=0x380000000000 (58720256MB), size=524288MB, count=1: uncachable
reg02: base=0x0c0000000 ( 3072MB), size=   64MB, count=1: uncachable
reg03: base=0x0c4000000 ( 3136MB), size=   32MB, count=1: uncachable
reg04: base=0x0c6000000 ( 3168MB), size=   16MB, count=1: uncachable
reg05: base=0x0c7000000 ( 3184MB), size=    1MB, count=1: uncachable
reg06: base=0x0c7100000 ( 3185MB), size=    1MB, count=1: uncachable
reg07: base=0x0c7200000 ( 3186MB), size=    1MB, count=1: uncachable
reg08: base=0x0c7300000 ( 3187MB), size=    1MB, count=1: uncachable
reg09: base=0x0c7400000 ( 3188MB), size=    1MB, count=1: uncachable

写组合

reg00: base=0x080000000 ( 2048MB), size= 1024MB, count=1: uncachable
reg01: base=0x380000000000 (58720256MB), size=524288MB, count=1: uncachable
reg02: base=0x0c0000000 ( 3072MB), size=   64MB, count=1: uncachable
reg03: base=0x0c4000000 ( 3136MB), size=   32MB, count=1: uncachable
reg04: base=0x0c6000000 ( 3168MB), size=   16MB, count=1: uncachable
reg05: base=0x0c7000000 ( 3184MB), size=    1MB, count=1: uncachable
reg06: base=0x0c7100000 ( 3185MB), size=    1MB, count=1: uncachable
reg07: base=0x0c7200000 ( 3186MB), size=    1MB, count=1: uncachable
reg08: base=0x0c7300000 ( 3187MB), size=    1MB, count=1: write-combining
reg09: base=0x0c7400000 ( 3188MB), size=    1MB, count=1: uncachable

回写

reg00: base=0x080000000 ( 2048MB), size= 1024MB, count=1: uncachable
reg01: base=0x380000000000 (58720256MB), size=524288MB, count=1: uncachable
reg02: base=0x0c0000000 ( 3072MB), size=   64MB, count=1: uncachable
reg03: base=0x0c4000000 ( 3136MB), size=   32MB, count=1: uncachable
reg04: base=0x0c6000000 ( 3168MB), size=   16MB, count=1: uncachable
reg05: base=0x0c7000000 ( 3184MB), size=    1MB, count=1: uncachable
reg06: base=0x0c7100000 ( 3185MB), size=    1MB, count=1: uncachable
reg07: base=0x0c7200000 ( 3186MB), size=    1MB, count=1: uncachable
reg08: base=0x0c7300000 ( 3187MB), size=    1MB, count=1: write-back
reg09: base=0x0c7400000 ( 3188MB), size=    1MB, count=1: uncachable

以下是使用不同策略的 8B 写入的波形捕获。我使用集成逻辑分析仪(ILA)来捕获这些波形。请观看pcie_endpoint_litepcietlpdepacketizer_tlp_req_payload_dat when pcie_endpoint_litepcietlpdepacketizer_tlp_req_valid已设置。可以通过计数来统计数据包的数量pcie_endpoint_litepcietlpdepacketizer_tlp_req_valid在这些波形示例中。

  1. 不可缓存: link https://i.stack.imgur.com/ubxfn.png-> 正确,1B x 8 数据包
  2. 写组合: link https://i.stack.imgur.com/wheZf.png-> 正确,8B x 1 包
  3. 回写: link https://i.stack.imgur.com/qCeIc.png-> 意外,1B x 8 数据包

系统配置如下。

  • CPU:英特尔(R) 至强(R) CPU E5-2630 v4 @ 2.20GHz
  • OS:Linux内核4.15.0-38
  • PCIe设备:Xilinx FPGA KC705 编程litepcie https://github.com/enjoy-digital/litepcie

相关链接

  1. 从 x86 CPU 生成 64 字节读取 PCIe TLP https://stackoverflow.com/questions/51918804/generating-a-64-byte-read-pcie-tlp-from-an-x86-cpu
  2. 如何在英特尔® 架构上实施 64B PCIe* 突发传输 https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/pcie-burst-transfer-paper.pdf
  3. 写入组合缓冲区乱序写入和 PCIe https://software.intel.com/en-us/forums/software-tuning-performance-optimization-platform-monitoring/topic/711304
  4. Ryzen 是否支持内存映射 IO 的回写式缓存(通过 PCIe 接口)? https://community.amd.com/thread/229989
  5. MTRR(内存类型范围寄存器)控制 https://www.kernel.org/doc/Documentation/x86/mtrr.txt
  6. 对Linux进行PAT https://www.kernel.org/doc/ols/2008/ols2008v2-pages-135-144.pdf
  7. 深入了解 TLP:PCI Express 设备如何通信(第一部分) http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-1

简而言之,映射 MMIO 区域写回似乎在设计上不起作用。

如果有人发现这是可能的,请上传答案。

我来寻找约翰·麦卡尔平的文章和答案。首先,映射 MMIO 区域写回是不可能的。其次,在某些处理器上可以采取解决方法。

  1. 映射 MMIO 区域写回是不可能的

    引用此链接 https://software.intel.com/en-us/forums/intel-isa-extensions/topic/628155

    仅供参考:WB 类型不适用于内存映射 IO。你可以 对位进行编程以将映射设置为 WB,但系统将 一旦收到不知道如何处理的交易,就会崩溃 处理。理论上可以使用WP或者WT来获取缓存 从 MMIO 读取,但一致性必须在软件中处理。

    引用此链接 https://software.intel.com/en-us/forums/software-tuning-performance-optimization-platform-monitoring/topic/393070

    只有当我将 PAT 和 MTRR 都设置为 WB 时,内核才会崩溃

  2. 在某些处理器上可以采取解决方法

    关于内存映射 IO 区域的缓存访问的注释,John McCalpin https://sites.utexas.edu/jdm4372/2013/05/29/notes-on-cached-access-to-memory-mapped-io-regions/

    有一组映射可以用于至少某些 x86-64处理器,它基于映射MMIO空间twice。 使用一组允许写入组合的属性映射 MMIO 范围 存储(但仅限未缓存的读取)。第二次映射 MMIO 范围 具有一组允许缓存行读取的属性(但仅 未缓存、非写组合存储)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

映射 MMIO 区域写回不起作用 的相关文章

  • xdotool 类型需要很长时间并导致整个桌面冻结

    我一直在使用xdotool type过去只能在快捷方式上输入耸肩xdotool type 这可行 但总是需要相当长的时间 并导致整个桌面冻结 完全冻结 而不仅仅是输入 几秒钟 不过并没有太打扰我 现在我需要一种方法来从文件中读取内容 对其进
  • 使用 MongoDB docker 镜像停止虚拟机而不丢失数据

    我已经在 AWS EC2 上的虚拟机中安装了官方的 MongoDB docker 映像 并且数据库上已经有数据 如果我停止虚拟机 以节省过夜费用 我会丢失数据库中包含的所有数据吗 在这些情况下我怎样才能让它持久 有多种选择可以实现此目的 但
  • 测试linux下磁盘空间不足

    我有一个程序 当写入某个文件的磁盘空间不足时 该程序可能会死掉 我不确定是否是这种情况 我想运行它并查看 但我的测试服务器不会很快耗尽空间 有什么办法可以嘲笑这种行为吗 看起来没有任何方法可以在 Ubuntu 中设置文件夹 文件大小限制 并
  • 使用 sed 将 old-link-url 替换为 new-link-url

    我正在 bash 中编写一个脚本 将 old link url 替换为 new link url 我的问题是 sed 由于斜杠而无法替换 url 如果我只输入一些文字就可以了 my code sed e s old link new lin
  • 原生 Linux 应用程序可像 ResHacker 一样编辑 Win32 PE

    我想运行自动修改 dll服务 用户提交特定的 dll 我在服务器上修改它 然后用户可以下载 dll的修改版本 是否有任何本机 Linux 应用程序提供常见的 Win32 PE 修改功能 例如图标 字符串 加速器 对话等 至少提供命令行或脚本
  • ARM 系统调用的接口是什么?它在 Linux 内核中的何处定义?

    我读过有关 Linux 中的系统调用的内容 并且到处都给出了有关 x86 架构的描述 0x80中断和SYSENTER 但我无法追踪 ARM 架构中系统调用的文件和进程 任何人都可以帮忙吗 我知道的几个相关文件是 arch arm kerne
  • “rep stos”x86 汇编指令序列有什么作用?

    我最近偶然发现了以下汇编指令序列 rep stos dword ptr edi For ecx重复 存储内容eax到哪里edi指向 递增或递减edi 取决于方向标志 每次 4 个字节 通常 这用于memset型操作 通常 该指令简单地写成r
  • 如何知道寄存器是否是“通用寄存器”?

    我试图了解寄存器必须具备什么标准才能被称为 通用寄存器 我相信通用寄存器是一个可以用于任何用途的寄存器 用于计算 将数据移入 移出等 并且是一个没有特殊用途的寄存器 现在我读到了ESP寄存器是通用寄存器 我猜是ESP寄存器可以用于任何事情
  • 如何使用ffmpeg重叠和合并多个音频文件?

    我正在尝试将多个音频文件合并到一个文件中 但我可以使用以下命令来连接 而不是连接 ffmpeg v debug i file1 wav i file2 wav i file3 wav filter complex 0 0 concat n
  • Xenomai 中的周期性线程实时失败

    我正在创建一个周期性线程 它在模拟输出上输出方波信号 我正在使用 Xenomai API 中的 Posix Skin 和 Analogy 我使用示波器测试了代码的实时性能 并查看了方波信号 频率为 1kHz 的延迟 我应该实现 250us
  • 如何在 Linux x86_64 上模拟 iret

    我正在编写一个基于 Intel VT 的调试器 由于当 NMI Exiting 1 时 iret 指令在 vmx guest 中的性能发生了变化 所以我应该自己处理vmx主机中的NMI 否则 guest会出现nmi可重入错误 我查了英特尔手
  • Windows 与 Linux 文本文件读取

    问题是 我最近从 Windows 切换到 Ubuntu 我的一些用于分析数据文件的 python 脚本给了我错误 我不确定如何正确解决 我当前仪器的数据文件输出如下 Header 有关仪器等的各种信息 Data 状态 代码 温度 字段等 0
  • R 未获取用户库

    我有一个带 R 3 6 0 的 Fedora 30 系统 用户库设置在Renviron就像这个 R LIBS USER R LIBS USER R x86 64 redhat linux gnu library 3 6 事实上 它出现在交互
  • 使用 NSCache 实现缓存过期

    我正在使用 NSCache 在我的应用程序中实现缓存 我想为其添加过期时间 以便在一段时间后它将获取新数据 有哪些选择以及最好的方法是什么 我应该查看访问缓存时的时间戳并使之无效吗 缓存是否应该通过使用固定间隔计时器自动使自身失效 缓存是否
  • CPU寄存器和多任务处理

    我目前正在学习汇编 我很困惑 CPU 寄存器如何与多任务一起工作 所以在多任务系统中 CPU可以随时暂停某个程序的执行并运行另一个程序 那么在这一步中寄存器值是如何保存的呢 寄存器是压入堆栈还是以其他方式 CPU 寄存器如何与多任务一起工作
  • 是否从页面缓存中的脏页面进行文件读取?

    当字节写入文件时 内核不会立即将这些字节写入磁盘 而是将这些字节存储在页缓存中的脏页中 回写缓存 问题是 如果在脏页刷新到磁盘之前发出文件读取 则将从缓存中的脏页提供字节 还是首先将脏页刷新到磁盘 然后进行磁盘读取以提供字节 将它们存储在进
  • 如何确保 numpy BLAS 库可用作动态加载库?

    The theano安装文档 http www deeplearning net software theano install html troubleshooting make sure you have a blas library指
  • 在 any() 语句中迭代一个小列表是否更快?

    在低长度迭代的限制下考虑以下操作 d 3 slice None None None slice None None None In 215 timeit any type i slice for i in d 1000000 loops b
  • 如何调用位于其他目录的Makefile?

    我正在尝试这样做 我想打电话给 make Makefile存在于其他目录中 abc可以使用位于不同目录中的 shell 脚本的路径 我该怎么做呢 由于 shell 脚本不允许我cd进入Makefile目录并执行make 我怎样才能编写she
  • 将数组传递给函数名称冲突

    Specs GNU bash 版本 3 1 17 无法升级 Premise 我一直在摆弄数组 我想知道是否有任何方法可以让函数的本地变量与所述函数外部的数组同名 Example 在下面的示例中 我将尝试显示该问题 Working bin b

随机推荐

  • 使用多线程 vb.net 时更新文本框

    My code Imports System IO Public Class Form1 Dim thread As System Threading Thread Dim thread2 As System Threading Threa
  • 如何在Python中比较两个时区?

    Example import pytz b pytz timezone Europe Rome c pytz timezone Europe Berlin 然而 这两个时区具有不同的名称但代表相同的事物 b c 返回 false b zon
  • RStudio Run命令运行两次问题[重复]

    这个问题在这里已经有答案了 我在使用 RStudio 时遇到了一个奇怪的问题 当我使用任何命令运行脚本时 例如 Ctrl R Ctrl Enter 或 RStudio 上的实际运行命令 该命令会运行两次 我在互联网上找不到任何与此相关的信息
  • C++、多态性和迭代器

    我想要一个存储接口 抽象类 和一组存储实现 SQLite MySQL Memcached 用于存储已知类的对象并从存储中检索子集 对我来说 清晰的界面是 class Storable int id blah blah blah string
  • JSP/GlassFish:如何正确设置 UTF-8 编码

    我正在寻求帮助 将堆栈中的所有层都转换为 UTF 8 编码 我发现这篇好文章 http www javapractices com topic TopicAction do Id 206 http www javapractices com
  • AWS - 错误 504 - 网关超时 - Flask 应用程序

    昨天 我在 Amazon Elastic Beanstalk 上部署了我的第一个 Flask 应用程序 应用程序正在运行 但当我按下启动抓取过程的按钮时出现问题 这个过程相当长 可能需要大约 3 4 分钟 显然在我按下按钮一分钟后 我收到了
  • 在 Microsoft SQL Server 中从十六进制文字插入 varbinary 值

    我有一个 SpringBoot 应用程序 我使用 jdbcTemplate 将一行插入到 mssql int numOfRowsAffected remoteJdbcTemplate update insert into dbo ELCOR
  • Python - 用 ASCII 字符替换 unicode 表情符号

    我当前的周末项目之一有问题 我正在编写一个 Python 脚本 它从不同来源获取一些数据 然后将所有内容输出到 esc pos 打印机 正如您可能想象的那样 POS 打印机并不完全喜欢表情符号 所以文本如下 可爱 给我这个字符串 u53ef
  • 如何在带有配置文件的 Powershell 脚本中使用自定义 WCF 代理?

    我在它自己的程序集中有一个手写的 WCF 代理 它非常简单 public class MyServiceClient ClientBase
  • 通过shields.io徽章添加SonarQube覆盖范围

    我有 com github xxxxxx xxxxxx Maven 存储库 我想添加盾牌徽章 但我有一个无效徽章 https img shields io sonar https sonarqube com com github norau
  • GMAIL SMTP:对 SSPI 的调用失败异常 - 不支持请求的功能

    我正在使用 gmail smtp 发送邮件 主机 smtp gmail com 端口 587 在 MVC 应用程序中使用 gmail smtp 发送邮件时出现异常 以下代码用于发送邮件 public static int SendMail
  • Three.js 的外观似乎被翻转了

    我这里有一个演示 测试场地 http www myuplay com game test html or Backup http direct myuplay com game test html 由于某种原因 即使鼠标矢量是正确的 我的对
  • R - 检测到非树模型!此功能只能与树模型一起使用

    我是 R 新手 当我尝试跑步时xgb importance 我得到这个 Error in xgb model dt tree feature names feature names text text Non tree model dete
  • 当父溢出更改时,firefox 过渡会中断

    我今天遇到一个问题 花了我很长时间来调试 我在网上找不到解决方案 所以我认为记录下来会很有用 如果父级的 溢出 属性与转换一起更改 则转换似乎在 Firefox 上不起作用 即 parent overflow hidden parent h
  • 在 MVC 4 中将对象转换为 JSON

    我正在使用将对象转换为 JSONJavaScriptSerializer我可以在服务器代码中看到这个 JSON 输出 UserId 1 UserName Admin 但在用户界面中它被转换为如下所示 quot UserId quot 1 q
  • 不能在常量列表中使用变量索引

    使用设备建模语言 DML 1 4 版 我创建了一个列表参数 例如 param X 0 0 0 0 0 1 我想在使用变量的方法中访问它们 例如 method get var uint32 idx gt uint32 return X idx
  • 如何通过 ID 以外的方式获取 RESTful 资源?

    在某些情况下 我可能需要通过 ID 以外的参数来查找对象 正确的 RESTful 方法是什么 例如我可能想找到一个User by username and password 所以严格的 RESTful GET users 1 行不通 根据R
  • 加速 WPF 调整大小/重绘

    我注意到即使调整空 WPF 窗口的大小也会显示黑色区域 我桌面上的很多程序都没有这些问题 所以我想知道 有没有办法设置调整大小重绘优先级或其他东西 并加快 WPF 窗口大小的调整速度 或者这个问题是不可避免的 这是 WPF 工作方式的继承
  • Java 加密替代硬编码密钥

    我是加密新手 我查看了 javax crypto 文档并使用此代码对文件进行了加密 File saveFile new File Settings set saveFile delete FileOutputStream fout new
  • 映射 MMIO 区域写回不起作用

    我希望对 PCIe 设备的所有读写请求都由 CPU 缓存进行缓存 然而 它并没有像我预期的那样工作 这些是我对回写 MMIO 区域的假设 对 PCIe 设备的写入仅在缓存回写时发生 TLP 有效负载的大小是缓存块大小 64B 然而 捕获的