1
ampedee 2022-12-08 12:06:54 +08:00 via iPhone
一直检查也没问题,限定一次中断处理能执行的时间片长度,执行完了就退出等下一次调度
|
2
kokutou 2022-12-08 12:07:53 +08:00
丢包嘛,无响应嘛
电脑死机了,你 ping 电脑 ip 也是不通的啊。 |
3
huangya OP @ampedee
感谢回复,但我更关心的其实是“但这样检查是原子操作吗?不会放过任何包吗?假设在检查之后,关中断之前来了一个包呢?” |
5
654656413245 2022-12-08 12:56:37 +08:00
1. Linux 中断分上半部和底半部,上半部执行很快耗时很短,也只有上半部处理期间会短暂屏蔽网卡外部中断
2. 网卡自身有缓冲,真的是容量耗尽的时候,直接丢包 3. 基本没有不带 DMA 的网卡了; DMA 完成后才发出硬中断,CPU 开始处理,而不是发出硬中断后才开始 DMA 4. 驱动处理函数都是 poll 流程,是软中断(底半部)执行 |
6
leonshaw 2022-12-08 13:56:47 +08:00
先开中断再处理,而不是等处理完了再开
|
7
sujin190 2022-12-08 14:06:15 +08:00
@huangya #4 一般来说,正常做这个中断程序干完屏蔽中断之后,都是循环读取直到缓冲区读取完成,然后解除屏蔽中断才结束的,正常情况下应该都会把检查队列是否空和清除中断屏蔽设计成一个指令才对
|
8
huangya OP @654656413245
>3. 基本没有不带 DMA 的网卡了; DMA 完成后才发出硬中断,CPU 开始处理,而不是发出硬中断后才开始 DMA 这个我知道。我是在学习网卡驱动,所以找的是最简单的例子。linux 内核里面的 3com 的 3c509 网卡就是不带 DMA 的。学习东西的时候,我喜欢从简单的硬件入手。现在的网卡除了带最基础的 DMA 功能,还带各种高级功能,各种 offload ,多队列,中断合并啥的。但是这样会让驱动复杂很多,新手会比较吃力。 回到我这个问题(我这个人有点钻牛角尖哈,也 @sujin190 ),我只是想知道对于这种网卡,有没有理论上的可能性就是这个包已经到了缓冲队列,但还是最终得不到处理或者及时处理的情况?比如过了很久,第三个包过来了,产生了一个中断,第二个包虽然从队列中顺便捞上来了,但已经被协议栈认为超时了,所以就丢弃。有没有这种情况产生呢? |
9
huangya OP @sujin190
>正常情况下应该都会把检查队列是否空和清除中断屏蔽设计成一个指令才对 不是一个指令。看了一下例子,检查队列会调一个 ioread16 函数(这个函数可能是封装了一个汇编指令),清除中断是另外一个函数.所以最起码是两条指令。 |
10
huangya OP @leonshaw 没太懂你的意思。你说的是中断的下半部分吧( linux 内核把中断分成上半部分和下半部分).下半部分是包已经送到协议栈了,此时中断已经开了。
|
11
sujin190 2022-12-08 14:38:26 +08:00
@huangya #9 如果是这样,那么中断产生条件可能是队列非空,或者你看的这个可能是系统软中断,网卡处理数据正常都是硬中断触发软中断,读取解析数据的过程一般都会在软中断中完成,并不会直接在网卡硬件中断中直接开始处理数据
|
12
leonshaw 2022-12-08 14:42:21 +08:00
@huangya 参考 linux 内核 handle_edge_irq 里的实现。第一个中断进来时,并不关中断;当第一个中断处理过程中又进来,才关中断同时记录 pending 状态;处理中断前开中断、清状态;循环直到没有 pending 为止。上半部分这样处理好了,下半部分自然也不会有问题,不管检查队列是在哪部分实现的。
|
13
huangya OP @sujin190
@leonshaw 两位,我看的是这个 https://elixir.bootlin.com/linux/latest/source/drivers/net/ethernet/3com/3c509.c#L907 el3_rx()被中断处理函数 el3_interrupt()调用. 在第 770 行,el3_interrupt 调用了 spin_lock(),spin_lock 会关中断。然后再第 783 行调用 el3_rx()函数。el3_rx ()使用 while ((rx_status = inw(ioaddr + RX_STATUS)) > 0) (第 915 行)看是否在队列中有新的包。第 941 行的 insl 函数我的理解是从网卡缓冲队列中取包到内存中( skb )。第 946 行 neif_rx 会把 skb 放到协议栈中的队列中,后续会交给软中断或者下半部分处理。 |
16
654656413245 2022-12-08 16:30:13 +08:00
CPU 关闭了中断后,网卡中断仍然会送到中断控制器,只是暂时不发给 CPU
等 CPU 打开中断了,中断控制器会将 pending irq 发给 CPU |
17
huangya OP @654656413245 这几天我还在看 driver 的代码,也在看一些计算机组成原理的书籍。
>等 CPU 打开中断了,中断控制器会将 pending irq 发给 CPU 如果是这样,看我在 13 楼的回复,在 CPU 处理第一个中断的时候,有个 while 循环在 check 有没有新包,那会不会出现 pending irq 发给 CPU 的时候,又进入了中断处理函数,但是收了空包,因为已经在上一次中断处理中完成了收包?我看的组成原理书籍都似乎没讲 pending irq 的情况。 |