news 2026/4/18 10:05:20

中断处理——lab net中为什么e1000_recv必须批量处理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
中断处理——lab net中为什么e1000_recv必须批量处理

因为我硬件知识有点欠缺,所以碰到硬件相关的都尽量专门写一篇笔记。


物理设备和设备控制器和中断控制器:网卡,声卡,显卡,键盘鼠标这些所有都是物理设备,而管理这些设备的叫设备控制器。CPU只和设备控制器进行交互,而不关心背后的设备具体如何。这节课中我们主要学习的设备控制器是UART,它并不管理具体的某个设备,而是在QEMU模拟器的帮助下管理从宿主机传进来的输入数据流和发往宿主机中断的输出数据流。设备控制器能够直接和CPU交互,即内核可以从设备控制器输入输出信息。但是设备控制器需要引起CPU关注时,它作为中断源,必须向中断控制器发送信号,中断控制器负责仲裁优先级,最后向CPU发起真正的中断。
而RISC-V中,负责记录和分发中断的组件是PLIC。

上面是我们之前已经在中断那里学到过的。现在我们结合一下E1000这里的例子深入一下。

E1000接收数据包时产生的中断信号传递过程:

1.E1000网卡内部:当数据包到达时,DMA完成,描述符写回后,中断信号会记录在E1000内部的ICR(Interrupt Cause Register)寄存器中。只要ICR里有未被清除的位,网卡就会持续拉高它连接到PLIC的那根物理导线为高电平。

2.PLIC:只要E1000拉高了导线,PLIC的网关就会立刻感知到。在PLIC的内部有一个Pending Bit Array(等待位数组),对应E1000的那个比特位会被置为1。哪怕CPU正在关中断,PLIC依然会将这个Pending Bit置为1.

3.CPU最终感知:当CPU开启中断时,CPU就会看到一个外部中断请求,然后跳转到trap处理程序。在trap处理程序中,会调用plic_claim()函数,然后PLIC将Pending Bit置零。

为什么我们在e1000_recv函数中一次只处理一个数据包可能会导致丢失中断信号:

void e1000_intr(void) { // 1. 读取 ICR 寄存器,看看发生了什么事 // 【关键动作】:读取 ICR 会自动清除 E1000 内部的中断标志! // 这相当于告诉网卡:“我知道了,别吵了,把手放下。” int icr = regs[E1000_ICR]; // 2. 调用你的接收函数 e1000_recv(); }

1.数据到达:假设在调用e1000_intr之前,qemu瞬间往接收环中塞了5个数据包。E1000网卡检测到数据,拉高中断线,PLIC看到高电平,将对应的Pending Bit置位。

2.CPU响应:CPU发现Pending位,跳转到e1000_intr。Pending Bit被置零,e1000_intr函数读取ICR寄存器,将中断线拉低,此时,物理层面上没有任何中断信号了。

3.e1000_recv:只处理第一个包,显然,后面包的中断信号全部丢失。

为什么批量处理能够避免丢失中断信号:

1.数据到达:和之前相同,到达5个数据包。

2.CPU响应:在PLIC将对应的Pending Bit置零,E1000信号线拉低。

3.e1000_recv:在e1000_recv中,由于我们采用的是批量处理的逻辑,所以所有的这5个数据包都会被读入。而假如在处理过程中,数据包再次到达,那么会重新将E1000信号线拉高,Pending Bit置位。当CPU处理完这个中断后,又能看到下一次中断的信号,然后继续处理第二次中断的数据包。

总结:之所以采用批量处理,是因为不论PLIC的Pending Bit还有信号线为高电平还是低电平都只能记录0或1。假如它们能够记录更大的值,那么我们就可以在每次一个数据包到达时使intrs++,然后CPU根据intrs的值来知道有多少次中断信号,这样就不会丢失中断信号了。

但是,由于只能记录0和1,所以0和1只能抽象为无数据包和有数据包的简单逻辑,而我们的recv函数也只知道有数据包,而不知道有多少数据包,因此采取批量处理是必然的。

推而广之,硬件中断对于 CPU 来说只是一个唤醒通知,而不是一个精确的任务计数器。作为驱动程序,收到通知后必须主动检查并处理所有堆积的任务,直到缓冲区为空。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 16:48:00

JAVA家政5.0:同城上门预约系统源码全解析

JAVA家政5.0:同城上门预约系统源码全解析一、系统架构设计1. 整体架构JAVA家政5.0同城上门预约系统采用微服务架构,基于Spring Cloud或Spring Boot Spring Cloud Alibaba生态体系构建。这种架构将用户管理、订单调度、支付结算、智能推荐等核心功能拆分…

作者头像 李华
网站建设 2026/4/17 19:26:11

Equalizer APO终极配置指南:从零打造专业级音频系统

Equalizer APO终极配置指南:从零打造专业级音频系统 【免费下载链接】equalizerapo Equalizer APO mirror 项目地址: https://gitcode.com/gh_mirrors/eq/equalizerapo 想要提升Windows系统的音频体验?Equalizer APO作为一款开源参数化均衡器&…

作者头像 李华
网站建设 2026/4/18 8:31:07

(Git Sparse Checkout + Docker)组合技曝光:极简工作树创建法

第一章:极简工作树的构建背景与意义在现代软件开发中,项目结构的复杂性往往随着功能迭代迅速膨胀。代码文件分散、依赖关系混乱、构建流程冗长等问题显著降低了团队协作效率与系统可维护性。极简工作树的核心理念在于通过规范化目录结构与最小化初始依赖…

作者头像 李华
网站建设 2026/4/18 2:06:39

文献管理效率翻倍:Jasminum如何解决中文论文处理的三大痛点?

文献管理效率翻倍:Jasminum如何解决中文论文处理的三大痛点? 【免费下载链接】jasminum A Zotero add-on to retrive CNKI meta data. 一个简单的Zotero 插件,用于识别中文元数据 项目地址: https://gitcode.com/gh_mirrors/ja/jasminum …

作者头像 李华
网站建设 2026/4/15 20:49:17

【前端开发新纪元】:语言模型驱动下的VSCode编码奇迹

第一章:前端开发新纪元的开启 前端开发正经历一场深刻的变革,从静态页面到动态交互,再到如今组件化、工程化的全面演进,技术边界不断被拓宽。现代浏览器能力的增强、JavaScript 语言标准的快速迭代以及构建工具的成熟,…

作者头像 李华
网站建设 2026/4/18 8:37:44

Driver Store Explorer终极指南:Windows驱动管理的完整解决方案

Driver Store Explorer终极指南:Windows驱动管理的完整解决方案 【免费下载链接】DriverStoreExplorer Driver Store Explorer [RAPR] 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 还在为Windows系统盘空间不足而烦恼吗?是…

作者头像 李华