linux内核中的哪段负责传输功能的代码调用过dma相关的API,请一定要给出linux源码中真实存在的代码,而不是自己编写代码
时间: 2024-05-16 09:17:53 浏览: 4
在 Linux 内核中,DMA 相关的 API 主要是由 dmaengine 子系统提供的。这个子系统的代码位于内核源码树的 drivers/dma 目录下,其中包括了一系列的 DMA 控制器驱动和 DMA 设备驱动。
下面以在网络传输中调用 DMA 相关的 API 为例,给出 Linux 内核中真实存在的代码:
在网络传输过程中,需要将数据从内存中复制到网络设备的发送缓冲区中。这个过程可以使用 DMA 进行加速。在 Linux 内核中,这个功能由 net/core/dev.c 文件中的 dev_hard_start_xmit 函数实现。
函数中会先通过 skb_shinfo 函数获取 skb 的共享信息结构体,然后通过 skb_shinfo(skb)->tx_dma 指针获取 skb 对应的 DMA 控制器描述符 dma_desc。接下来,通过 dma_map_single 函数将 skb 中的数据映射到 DMA 缓冲区中,并将得到的 DMA 地址写入 dma_desc 结构体中。
```
static int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
struct netdev_queue *txq)
{
...
struct skb_shared_info *shinfo = skb_shinfo(skb);
...
dma_addr_t dma_addr = dma_map_single(dev->dev.parent, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
...
shinfo->tx_dma = dma_desc;
...
}
```
在网络设备的 DMA 完成后,需要将 skb 从 DMA 缓冲区中解除映射。这个过程可以使用 dma_unmap_single 函数实现。在 net/core/dev.c 文件的 dev_kfree_skb_any 函数中,会判断 skb 的共享信息结构体中是否有 tx_dma 指针,如果有,则表示 skb 中的数据已经被映射到 DMA 缓冲区中,需要调用 dma_unmap_single 函数将其解除映射。
```
void dev_kfree_skb_any(struct sk_buff *skb)
{
...
if (shinfo->tx_dma) {
dma_unmap_single(dev->dev.parent, shinfo->tx_dma, skb_headlen(skb), DMA_TO_DEVICE);
shinfo->tx_dma = 0;
}
...
}
```
以上就是 Linux 内核中调用 DMA 相关 API 的真实代码示例。