2.2.1 linux网络收包总览

用户进程$~~~$|应用层 客户端| —–> HTTP、FTP

————-| socket|———————-


Linux内核 $~~~~~~~~$| 传输层 | —–> TCP、UDP

    协议栈 |    网络层     | -----> IP、ICMP以及IGMP
              
    ----------------------------------------------
              
    驱动  |   链路层     | -----> 网络设备驱动
              

          |    物理层    | -----> 网卡、网线
              

内核和网络设备驱动通过中断方式处理。而且对于网络模块中断,由于处理过程比较复杂和耗时,如果在中断函数中完成所有处理,会导致中断处理函数(优先级过高)过度占用CPU,使得CPU无法响应其他设备,例如鼠标和键盘。

Linux中断处理函数分为上、下部分。

上半部分只进行简单的工作,快速处理后释CPU,接着CPU允许其他中断进来。

下半部分慢慢处理剩下大部分工作。

2.4以后的linux内核版本采用软中断实现,由ksoftqd内核线程全权处理。

硬中断实现:给CPU物理引脚施加电压变化。

软中断实现:通过给内存中的一个变量赋予二进制值以标记由软中断发生。

网卡收到数据—>网卡以DMA的方式把网卡收到的帧写到内存

—>网卡向CPU发起硬中断

—>CPU收到中断,调用网络设备驱动注册的中断处理函数

—>网卡的中断处理函数并不做过多工作,发出软中断请求,释放CPU资源

—>ksoftirqd内核线程检测到有软中断请求到达

—>调用Poll开始轮询收包

—>收到后交由各级协议栈处理 (对于TCP包来说,会被放到用户socket的接收队列中)

2.2.2 Linux驱动

创建 Ksoftirqd内核线程

① 该线程数量不是1个,而是N个,其中N等于你的机器的荷属

$~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$ 2.Spawn内核 $~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$|——–| 3.注册线程函数

1. 启动$~~~~~~~~~~~~~~~~~~~~~$ 线程ksoftirqd $~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$ | $~~~~~~~~~~$| ksoftirqd_should_run,

② ———> | kernel/smpboot.c | ————–> | kernel/softirq.c |<— run_ksoftirqd