【问题标题】:Direct Memory Mapping to DIMM直接内存映射到 DIMM
【发布时间】:2018-02-09 23:32:56
【问题描述】:

假设您在Intel x86-64 主板中插入了 2 个 DIMM。所有内存交错(库和通道)都被禁用。

我想做的是从Linux kernel(版本4.11.11)中保留其中一个DIMM的物理内存空间,并为应用程序公开该物理(保留)内存空间。 DIMM 将不会在内存通道中移动。我该怎么做呢?过程是什么?我是内核开发的新手,可以使用指导。

到目前为止我发现了什么:

  1. 要从 Linux 内核保留内存,您可以指定 memmap=nn[KMG]$ss[KMG] 引导参数。此参数将特定内存标记为从 ss 到 ss+nn 的内存保留区域。

  2. mmap 可用于在地址 palen 的进程的地址空间之间建立映射文件描述符 fildes 表示的内存对象的字节,偏移量 offlen 个字节。

保留内存后,我假设需要一些字符设备驱动程序才能将保留的内存公开给用户空间应用程序?想法?


更新

还应注意,需要保留的 DIMM 将位于其自己的专用内存通道中,不会启用任何 bank 或通道交错。

【问题讨论】:

  • 我看不出 DIMM 部分如何融入整个画面。无论如何,像/dev/mem 这样的东西不会吗?我不知道保留的内存是否会被这样的设备映射。
  • @MargaretBloom 关于 DIMM 有什么不清楚的地方?我正在尝试保留其中一个 DIMM 上的所有内存以供内核使用。明白了吗? /dev/mem 代表所有可供内核使用的内存,因此不一定代表我需要的内容。
  • 如果标志 arg 中有任何未使用的位,您可以通过 mmap 的新标志公开它,即定义 MAP_RESERVED_DIMM。 HugeTLBFS 是另一种模型:一个特殊的文件系统,您可以将文件映射到该文件系统上,以获取与后备内存有关的特殊内容的映射。我不是 Linux 内部的专家(只是一个感兴趣的业余爱好者),但您对 char 或块设备的想法也可能会奏效。特别是如果您计划一次只使用一个用户空间进程,否则您如何让他们确定哪些部分已经映射?
  • @PeterCordes 感谢 cmets。我添加了一些更新。服务器平台将禁用内存条和通道交错,必须保留的 DIMM 将在其自己的专用通道中。内存通道中不会出现其他 DIMM。我正在尝试一些预取机制,带宽是我的目标。想法?
  • 好的,这听起来是一个很好的理由想要这个,但我不确定它的效果如何。硬件预取不考虑内存通道,只考虑 L2 和 L3 之间的管道有多忙,或者其他什么。因此,如果它对另一个频道充满了商店,那么预取到您正在测试的频道可能不会发生。 (OTOH,英特尔 CPU 中的大多数预取硬件都在 L2 中,这是每个内核私有的。我不确定来自其他内核的流量对限制预取有多大影响。)仅测试会容易得多一个大部分空闲的系统,如果你能安排的话。

标签: memory memory-management linux-kernel x86-64


【解决方案1】:

映射/dev/mem 是一种简单的方法。我以前做过。来自kernel sourcemmap 实现:

static int mmap_mem(struct file *file, struct vm_area_struct *vma)
{
    size_t size = vma->vm_end - vma->vm_start;
    phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;

    /* It's illegal to wrap around the end of the physical address space. */
    if (offset + (phys_addr_t)size - 1 < offset)
        return -EINVAL;

    if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size))
        return -EINVAL;

    if (!private_mapping_ok(vma))
        return -ENOSYS;

    if (!range_is_allowed(vma->vm_pgoff, size))
        return -EPERM;

    if (!phys_mem_access_prot_allowed(file, vma->vm_pgoff, size,
                        &vma->vm_page_prot))
        return -EINVAL;

    vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
                         size,
                         vma->vm_page_prot);

    vma->vm_ops = &mmap_mem_ops;

    /* Remap-pfn-range will mark the range VM_IO */
    if (remap_pfn_range(vma,
                vma->vm_start,
                vma->vm_pgoff,
                size,
                vma->vm_page_prot)) {
        return -EAGAIN;
    }
    return 0;
}

您可能需要修改的唯一内容是valid_mmap_phys_addr_range(vma-&gt;vm_pgoff, size)。或者您可以编写自己的/dev/mem 驱动程序。

【讨论】:

  • 但这并没有分配/保留那些物理内存区域来阻止它们被用于其他用途,是吗?正如该评论所示,将其映射为VM_IO 意味着什么? mmap(/dev/mem) 很可能是完整答案的有用部分,但我不认为这部分是困难的部分。
  • 使用mem=xx cmdline 让内核仅使用部分内存。比如传递mem=4G会使内核只使用4G以下的内存,那么你可以使用修改后的/dev/mem驱动来映射4G以上的内存。
  • 这是一个有趣的想法,应该适用于没有交错的 OP 设置。你确定/dev/mem 仍然可以访问内核其余部分认为存在的范围之外的内存吗?
  • 不,您不能直接使用/dev/mem 来实现您的目标。正如我发布的那样,您应该对地址检查进行一些修改。
猜你喜欢
  • 2018-06-24
  • 1970-01-01
  • 2015-09-15
  • 2020-04-07
  • 2018-05-24
  • 2018-05-18
  • 1970-01-01
  • 2014-06-04
相关资源
最近更新 更多