深入理解Linux网络:第二章-内核是怎么接收数据包的?

关于中断

内核和网络设备驱动都是通过中断的方式来处理的。

当然中断分为两种,硬中断和软中断。当设备有数据进来了,设备首先会触发硬中断,因为处理数据需要耗费很长的时间所以CPU肯定是要把耗时的事情交给别人去干,随后CPU会发出软中断,让内核线程去处理数据。

两种中断的触发方式,硬中断通过给CPU相关的引脚发出一个电压变化,软中断通过一个内存里面的变量来做一个标记。同时程序里面说的那种都是软中断。他只是一个标记不会真的,意思是当前线程需要让出CPU资源。

内核收到路径

  1. 数据帧从外部网络到达网卡
  2. 网卡把帧DMA到内存上(RingBuffer)
  3. 网卡硬中断通知CPU
  4. CPU 响应硬中断,建立处理后发出软中断给内核线程
  5. 内核线程处理软中断,开始调用网卡驱动注册的poll函数开始收包
  6. 内核线程把数据从RingBuffer 上摘下来 保存为一个skb (网络协议栈数据结构体)
  7. 协议层开始处理网络帧,处理完成后数据data被放到socket的接收队列中。 (处理 :主要是传输层的一些处理,会根据不同的协议包来处理 拆包 封包等等)
  8. 内核唤醒用户进程

标记:这里最好结合计算机网络模型一起看

RingBuffer

RingBuffer 由三部分组成 igb_rx_buffer (这个数组是内核使用的), e1000_adv_rx_desc 数组(这个数组是网卡硬件使用的), skb (网络帧数据结构体)。

RingBuffer 是有大小的。

RingBuffer 当然也分为RX TX 两种,RX:接收数据队列,TX:发送数据队列

RingBuffer 丢数据的情况?

当RingBuffer 满的时候,新来的数据包就会被丢弃。使用ifconfig命令查看网卡的时候,可以看到里面有一个overruns,表示因为RingBuffer 队列满被丢弃的包数,如果发现有 丢包,可以通过ethtool 命令来加大环形队列的长度。

为什么网卡开启多队列能提升网络性能?

每一个队列都有独立的、不同的中断好,所以不同的队列在将数据接收到自己的 RingBuffer 后,会想不同的CPU 发起硬中断通知,而在硬中断处理中,软中断的执行是基于当前CPU核来执行的。所以如果只有一个队列的话,那么每一次处理数据都是由同一个CPU在执行。需要开启多队列,让不同的CPU来处理网络数据接收。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值