Chinaunix

标题: 请教:网卡驱动报文发送理解,谢谢 [打印本页]

作者: skyprince    时间: 2009-08-10 11:52
标题: 请教:网卡驱动报文发送理解,谢谢
查看tg3驱动源码,对报文发送部分不太理解。
1、pci_map_single这个函数是要实现什么功能?把要发送的报文数据DMA到网卡设备上吗?
2、tg3_set_txd函数又实现了什么功能呢?

谢谢。

static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
……
mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE);

        tp->tx_buffers[entry].skb = skb;
        pci_unmap_addr_set(&tp->tx_buffers[entry], mapping, mapping);

        tg3_set_txd(tp, entry, mapping, len, base_flags,
                    (skb_shinfo(skb)->nr_frags == 0) | (mss << 1));

        entry = NEXT_TX(entry);
……
}
作者: eexplorer    时间: 2009-08-10 12:40
标题: 回复 #1 skyprince 的帖子
> 查看tg3驱动源码,对报文发送部分不太理解。
> 1、pci_map_single这个函数是要实现什么功能?把要发送的报文数据DMA到网卡设备上吗?

在作dma之前,需要进行一次从kernel的virtual address到dma address的mapping,设备上的dma engine需要使用dma address进行memory copy (从physical memory -> device)。
同时,在pci_map_single的时候,还会涉及到cache flush的问题,一旦map好以后,设备就可以访问物理内存的内容,所以需要把cache中的内容flush到memory中,保证device读到的是最新的data。由于x86 cpu在硬件上会保证cache coherence,所以并没有cache flush的操作。

> 2、tg3_set_txd函数又实现了什么功能呢?
没看过tg3,但是一般就是在tx ring buffer中找到一个free的tx slot, 根据得到的dma_address和数据长度,设置这个tx slot。device在得到这些信息后,就可以启动dma engine,把数据从host memroy中copy到device on-board memory中,然后在发送出去。
作者: skyprince    时间: 2009-08-10 16:07
非常感谢eexplorer  的解答。

是不是可以这样理解 pci_map_single 只是执行了地址映射,还没有执行实际的 memory copy操作。
到了tg3_set_txd函数时,才触发memory copy操作?

那启动DMA操作的主体是网卡还是驱动呢?是网卡实现将数据从 physical memory -> device。还是由驱动来完成?
作者: eexplorer    时间: 2009-08-10 16:41
标题: 回复 #3 skyprince 的帖子
> 是不是可以这样理解 pci_map_single 只是执行了地址映射,还没有执行实际的 memory copy操
> 作。到了tg3_set_txd函数时,才触发memory copy操作?

memory copy 是由网卡上的dma engine发起的,是有硬件自动完成的,是一个异步操作。驱动的作用是把网卡dma engine作memory copy所需要的信息填好并通知网卡(tg3_set_txd)
作者: finalfantasy000    时间: 2009-08-10 19:22
原帖由 eexplorer 于 2009-8-10 12:40 发表
> 查看tg3驱动源码,对报文发送部分不太理解。
> 1、pci_map_single这个函数是要实现什么功能?把要发送的报文数据DMA到网卡设备上吗?

在作dma之前,需要进行一次从kernel的virtual address到dma address的 ...


cache是指哪儿的cache?CPU的么?还是网卡上面的buffer
作者: emmoblin    时间: 2009-08-10 23:08
cache应该是内存上的dma 环行缓冲区
作者: eexplorer    时间: 2009-08-11 09:37
原帖由 finalfantasy000 于 2009-8-10 19:22 发表


cache是指哪儿的cache?CPU的么?还是网卡上面的buffer


cache是cpu的cache, 这里涉及到cpu cache和 physical memory之间一致性的问题,因为网卡的dma engine是直接访问physical memory的。

在cpu准备好data buffer以后,需要flush cache以保证网卡的dma engine访问到的memory中的数据是最新的 -> pci_map_single
同时在收包时,网卡的dma engine会把受到的数据直接copy到memory中,这是如果cpu要访问的话,必须先invalidate 自己cache中对应这块memory的内容,以免从cache中读取旧的数据 -> pci_unmap_single

因为x86都是硬件帮你做掉了,所以这两个函数里并没有涉及到cpu cache的操作。

[ 本帖最后由 eexplorer 于 2009-8-11 09:39 编辑 ]
作者: dreamice    时间: 2009-08-11 09:44
标题: 回复 #7 eexplorer 的帖子
这个cache是一个硬件层面的cache吧
作者: eexplorer    时间: 2009-08-11 10:38
原帖由 dreamice 于 2009-8-11 09:44 发表
这个cache是一个硬件层面的cache吧


是的,是指cpu上的cache (L1, L2...)。
刚才查了一下,好像arm需要显式的flush/invalidate cache (arm不熟,请有经验的同学确认一下。。。)
作者: Cyberman.Wu    时间: 2009-08-13 14:42
1、这个问题2楼已经讲得很清楚了,直接的DMA是外设做的。这个实际上是所谓DMA基本上都是外设直接访问内存,而此时CPU如果只支持一些运算或只使用Cache数据,两者可以并行执行,从而提高时间。某些CPU中会集成一些DMA Engine,也许它可以用来做主动DMA,但这种架构比较少见。

2. 这个函数实际上是填写网卡和驱动共用的一个DMA描述符缓冲区,它本身还是在系统内存中,不过是一块Coherent DMA。真正通知网卡数据准备好了是在tg3_start_xmit->tw32_tx_mbox中写网卡的寄存器,里面的写操作触发网卡开始工作,首先检查描述符的ring buffer,然后根据描述处理数据。这个其实是很常见的一种设计。
作者: skyprince    时间: 2009-08-21 16:30
标题: 新的疑问:报文发送流程
看Linux设备驱动程序时,提到内核传输数据包是调用驱动程序hard_start_transmit函数执行发送操作。
tg3_start_xmit函数就是tg3驱动的hard_start_transmit函数。驱动中还有一个tg3_tx函数。

我在这两个函数中通过printk打印提示信息。加载驱动后,在命令行执行ping操作。
printk("===start tg3_tx==\n")
printk("===start tg3_start_xmit===\n")

然后执行dmesg查看系统信息,发现只打印了“===start tg3_tx==”信息。

很迷惑:ping执行了发包操作,那应该调用驱动中的发包函数。怎么记录的是它进入的是 tg3_tx函数,而没有进入tg3_start_xmit函数呢?
或者说tg3_start_xmit函数和tg3_tx函数分别实现什么功能?数据发送时调用的是哪个函数?

谢谢。
作者: Cyberman.Wu    时间: 2009-08-23 12:39
标题: 回复 #11 skyprince 的帖子
你都已经开始调试打印了,就干脆不停地加打印把整个流程搞清楚然后给大家来讲一讲了

感觉这个和NAPI有关系,在使用NAPI时IP层下发数据可能通过那个poll方法来走了;不过NAPI不熟悉,你得自己去测试一下了。可以用打印调用栈的方式来加速分析吧。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2