【问题标题】:Contiguous physical memory from userspace来自用户空间的连续物理内存
【发布时间】:2011-05-23 01:29:19
【问题描述】:

有没有办法在 linux 中从用户空间分配连续的物理内存?至少有几个保证连续的内存页。一个巨大的页面不是答案。

【问题讨论】:

  • 你为什么要关心它是否在物理上是连续的?
  • 这样的事情可能很重要的唯一原因是是否涉及 DMA 访问。在这种情况下,应该由内核驱动程序来处理,而不是用户空间。
  • 我们需要它来进行一些内存/缓存性能测试:通过基于缓存关联性的步骤逐步遍历内存并导致缓存未命中,从而使用相同索引填充缓存行。
  • 编写并安装内核驱动程序?
  • 问题是它必须在没有额外内核模块的情况下从用户空间工作

标签: linux memory


【解决方案1】:

没有。那没有。您确实需要从内核空间执行此操作。

如果您说“我们需要从用户空间执行此操作” - 在内核空间中没有任何事情发生,这毫无意义 - 因为用户空间程序无法控制甚至不知道底层内存是否连续。

您需要这样做的唯一原因是,如果您正在与一块硬件或其他需要此要求的低级(即内核)服务一起工作。同样,您必须在 级别处理它。

所以答案不仅仅是“你不能”——而是“你永远不需要”。

我已经编写了这样的内存管理器,确实允许我这样做 - 但这始终是因为内核级别的一些潜在问题,必须在内核级别解决。通常是因为总线上的一些其他代理(PCI 卡、BIOS 甚至是通过 RDMA 接口的另一台计算机)具有物理连续内存要求。同样,所有这些都必须在内核空间中解决。

当您谈论“缓存行”时 - 您无需担心。您可以放心,您的用户空间内存的每个 page 都是连续的,并且每个 page 都比缓存行大得多(无论您在谈论什么架构大约)。

【讨论】:

  • 为了完整起见,这将如何从内核空间完成? kmalloc?
  • 编写一个模块/设备驱动程序,使用“get_free_pages”来分配适当的(连续的)页面数量。伙伴系统,然后让该驱动程序向该内存公开一个 MMAP 接口。并不是说您通常可能必须在启动时运行此权限以确保内存没有足够的碎片以不允许此操作(取决于您需要多少内存) - 如果内存不足,它可能会失败。
  • 人们提出问题是因为他们手头有问题需要解决。例如 Knights Landing 在 MCDRAM 中带有直接映射缓存。如果您可以将经常使用的数据粘贴到相同的 16gb 物理范围内,则可以确保不会发生导致缓存抖动的缓存冲突。
  • 那么,hugetlb 的匿名 mmap 可能是一个答案 - 但 OP 说“客户不想这样做”。我并不是在争论有时需要这样做——只是在用户空间中没有定义明确、可靠的方法来做到这一点。英特尔 SPDK 试图解决这个问题——并且有一些公认的 hacky 方法来做到这一点。 ..
【解决方案2】:

是的,如果您只需要几页,这确实是可能的。

文件/proc/[pid]/pagemap 现在允许程序检查其虚拟内存到物理内存的映射。

虽然您不能显式修改映射,但可以只分配一个虚拟页面,通过调用mlock 将其锁定到内存中,通过查找/proc/self/pagemap 记录其物理地址,并重复直到你刚刚发生以获得足够的块相互接触以创建一个足够大的连续块。然后解锁并释放多余的积木。

它很老套、笨重而且可能很慢,但值得一试。另一方面,这很有可能不是您真正需要的。

【讨论】:

    【解决方案3】:

    DPDK 库的内存分配器使用@Wallacoloo 描述的方法。 eal_memory.c。该代码已获得 BSD 许可。

    【讨论】:

    • 看起来 DPDK 现在正在托管自己的代码。 this 似乎是新的 eal_memory.c url。
    • 链接再次断开
    【解决方案4】:

    如果特定设备驱动导出物理连续的 dma 缓冲区,用户空间可以通过 dma buf apis 访问 所以用户任务可以访问但不能直接分配

    这是因为物理上连续的约束不是来自用户应用程序,而是来自设备 所以只有设备驱动程序才应该关心。

    【讨论】:

      猜你喜欢
      • 2014-03-28
      • 2017-10-27
      • 2012-01-08
      • 2017-11-16
      • 2014-06-10
      • 1970-01-01
      • 2010-10-24
      • 1970-01-01
      相关资源
      最近更新 更多