多队列网卡简介以及Linux通过网卡发送数据包源码解读


摘自:http://blog.csdn.net/yanghua_kobe/article/details/7485254 

首先我们看一下一个主流多队列网卡(E1000)跟多核CPU之间的关系图:


非多队列:

linux的网卡由结构体net_device表示,一个该结构体对应一个可以调度的数据包发送队列。

数据包的实体在内核中以结构体sk_buff(skb),形如:


多队列:

一个网卡可以拥有多个队列


接下来,看看TX引擎是如何工作的(注:对于发送和接收数据包有两个名词,分别应对TX,RX)


解释:

函数-dev_queue_xmit():入队一个buffer以传输到网络驱动设备。

配合该函数的源码来解释上图的传输过程:

步骤一:可以看到如果设备支持队列,则数据包入设备队列。在入队操作前后,有加锁和释放队列锁的过程。


步骤二:调出设备的qdisc(该对象是队列的排队规则)


QDisc(排队规则)是queueingdiscipline的简写,它是理解流量控制(traffic control)的基础。无论何时,内核如果需要通过某个网络接口发送数据包,它都需要按照为这个接口配置的qdisc(排队规则)把数据包加入队列。然后,内核会尽可能多地从qdisc里面取出数据包,把它们交给网络适配器驱动模块。最简单的QDisc是pfifo它不对进入的数据包做任何的处理,数据包采用先入先出的方式通过队列。不过,它会保存网络接口一时无法处理的数据包。

步骤三:重置skb的队列映射,置为0


步骤四:tx lock->hard_start_xmit

到这里,我们好像没有看到tx_lock、hard_start_xmit函数,反而我们在无队列的设备分支中看到了这些:


Dev_hard_start_xmit的定义:


很明显我们应该拨开云雾看到一些本质,再次回到设备支持队列的分支中(这才是我们关心的):

不管怎么样,你总该有发送的函数调用吧,就是下面圈起来的这个:


果不其然,这是一个封装函数:


参考:

http://www.landley.net/kdocs/ols/2007/ols2007v2-pages-305-310.pdf

http://vger.kernel.org/~davem/davem_nyc09.pdf

http://www.chineselinuxuniversity.net/kerneldocs/networking/API-dev-queue-xmit.html

http://apps.hi.baidu.com/share/detail/36206005

http://cache.baidu.com/c?m=9d78d513d98017f419bc837f7d01d0120e55f0237b8bc7150ec3e54c84145d563164f4cd25351174c4b5777075d95e2cebe74703234460e99492ce0c9fac935b3295776a2d499141658243f4971532c157c304b2ff4ab7e9e732e4ff8f8cc2040d97061832daabc8015c41ca65ed4771a5fdc816424240b8fa3013a4537d2c992742b750f997682858df&p=ce7ddc1187904eac59b5c4710e14d625&user=baidu&fm=sc&query=qdisc%5Frun+%D6%B4%D0%D0%B9%FD%B3%CC&qid=f6ae9cf00151dde4&p1=1

http://lwn.net/Articles/289137/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DMA(Direct Memory Access)是一种计算机技术,允许外部设备(如网卡)直接访问计算机内存,而无需通过中央处理器进行数据传输。通过DMA,网卡可以直接与内存进行读写操作,从而提高数据传输的效率。 网卡实现DMA机制接收和发送数据包代码可以按照以下步骤实现: 1. 初始化DMA控制器,配置DMA通道和相关寄存器。设置网卡接收数据包的DMA通道和发送数据包的DMA通道。 2. 当网卡接收到数据包时,触发DMA中断,DMA控制器将数据包直接拷贝到指定的接收缓冲区。 3. 网卡发送数据包时,将数据包内容写入发送缓冲区,然后触发DMA中断,DMA控制器将数据包直接从发送缓冲区传输到网卡发送队列,并发送到目标设备。 以下是伪代码示例: 初始化DMA控制器和相关寄存器: ``` initialize_DMA_controller(); configure_DMA_channel(Receive_channel, receive_buffer); configure_DMA_channel(Transmit_channel, transmit_buffer); ``` 接收数据包的DMA中断处理函数: ``` void DMA_Receive_Interrupt_Handler() { if (DMA_receive_channel_interrupt) { // 从DMA通道读取数据包到接收缓冲区 read_data_to_receive_buffer(); } } ``` 发送数据包的DMA中断处理函数: ``` void DMA_Transmit_Interrupt_Handler() { if (DMA_transmit_channel_interrupt) { // 从发送缓冲区将数据包传输到DMA通道 write_data_from_transmit_buffer(); } } ``` 通过以上代码,网卡可以利用DMA机制实现高效地接收和发送数据包,避免了CPU的干预,提高了数据传输的效率。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值