繁体   English   中英

映射MMIO区域回写不起作用

Mapping MMIO region write-back does not work

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

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

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

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

但是,捕获的TLP不遵循我的假设。

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

我使用以下用户空间程序和设备驱动程序向MMIO区域写入8字节的0xff

用户程序的一部分

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_datpcie_endpoint_litepcietlpdepacketizer_tlp_req_valid设置。 您可以通过计算这些波形示例中的pcie_endpoint_litepcietlpdepacketizer_tlp_req_valid来计算数据包的数量。

  1. Uncacheablelink - > correct,1B x 8包
  2. 写入组合链接 - >正确,8B x 1数据包
  3. 回写链接 - >意外,1B x 8数据包

系统配置如下。

  • CPU :Intel(R)Xeon(R)CPU E5-2630 v4 @ 2.20GHz
  • 操作系统 :Linux内核4.15.0-38
  • PCIe器件 :采用litepcie编程的Xilinx FPGA KC705

相关链接

  1. 从x86 CPU生成64字节读取PCIe TLP
  2. 如何在英特尔®架构上实现64B PCIe *突发传输
  3. 写入组合缓冲区无序写入和PCIe
  4. Ryzen是否支持内存映射IO的回写缓存(通过PCIe接口)?
  5. MTRR(存储器类型范围寄存器)控制
  6. PATting Linux
  7. 下至TLP:PCI Express设备如何通话(第一部分)
1 个回复

简而言之,映射MMIO区域回写似乎不适用于设计。

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

我来找John McCalpin的文章和答案。 首先,不可能映射MMIO区域回写。 其次,某些处理器可以采用解决方法。

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

    从这个链接引用

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

    从这个链接引用

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

  2. 某些处理器可以解决方法

    关于缓存访问内存映射IO区域的注意事项,John McCalpin

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

1 Python-回写功能不起作用

这是我的数字游戏学校项目代码:我试图将用户名和分数存储在数据库中,然后打印所有用户名和分数的列表。 当我运行代码时,用户的姓名和分数每次都会被覆盖,并且以前的用户和分数不会保存。 writeback = True函数是否应该防止数据被覆盖? ...

2 写注册,读回和比较不起作用

我正在编写一段C代码,在其中我将一些值写入寄存器(从i2c设备),从寄存器中读回值,然后比较值是否相同。 看起来像这样: 到目前为止,还可以。 函数void write_to_i2c将消息写入i2c寄存器。该消息是i2c从设备的寄存器地址和必须写入该寄存器的值。 函数“ rea ...

3 串行写不起作用

我正在尝试使用本教程提供的代码示例在iPhone的串行端口上写char“ b”,但是我没有得到想要的结果。 当我使用此链接提供的串行控制台应用程序时,似乎正在向Arduino发送字母/ char“ b”,因为我的灯开始闪烁。 我为要发送“ b”字符​​的应用程序构造的方法如下所示, ...

4 如何从 PCIe 中的 BAR 地址计算 MMIO 映射区域的大小

我一直在深入研究 PCIe 的一般工作原理,但我被困在许多书籍和网站都在谈论 PCIe 配置空间的地方。 到目前为止,我了解到的是,对于每个分配的设备及其 BDF(总线设备功能位),该设备对应一个 4KB 的配置空间,其中包括 64B 区域,如下所示: 我了解每个基地址寄存器(代表内存映射区域)的 ...

6 #如果区域不起作用

我想使用#if语句在val2为true时跳过序列化val ,而在val2为false时序列化val 。 但是我的代码似乎不起作用: 我必须怎么做才能使其正常工作? 谢谢 ...

7 MMIO读/写延迟

我发现我的MMIO读取/写入延迟过高。 我希望有人能给我一些建议。 在内核空间中,我编写了一个简单的程序来读取PCIe设备的BAR0地址中的4字节值。 该设备是PCIe Intel 10G NIC,并且已插入我的Xeon E5服务器上的PCIe x16总线上。 我使用rdtsc测量M ...

8 Sessionhandler写不起作用?

我使用symfony http-foundation / session在php中进行会话存储。我的问题是下面的代码。 会话文件已创建到指定目录。当我使用代码时,但是在设置任何数据时写入过程均不起作用。 有什么问题? 。感谢您的回复。 ...

9 在文件上写不起作用

我有一个问题是: 我有一个程序可以在抛出File.WriteAllText的文件上进行写操作,并且在关闭它所写的活动之前,它可以正常工作。 当我关闭该活动时,该文件尚未保存我所做的更改。 可能是什么问题? ...

10 Java FileOutputStream写不起作用

我在这里遵循了该教程: http : //www.mkyong.com/java/how-to-write-to-file-in-java-fileoutputstream-example/ 并已实现以下代码为例: 但是没有任何内容写入score.txt文件。 编辑:整个功能 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2021 STACKOOM.COM