dma_alloc_wc

这篇具有很好参考价值的文章主要介绍了dma_alloc_wc。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

static inline void *dma_alloc_wc(struct device *dev, size_t size,
                 dma_addr_t *dma_addr, gfp_t gfp)
{
    unsigned long attrs = DMA_ATTR_WRITE_COMBINE;

    if (gfp & __GFP_NOWARN)
        attrs |= DMA_ATTR_NO_WARN;

    return dma_alloc_attrs(dev, size, dma_addr, gfp, attrs);
}

void *dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle,
        gfp_t flag, unsigned long attrs)
{
    const struct dma_map_ops *ops = get_dma_ops(dev);
    void *cpu_addr;

    WARN_ON_ONCE(!dev->coherent_dma_mask);

    if (dma_alloc_from_dev_coherent(dev, size, dma_handle, &cpu_addr))
        return cpu_addr;

    /* let the implementation decide on the zone to allocate from: */
    flag &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);

    if (dma_is_direct(ops))
        cpu_addr = dma_direct_alloc(dev, size, dma_handle, flag, attrs);
    else if (ops->alloc)
        cpu_addr = ops->alloc(dev, size, dma_handle, flag, attrs);
    else
        return NULL;

    debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr);
    return cpu_addr;
}

void *dma_direct_alloc(struct device *dev, size_t size,
        dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
{
    if (!IS_ENABLED(CONFIG_ARCH_HAS_UNCACHED_SEGMENT) &&
        dma_alloc_need_uncached(dev, attrs))
        return arch_dma_alloc(dev, size, dma_handle, gfp, attrs);
    return dma_direct_alloc_pages(dev, size, dma_handle, gfp, attrs);
}

void *dma_direct_alloc_pages(struct device *dev, size_t size,
        dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
{
    struct page *page;
    void *ret;

    page = __dma_direct_alloc_pages(dev, size, dma_handle, gfp, attrs);
    if (!page)
        return NULL;

    if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) &&
        !force_dma_unencrypted(dev)) {
        /* remove any dirty cache lines on the kernel alias */
        if (!PageHighMem(page))
            arch_dma_prep_coherent(page, size);
        *dma_handle = phys_to_dma(dev, page_to_phys(page));
        /* return the page pointer as the opaque cookie */
        return page;
    }

    if (PageHighMem(page)) {
        /*
         * Depending on the cma= arguments and per-arch setup
         * dma_alloc_contiguous could return highmem pages.
         * Without remapping there is no way to return them here,
         * so log an error and fail.
         */
        dev_info(dev, "Rejecting highmem page from CMA.\n");
        __dma_direct_free_pages(dev, size, page);
        return NULL;
    }

    ret = page_address(page);
    if (force_dma_unencrypted(dev)) {
        set_memory_decrypted((unsigned long)ret, 1 << get_order(size));
        *dma_handle = __phys_to_dma(dev, page_to_phys(page));
    } else {
        *dma_handle = phys_to_dma(dev, page_to_phys(page));
    }
    memset(ret, 0, size);

    if (IS_ENABLED(CONFIG_ARCH_HAS_UNCACHED_SEGMENT) &&
        dma_alloc_need_uncached(dev, attrs)) {
        arch_dma_prep_coherent(page, size);
        ret = uncached_kernel_address(ret);
    }

    return ret;
}

struct page *__dma_direct_alloc_pages(struct device *dev, size_t size,
        dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
{
    size_t alloc_size = PAGE_ALIGN(size);
    int node = dev_to_node(dev);
    struct page *page = NULL;
    u64 phys_mask;

    if (attrs & DMA_ATTR_NO_WARN)
        gfp |= __GFP_NOWARN;

    /* we always manually zero the memory once we are done: */
    gfp &= ~__GFP_ZERO;
    gfp |= __dma_direct_optimal_gfp_mask(dev, dev->coherent_dma_mask,
            &phys_mask);
    page = dma_alloc_contiguous(dev, alloc_size, gfp);
    if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) {
        dma_free_contiguous(dev, page, alloc_size);
        page = NULL;
    }
again:
    if (!page)
        page = alloc_pages_node(node, gfp, get_order(alloc_size));
    if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) {
        dma_free_contiguous(dev, page, size);
        page = NULL;

        if (IS_ENABLED(CONFIG_ZONE_DMA32) &&
            phys_mask < DMA_BIT_MASK(64) &&
            !(gfp & (GFP_DMA32 | GFP_DMA))) {
            gfp |= GFP_DMA32;
            goto again;
        }

        if (IS_ENABLED(CONFIG_ZONE_DMA) && !(gfp & GFP_DMA)) {
            gfp = (gfp & ~GFP_DMA32) | GFP_DMA;
            goto again;
        }
    }

    return page;
}文章来源地址https://www.toymoban.com/news/detail-561166.html

/**
 * dma_alloc_contiguous() - allocate contiguous pages
 * @dev:   Pointer to device for which the allocation is performed.
 * @size:  Requested allocation size.
 * @gfp:   Allocation flags.
 *
 * This function allocates contiguous memory buffer for specified device. It
 * first tries to use device specific contiguous memory area if available or
 * the default global one, then tries a fallback allocation of normal pages.
 *
 * Note that it byapss one-page size of allocations from the global area as
 * the addresses within one page are always contiguous, so there is no need
 * to waste CMA pages for that kind; it also helps reduce fragmentations.
 */
struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp)
{
    size_t count = size >> PAGE_SHIFT;
    struct page *page = NULL;
    struct cma *cma = NULL;

    if (dev && dev->cma_area)
        cma = dev->cma_area;
    else if (count > 1)
        cma = dma_contiguous_default_area;

    /* CMA can be used only in the context which permits sleeping */
    if (cma && gfpflags_allow_blocking(gfp)) {
        size_t align = get_order(size);
        size_t cma_align = min_t(size_t, align, CONFIG_CMA_ALIGNMENT);

        page = cma_alloc(cma, count, cma_align, gfp & __GFP_NOWARN);
    }

    return page;
}

到了这里,关于dma_alloc_wc的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WCDMA网络容量及WCDMA 3G网络速度影响因素

    WCDMA网络是一个软容量网络,其与网络的覆盖、质量均有关系,所以在现网中,网络容量不是固定的。 从纯理论角度考虑,一个扇区可以支持120个普通语音用户或30个视频语音用户或15个R99数据用户,这是因为WCDMA网络容量是通过码资源来分配的,单扇区包含16个信道资源(S

    2024年02月05日
    浏览(83)
  • 【Linux】:文件查看 stat、cat、more、less、head、tail、uniq、wc

    🎥 屿小夏 : 个人主页 🔥个人专栏 : Linux深造日志 🌄 莫道桑榆晚,为霞尚满天! 在Linux系统中,文件是信息的核心。深入了解和操作文件内容是每个系统管理员和开发者必备的技能。本文将为您揭开Linux文件魔法的面纱,介绍一系列强大的命令,包括stat、cat、more、less、

    2024年04月28日
    浏览(41)
  • Linux:文件查看:《cat》《more》《less》《head》《tail》《wc》《grep》使用方法

    同样是查看为什么要有这么多查看方法??? 因为他们的用法和扩功能肯定不一样,选择与你需要匹配的一条命令可以节省时间的同时更快速 cat + 文件 可以直接查看文件内的内容  直接可以查看文件内的内容 要直接看更多的文件以空格隔开的方式一起查看文件 more + 文件

    2023年04月26日
    浏览(43)
  • 4-Linux 操作系统进阶指令 du、df、free、find、ps、service、grep、wc、管道

    重点:find 、ps 、grep 、管道 1、du 指令 作用:du表示directory used,显示出目录所占的磁盘空间大小的情况。 语法:#du -sh 目录 路径 选项说明: -s:表示sumary,汇总统计 -h:表示以较高可读性的形式显示 案例:使用du指令统计出“/home”的大小情况 2、df 指令 作用:disk free,查

    2024年02月08日
    浏览(47)
  • Linux DMA子系统(3):DMA设备驱动(consumer)

    目录 1. 前言 2. 重要的结构体 2.1 struct dma_slave_config 2.2 struct dma_async_tx_descriptor 3. 设备驱动使用DMA Engine的方法 3.1 分配一个DMA从通道 3.2 设置DMA通道的具体参数 3.3 获取描述符 3.4 提交传输并启动传输 3.5 等待传输完成 4. 参考文章 上文从DMA控制器驱动的角度去分析了DMA Engin

    2024年02月03日
    浏览(42)
  • Linux DMA子系统(2):DMA控制器驱动(provider)

    目录 1. 前言 2. 重要的结构体 2.1 struct dma_device 2.2 struct dma_chan 2.3 struct virt_dma_chan 3. 重要的API 3.1 注册及注销API 3.2 cookie相关API 4. DMA控制器驱动的编写步骤 5. 参考文章 本文将从DMA控制器驱动(provider)的角度来介绍DMA Engine,包括重要的结构体和API接口。 DMA控制器驱动主要作用

    2023年04月09日
    浏览(39)
  • Linux——内存和DMA

    目录 本章目标: 一、内存组织 二、按页分配内存 三、slab分配器 四、不连续内存页分配 五、per-CPU变量           在前面的所有例子中,我们使用的都是全局变量或在栈上分配的内存。本章我们将先讨论如何动态分配内存和per-CPU变量。类似于 ARM 这样的体系结构,操作硬

    2024年02月07日
    浏览(39)
  • Linux 之 DMA

    DMA(Direct Memory Access,直接内存访问)是一种计算机系统中常用的数据传输方式,它可以让设备在不占用CPU时间的情况下,直接访问内存,实现高速数据传输。在数据传输量大、速度要求高的场景中,DMA可以大大提高系统性能。 DMA传输过程中,通常需要使用一个特殊的硬件设

    2024年02月07日
    浏览(28)
  • Linux DMA 简介

    限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。 本文基于 Linux 4.14 内核源码 + ARM32 架构 进行分析。本文涉及所有代码均来自于开源社区。 DMA 全称为 Direct Memory Access ,通常情形时:通过给定 DMA 控制器 数据的 源地址(从主存传送数据到

    2024年02月16日
    浏览(28)
  • PYTORCH_CUDA_ALLOC_CONF max_split_size_mb | Shell ( Linux ) 环境下的解决措施

    参考文献如下 [1] 通过设置PYTORCH_CUDA_ALLOC_CONF中的max_split_size_mb解决Pytorch的显存碎片化导致的CUDA:Out Of Memory问题 https://blog.csdn.net/MirageTanker/article/details/127998036 [2] shell环境变量说明 https://blog.csdn.net/JOJOY_tester/article/details/90738717 具体解决步骤 报错信息 如下: 计算 reserved - allocat

    2024年02月11日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包