[Linux 驱动] -- pci_alloc_consistent () 申请DMA空间返回NULL

问题: 在tw686x驱动从linux4.7内核移植到4.4内核的过程中,出现pci_alloc_consistent()函数申请DMA空间,返回NULL

在启动log中出现如下信息:

tw686x 0000:01:00.0:dma0: unable to allocate B-buffer

unable to handle kernel NULL pointer dereference at virtual address 00000000

解决:

    网上的解决方法:

问题描述:

    在ZYNQ上加载一个视频编码芯片驱动失败,芯片接口为PCIE。

    查看现象,是调用 pci_alloc_consistent  申请DMA空间失败。

    这个函数要被调用很多次,前几次成功,然后就失败了,第一反应就是DMA预留空间不足。

问题解决思路:
    1. 在网上看到有 CONSISTENT_DMA_SIZE 这个宏可以定义,但是在我的内核代码中没有发现,然后谷歌了一把,发现这个宏已经被修改。
    2.在谷歌上看到,内核3.5版本以后,内核启动命令行,有一个cma的参数可以控制,于是在设备树种修改启动参数,发现还是没用。
bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk vmalloc=300M cma=64M";
    3.在检查内核启动时,看到这么一条:DMA: preallocated 256 KiB pool for atomic coherent allocations. 刚好我们的驱动也是申请了200多K的DMA后失败了。
      于是在代码中查找这个打印,然后修改DMA分配的大小。
vi arch/arm/mm/dma-mapping.c +320

#define DEFAULT_DMA_COHERENT_POOL_SIZE  SZ_64M

    4.驱动终于加载成功。
    5. 倒退回去,把第2步的cma=64M去掉,发现还是失败。
    6. 一次最终方案:
        a.在内核启动参数中添加cma=64M
        b. 修改DMA大小。
原文:https://blog.csdn.net/tea1896/article/details/50936093 

验证网上的方法可行!!!

实际的实验中,使用了另外一种方法,如下:

pci_alloc_consistent函数实际上是对dma_alloc_coherent函数做了一层封装,函数原型为:

pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)

{

    return dma_alloc_coherent(hwdev  ==  NULL ? NULL : &hwdev->dev,size,dma_handle, GFP_ATOMIC);

}

修改为,在实际调用pci_alloc_consistent函数的地方,直接调用dma_alloc_coherent函数,如下:

virt = dma_alloc_coherent(&dev->pci_dev->dev,len,&vc->dma_descs[pb].phys,GFP_KERNEL);

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值