微知-记一次Linux PCIe驱动DMA正常,RDMA异常的罪魁祸首:pci_set_master

背景

最近写一个PCIe驱动,正常probe、remove,也正常通过iomem操作bar空间,也能通过DPU正常来DMA HOST的内存,但是却遇到了网卡上DMA无法DMA HOST的内存。何因?

根因

最后查出来是因为在PCIe驱动中初始化没有设置pcie设备pdev的pci_set_master

pci_set_master干什么?

先看说明

pci_set_master(pdev); 函数在Linux内核中用于将PCI设备设置为主设备(Bus Master)。主要作用:

  • **启用DMA:**pci_set_master() 通过在PCI_COMMAND寄存器中设置总线主控位(Bus Master bit)来启用DMA。可以让设备直接与内存进行数据传输,而不需要CPU的介入
  • 总线事务控制:当设备被设置为主设备时,它可以控制总线上的其他设备,并发起总线事务。=

如果不调用 pci_set_master(pdev);,PCI设备可能无法作为总线主控进行DMA操作,可能无法控制总线上的其他事务,这可能会影响到设备的功能性和效率。因此,在PCI设备驱动程序中,通常需要调用此函数以确保设备能够充分利用DMA和总线主控的能力。

再看代码

可以看到这里做了两个动作,一个是对PCIe配置空间配置了COMMAND使能master,另一个是bios进行了设置。

/**
 * pci_set_master - enables bus-mastering for device dev
 * @dev: the PCI device to enable
 *
 * Enables bus-mastering on the device and calls pcibios_set_master()
 * to do the needed arch specific settings.
 */
void pci_set_master(struct pci_dev *dev)
{
   
   
	__pci_set_master(dev, true);
	pcibios_set_master(dev);
}

static void __pci_set_master(struct pci_dev *dev, bool enable)
{
   
   
	u16 old_cmd, cmd;

	pci_read_config_word(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值