深入理解Linux网络笔记-第一章内核是如何接收网络包的
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


