__GFP_DIRECT_RECLAIM 对smmu申请memory的函数是申请物理不连续的内存?

在swiotlb的alloc函数中
static void *__dma_alloc_coherent(struct device *dev, size_t size,
                  dma_addr_t *dma_handle, gfp_t flags,
                  unsigned long attrs)
{
    if (dev == NULL) {
        WARN_ONCE(1, "Use an actual device structure for DMA allocation\n");
        return NULL;
    }

    if (IS_ENABLED(CONFIG_ZONE_DMA) &&
        dev->coherent_dma_mask <= DMA_BIT_MASK(32))
        flags |= GFP_DMA;
    if (dev_get_cma_area(dev) && gfpflags_allow_blocking(flags)) {
        struct page *page;
        void *addr;

        page = dma_alloc_from_contiguous(dev, size >> PAGE_SHIFT,
                            get_order(size));
        if (!page)
            return NULL;

        *dma_handle = phys_to_dma(dev, page_to_phys(page));
        addr = page_address(page);
        memset(addr, 0, size);
        return addr;
    } else {
        return swiotlb_alloc_coherent(dev, size, dma_handle, flags);
    }
}
首先会判断是否打开了CONFIG_ZONE_DMA  且dev的coherent_dma_mask <=DMA_BIT_MASK(32)的话,会在flag中设置dma的flag,但是这个时候如果是能了cma的话,这个flag感觉有没有作用,是被丢弃了,这里吐槽一下.
static inline bool gfpflags_allow_blocking(const gfp_t gfp_flags)
{
    return !!(gfp_flags & __GFP_DIRECT_RECLAIM);
}

在__dma_alloc_coherent 中如果使能了cma也用户设置了__GFP_DIRECT_RECLAIM 就调用cma来申请内存,但是如果cma申请失败,就直接返回error了,并没有转到使用swiotlb_alloc_coherent 来申请,这里再吐槽一下。

同样smmu的iommu_dma_ops中的 __iommu_alloc_attrs
static void *__iommu_alloc_attrs(struct device *dev, size_t size,
                 dma_addr_t *handle, gfp_t gfp,
                 unsigned long attrs)
{
    bool coherent = is_device_dma_coherent(dev);
    int ioprot = dma_direction_to_prot(DMA_BIDIRECTIONAL, coherent);
    size_t iosize = size;
    void *addr;

    if (WARN(!dev, "cannot create IOMMU mapping for unknown device\n"))
        return NULL;

    size = PAGE_ALIGN(size);

    /*
     * Some drivers rely on this, and we probably don't want the
     * possibility of stale kernel data being read by devices anyway.
     */
    gfp |= __GFP_ZERO;

    if (gfpflags_allow_blocking(gfp)) {
        struct page **pages;
        pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL, coherent);

        pages = iommu_dma_alloc(dev, iosize, gfp, attrs, ioprot,
                    handle, flush_page);
        if (!pages)
            return NULL;

        addr = dma_common_pages_remap(pages, size, VM_USERMAP, prot,
                          __builtin_return_address(0));
        if (!addr)
            iommu_dma_free(dev, pages, iosize, handle);
    } else {
        struct page *page;
        /*
         * In atomic context we can't remap anything, so we'll only
         * get the virtually contiguous buffer we need by way of a
         * physically contiguous allocation.
         */
        if (coherent) {
            page = alloc_pages(gfp, get_order(size));
            addr = page ? page_address(page) : NULL;
        } else {
            addr = __alloc_from_pool(size, &page, gfp);
        }
        if (!addr)
            return NULL;

        *handle = iommu_dma_map_page(dev, page, 0, iosize, ioprot);
        if (iommu_dma_mapping_error(dev, *handle)) {
            if (coherent)
                __free_pages(page, get_order(size));
            else
                __free_from_pool(addr, size);
            addr = NULL;
        }
    }
    return addr;
}
也会判断__GFP_DIRECT_RECLAIM 这个标志,如果设置了这个标志就调用iommu_dma_alloc 来申请物理不连续的内存,如果没有设置这个标志就先通过alloc_pages 申请连续的物理内存。

难道这个__GFP_DIRECT_RECLAIM 针对开启smmu和没有开启smmu的含义完全相反吗?
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值