dma传输与memcpy传输对比测试程序

本文介绍了一个使用Linux DMA引擎进行大规模数据传输的测试模块,详细阐述了内存分配、通道请求及数据异步复制过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
 * DMA test module
 *
 * Copyright (C) 2007 KEDACOM Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/init.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/random.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/highmem.h>
#include <linux/mm.h>
#include <linux/dma-mapping.h>
#include <linux/async_tx.h>
#include <linux/jiffies.h>

#define XFER_TIMES 4000
#define XFER_LEN  1<<20

void *dma_src,*dma_dest;
struct dma_chan *chan = NULL;

static int __init dmatest_init(void)
{

    int xfer_order = get_order(XFER_LEN);
    int i,ret ;
    dma_cap_mask_t mask;
    dma_cookie_t cookie;
    enum dma_status status;
    u64 j1,j2;

    dma_src = __get_free_pages(GFP_KERNEL | GFP_DMA, xfer_order);
    if (!dma_src) {
        printk(KERN_ALERT "dma_src :alloc memory fail.\n");
        ret = -ENOMEM;
        goto CLEAN;

    }
    
    dma_dest = __get_free_pages(GFP_KERNEL | GFP_DMA, xfer_order);
    if (!dma_dest) {
        printk(KERN_ALERT "dma_dest :alloc memory fail.\n");
        ret = -ENOMEM;
        goto CLEAN;
    }
    printk(KERN_NOTICE"dma_src=%#x,dma_dest=%#x\n",dma_src,dma_dest);    
    dma_cap_zero(mask);
    dma_cap_set(DMA_MEMCPY, mask);
    chan = dma_request_channel(mask, NULL, NULL);
    
    if (chan) {
        printk(KERN_NOTICE "dma_request_channel ok,current channel is : %s\n",dma_chan_name(chan));
    }else {
        printk(KERN_NOTICE "dma_request_channel fail,no dma channel available.\n");
        ret = -1;
        goto CLEAN;
    }
    
    j1 = get_jiffies_64();
    for(i =0;i<XFER_TIMES;i++) {
        cookie = dma_async_memcpy_buf_to_buf(chan, dma_dest, dma_src, XFER_LEN);
        if (dma_submit_error(cookie)) {
            printk(KERN_NOTICE"submit error\n");
            ret = -1;
            goto CLEAN;
        }
    }
    
    dma_async_memcpy_issue_pending(chan);
    do {
        status = dma_async_memcpy_complete(chan, cookie, NULL, NULL);
    
    } while (status == DMA_IN_PROGRESS);

    if (status != DMA_SUCCESS)
        printk(KERN_NOTICE "dma xfer dont accomplish,status=%d\n",status);
    j2 = get_jiffies_64();
    printk(KERN_NOTICE"dma xfer time cost:%d ms.\n",jiffies_to_msecs(j2-j1));

    j1 = get_jiffies_64();
    for(i =0;i<XFER_TIMES;i++){
        memcpy(dma_dest, dma_src, XFER_LEN);
    }
    j2 = get_jiffies_64();
    printk(KERN_NOTICE"memcpy time cost:%d ms.\n",jiffies_to_msecs(j2-j1));
    return 0;

CLEAN:
    if (chan)
        dma_release_channel(chan);

    if (dma_src)
        free_pages(dma_src,xfer_order);

    if (dma_dest)
        free_pages(dma_dest,xfer_order);

    return ret;

}
/* when compiled-in wait for drivers to load first */
module_init(dmatest_init);

static void __exit dmatest_exit(void)
{
    if (chan)
        dma_release_channel(chan);

    if (dma_src)
        free_pages(dma_src,get_order(XFER_LEN));

    if (dma_dest)
        free_pages(dma_dest,get_order(XFER_LEN));

}
module_exit(dmatest_exit);

MODULE_AUTHOR("ZhangZhuan <zhangzhuan@kedacom.com>");
MODULE_LICENSE("GPL v2");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值