使用mmap和/proc/mtrr访问无法缓存的区域 [英] Accessing uncachable region using mmap and /proc/mtrr

查看:131
本文介绍了使用mmap和/proc/mtrr访问无法缓存的区域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在玩mmap和/proc/mtrr,目的是对物理内存分析做一些深入的分析.这是我正在尝试做的基本思想,以及到目前为止所做的总结.我使用的是Ubuntu内核版本3.5.0-54(通用).

I am playing around with mmap and /proc/mtrr in an effort to do some in-depth analysis on physical memory analysis. Here is the basic idea of what I am trying to do and a summary of what I have done so far. I am on Ubuntu kernel version 3.5.0-54-generic.

我基本上是映射到特定的物理地址(使用/proc/iomem的提示),并测量对该物理地址范围的访问延迟.到目前为止,这是我所做的:

I am basically mmapping to a specific physical address (using hints from /proc/iomem) and measuring access latency to this physical address range. Here is what I have done so far:

  1. 在/proc/mtrr中创建了一个条目,以使我无法映射的物理地址范围无法实现.
  2. 使用/dev/mem映射到特定地址.为了从/dev/mem读取1 MB以上的内存,我不得不放宽了安全限制.

尽管我能够毫无问题地执行程序,但我对不可固定的部分是否确实有效存在一些疑问.这是我正在使用的代码片段.请注意,我使用了先前研究论文中的伪代码来创建此代码.

While, I am able to execute the program with no issues, I have some doubts about whether the uncachable part actually works. Here is a snippet of code I am using. Note that I have used a pseudocode from a prior research paper to create this code.

  int main(int argc, char *argv[]) {  
    int fd; // file descriptor to open /dev/mem
    struct timespec time1, time2;
    fd = open("/dev/mem", O_RDWR|O_SYNC);
    if (fd == -1) {
        printf("\n Error opening /dev/mem");
        return 0;
    }
    struct timespec t1, t2;
    char *addr = (char*)mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0x20000);
    if (addr == MAP_FAILED) {
      printf("\n mmap() failed");
    } 
    // Begin accessing 
    char *addr1 = addr;
    char *addr2 = addr1 + 64; // add cache line

    unsigned int i = 0;
    unsigned int j = 0;
    // Begin accessing uncached region
    while(j < 8192){
        i = 0;
        while(i < 500) {
            *addr1 = *addr2 + i;
            *addr2 = *addr1 + i;
            i = i+1;
        }
        j = j + 64;
        addr2 = addr1 + j;
    }
    if (munmap(addr, 8192) == -1) {
         printf("\n Unmapping failed");
         return 0;
    }
    printf("\n Success......");
    return 0;
}

我根据输出/proc/iomem使用偏移量0x20000,如下所示(仅显示相关信息):

I use the offset 0x20000 based on the output /proc/iomem as shown below (showing only relevant info):

00000000-0000ffff : reserved
**00010000-0009e3ff : System RAM**
0009e400-0009ffff : RAM buffer
000a0000-000bffff : PCI Bus 0000:00
000a0000-000b0000 : PCI Bus 0000:20
000c0000-000effff : PCI Bus 0000:00

以下是/proc/mtrr中的条目:

The following are the entries in /proc/mtrr:

reg00: base=0x0d3f00000 ( 3391MB), size=    1MB, count=1: uncachable
reg01: base=0x0d4000000 ( 3392MB), size=   64MB, count=1: uncachable
reg02: base=0x0d8000000 ( 3456MB), size=  128MB, count=1: uncachable
reg03: base=0x0e0000000 ( 3584MB), size=  512MB, count=1: uncachable
reg04: base=0x000020000 (    0MB), size=    8KB, count=1: uncachable

如您所见,最后一个条目使感兴趣的地址区域不可分离.

As you can see, the final entry makes the interested address region uncachable.

虽然我在运行代码时没有遇到问题,但是我有以下问题:

While I have no problems running the code, I have the following concerns:

  1. 选择表示为系统RAM的特定物理地址范围进行读/写是否正确?我的理解是该地址范围用于存储数据和代码.除了使用hexdump读取/dev/mem之外,我还观察到地址区域未初始化(设置为0).
  2. 要检查对未缓存区域的访问是否实际上未缓存,我执行了一个perf stat -e cache-misses:u来衡量发生了多少次缓存未命中.我得到的数字在128,200范围内.对我来说,这确认了地址没有被缓存并且正像循环中一样进入RAM,我正在执行(8192/64)* 500 * 2 = 128,000次访问.我用另一段相似的代码进行了相同的性能练习,其中的mmap被替换为长度相同的字符数组的动态内存分配.在这种情况下,性能统计报告的缓存未命中率要低得多.
  3. 要重新检查是否确实绕过缓存并转到内存,我将偏移量更改为系统RAM范围内的另一个值(例如0x80000),并运行了perf命令以测量发生了多少次缓存未命中.这里的混乱之处在于,它报告的回退次数几乎与前一种情况相同(大约128,200).我期望的东西要少得多,因为我没有使该物理地址区域无法固定.

任何有关了解此观察结果的建议/反馈都将有所帮助.

Any suggestions/feedback on this to understand this observation would be helpful.

谢谢

推荐答案

我想我明白了.手册页中的MAP_PRIVATE表示所做的更改不会反映到基础文件中.将其更改为MAP_SHARED并启用/proc/mtrr中的条目后,缓存未命中和命中次数的变化将发生显着变化.

I think I figured it out. MAP_PRIVATE from the man pages says that the changes are not reflected to the underlying file. On changing it to MAP_SHARED, and enabling the entry in /proc/mtrr, the change in the number of cache misses and hits change significantly.

这篇关于使用mmap和/proc/mtrr访问无法缓存的区域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆