首页 > 解决方案 > mmap 支持截面图吗?

问题描述

我希望在用户空间中映射一个内存块来读/写,用一个文件映射。内存块大小超过12M。为了提高性能,我想要map with section,但我跟踪linux内核(4.19),似乎只支持页面映射。调用栈是remap_pfn_range-->remap_p4d_range->remap_p4d_range->remap_pmd_range。在remap_pmd_range函数中,为什么不支持section map呢?

static inline int remap_pmd_range(struct mm_struct *mm, pud_t *pud,
            unsigned long addr, unsigned long end,
            unsigned long pfn, pgprot_t prot)
{
    pmd_t *pmd;
    unsigned long next;
    int err;

    pfn -= addr >> PAGE_SHIFT;
    pmd = pmd_alloc(mm, pud, addr);
    if (!pmd)
        return -ENOMEM;
    VM_BUG_ON(pmd_trans_huge(*pmd));
    do {
        next = pmd_addr_end(addr, end);
        err = remap_pte_range(mm, pmd, addr, next,
                pfn + (addr >> PAGE_SHIFT), prot);
        if (err)
            return err;
    } while (pmd++, addr = next, addr != end);
    return 0;
}

不过还有一个类似的功能,支持剖面图,代码如下:

static inline int ioremap_pmd_range(pud_t *pud, unsigned long addr,
        unsigned long end, phys_addr_t phys_addr, pgprot_t prot)
{
    pmd_t *pmd;
    unsigned long next;

    phys_addr -= addr;
    pmd = pmd_alloc(&init_mm, pud, addr);
    if (!pmd)
        return -ENOMEM;
    do {
        next = pmd_addr_end(addr, end);

        if (ioremap_pmd_enabled() &&
            ((next - addr) == PMD_SIZE) &&
            IS_ALIGNED(phys_addr + addr, PMD_SIZE) &&
            pmd_free_pte_page(pmd, addr)) {
            if (pmd_set_huge(pmd, phys_addr + addr, prot)) /* support section map*/
                continue;
        }

        if (ioremap_pte_range(pmd, addr, next, phys_addr + addr, prot))
            return -ENOMEM;
    } while (pmd++, addr = next, addr != end);
    return 0;
}

我不知道为什么ioremap_pmd_range 支持section map,但是remap_pmd_range 不支持,谁能帮忙解释一下为什么?有什么办法让mmap map with section?

标签: dictionarymmaparm64pmdmmu

解决方案


推荐阅读