页面迁移从CMA(连续内存分配器)区域失败

时间:2014-02-06 05:51:35

标签: linux memory-management linux-kernel linux-device-driver

我面临着CMA的问题。我正在尝试通过CMA(连续内存分配)为运行linux 3.8内核的基于ARM的目标板分配设备内存。

在通过私有cma节点请求内存分配时,会产生“NO memin CMA area”。尽管我们保留了所需的内存。在调试“_alloc_contig_migrate_range”函数时,我们发现某些页面的迁移失败并导致CMA区域中没有mem。

正在迁移“migrate_page_move_mapping(migrate.c)”函数中满足以下条件的页面。

   if (!mapping) {
            /* Anonymous page without mapping */
             if (page_count(page) != 1) {
                         return -EAGAIN;
             }
             return MIGRATEPAGE_SUCCESS;
   }

其他页面失败并从

中的migrate_page_move_mapping()返回
    if (page_count(page) != expected_count ||

                radix_tree_deref_slot_protected(pslot, &mapping->tree_lock) != page) {

                        spin_unlock_irq(&mapping->tree_lock);

        return -EAGAIN;

    }

而page_count(页面) - > 3和expected_count - > 2不匹配,因此会重复返回-EAGAIN。

在查看页面标记时,我发现了标记中的差异。

迁移成功 - > 0xc3a40059

迁移失败 - > 0xc3a0000d

旗帜中的差异是

观察标志 - >                 PG_dirty                 PG_active                 PG_swapbacked                 PG_referenced

迁移成功---->  组  组  组  NOTSET

迁移失败------>  没有设置  没有设置  没有设置  SET

任何建议都会有所帮助。

1 个答案:

答案 0 :(得分:0)

有关CMA迁移可能在3.18之前的内核上失败的几个原因记录在案 here (伙伴分配器会计错误) here (KSM)不支持迁移)

  

与流行的看法相反,Linux内核中的 Contiguous Memory Allocator 框架   并不保证在整个系统生命周期内连续内存的可用性。

CMA的核心概念如下......

  1. 启动时,允许将一定量的内存定义为连续缓冲池。
  2. 在运行时,允许从此连续缓冲池中为常规内存分配请求分配内存(作为最后的手段)。
  3. 每当请求大型连续缓冲区时,

    一个。立即将上面 step2 中分配的页面迁移到常规内存池中。

    湾为请求者提供一个大的连续缓冲区。

  4. 问题在于在某些情况下, 在步骤 3a 中迁移页面可能会失败。这可能是由于:

    • 缺少可用内存 swap 作为迁移已在CMA池中分配的非连续小页面的目标。
    • 进程pin memory/buffers分配给他们的能力。

    由于在更新/替换CMA的单一方法上没有任何理由,它在大多数情况下以其当前形式继续存在,但不能保证在所有可能情况下的连续存储器。随着SMMU的出现以及对其他控制器的分散 - 聚集DMA支持,对大型连续缓冲区的需求也越来越少。

    也就是说,有两种主要方法可以改进CMA,这些方法已经尝试过并在某些圈子中被接受:

    1. GCMA

    2. ZONE CMA

    3. 这两种方法都有其自身的局限性,基于他们认为可以接受的妥协。