免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6325 | 回复: 11
打印 上一主题 下一主题

中断为何会丢失? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-11-05 18:00 |只看该作者 |倒序浏览
正在读ULK3,第四章中断中关于__DO_IRQ()的代码中涉及中断丢失的部分有点迷惑。代码如下:

  1. spin_lock(&(irq_desc[irq].lock));
  2. irq_desc[irq].handler->ack(irq);
  3. irq_desc[irq].status &= ~(IRQ_REPLAY | IRQ_WAITING);
  4. irq_desc[irq].status |= IRQ_PENDING;
  5. if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))
  6.     && irq_desc[irq].action) {
  7.      irq_desc[irq].status |= IRQ_INPROGRESS;
  8.      do {
  9.           irq_desc[irq].status &= ~IRQ_PENDING;
  10.           spin_unlock(&(irq_desc[irq].lock));
  11.           handle_IRQ_event(irq, regs, irq_desc[irq].action);
  12.           spin_lock(&(irq_desc[irq].lock));
  13.      } while (irq_desc[irq].status & IRQ_PENDING);
  14.      irq_desc[irq].status &= ~IRQ_INPROGRESS;
  15. }
  16. irq_desc[irq].handler->end(irq);
  17. spin_unlock(&(irq_desc[irq].lock));
复制代码
按照我对ULK3的理解,假设有两个CPU分别称为A和B。B正在执行中断服务程序handle_IRQ_event(),此时同类型的中断在A上发生,那么A将进入__DO_IRQ()执行上面的代码片段。如果在A确认中断之前,B执行了disable_irq()屏蔽了IRQ线并置IRQ_DISABLED标志,那么A执行到第5行时由于IRQ_DISABLED标志置位,A直接从__DO_IRQ()返回,这就是中断的丢失。我有两个地方不明白:

1. 这里ULK3为什么要强调在A确认中断之前?难道确认中断之后就不会丢失中断吗?
2. 这种情况下,中断真的会丢失吗?A在进入do_IRQ()函数之后,在第三行将IRQ_PENDING置位了,所以虽然A从do_IRQ()返回,但B在执行完handle_IRQ_event()后循环条件成立(IRQ_PENDING置位),所以仍然会再次调用handle_IRQ_event来处理,所以我觉得这里中断不会丢失呀。

论坛徽章:
0
2 [报告]
发表于 2011-11-05 22:06 |只看该作者
你的理解有误,本CPU调用disable_irq()时,只会禁止本CPU相应中断,确切的说,是设置本CPU的IF标志,而不会去禁用中断控制器APIC;

更进一步说,每个CPU都有一个Local APIC,即使禁止了本地的APIC,外部中断也可以通过ICC传向其他CPU, 其他CPU也是可以响应

论坛徽章:
0
3 [报告]
发表于 2011-11-05 23:01 |只看该作者
你的理解有误,本CPU调用disable_irq()时,只会禁止本CPU相应中断,确切的说,是设置本CPU的IF标志,而不会 ...
wangjianchangdx 发表于 2011-11-05 22:06


是的,不论具体如何实现,当中断处理期间同一个CPU上同类型的中断不会再次发生。但是其他CPU上的同类型中断却会再次发生,这也是中断丢失的必要条件。我不理解的是中断如何丢失,代码中的那个循环应该可以保证不会丢失中断的。

论坛徽章:
0
4 [报告]
发表于 2011-11-06 00:32 |只看该作者
> 1. 这里ULK3为什么要强调在A确认中断之前?难道确认中断之后就不会丢失中断吗?

A确认中断时,已经获得了irq_desc[irq].lock,而disable_irq必须也要获取到该锁,所以,当A确认中断之后,B已经没有机会disable_irq了,必须要等到A执行完之后,才可以;


> 2. 这种情况下,中断真的会丢失吗?A在进入do_IRQ()函数之后,在第三行将IRQ_PENDING置位了,所以虽然A从do_IRQ()返回,但B在执行完handle_IRQ_event()后循环条件成立(IRQ_PENDING置位),所以仍然会再次调用handle_IRQ_event来处理,所以我觉得这里中断不会丢失呀。

英文版上说的是“A hardware device raises the IRQ line, and the multi-APIC system selects our CPU for handling the interrupt. Before the CPU acknowledges the interrupt, the IRQ line is masked out by another CPU;”,这里很微妙,是的你说的很对,do_IRQ()本身可以确保中断不丢失,但是为什么disable_irq不能被内核的其他函数调用呢?如果那里只是单纯的成对使用disable_irq和enable_irq,那就会有中断丢失了,不是吗?呵呵,这里说的不清楚,只是说明了by another CPU, 而没有说by another CPU who's  not executing __do_IRQ().

论坛徽章:
0
5 [报告]
发表于 2011-11-06 00:43 |只看该作者
把注意力集中在代码本身了,没有考虑到其他地方也会屏蔽中断。非常感谢!

论坛徽章:
0
6 [报告]
发表于 2011-11-06 00:49 |只看该作者
你有没有考虑过中断被pending两次的情况?呵呵

论坛徽章:
0
7 [报告]
发表于 2011-11-06 09:05 |只看该作者
我想应该可以pending两次或多次,只是多于两次会丢失。按ULK3的说法丢掉好像没有什么特别的处理,请指教。

论坛徽章:
0
8 [报告]
发表于 2011-11-06 11:23 |只看该作者
嗯,我认为也是可以的,只是丢失也没问题。
首先,外部中断源能否在上一次中断未被处理的情况下,再一次发出中断信号,是个问题;
其次,即使可以,那是否可以多次中断,一次处理呢?只记录了pending的状态,而没有记录pending的次数,所以只会而且一定会调用一次ISR。一般的情况都好理解,假设网卡收到一个包,发出中断,并把包存放在某处,继续接受下一个包,接收到之后,有发出中断。。。这样,调用ISR的时候,只需要去存包的地方取包就可以了,pending的包都可以取到。

我疑惑的是时钟中断丢失的情形,但是查资料发现,6.4.1 找回遗失的时钟中断http://book.51cto.com/art/200810/93782.htm,说明,对于需要特殊处理的中断,内核是考虑到并做了处理的。

论坛徽章:
0
9 [报告]
发表于 2011-11-06 12:44 |只看该作者
的确存在丢失的情况

论坛徽章:
0
10 [报告]
发表于 2011-11-06 12:50 |只看该作者
> 首先,外部中断源能否在上一次中断未被处理的情况下,再一次发出中断信号,是个问题;

这可能与中断控制器有关,我记得8259A可以通过编程使它在前一个中断没有确认的情况下不会接受同类型的下一个中断。此时,对应的IRQ线和设备都无法继续。我也一直有个问题:PIC是如何阻塞一个设备的,PIC是否也需要对设备做确认?

> 其次,即使可以,那是否可以多次中断,一次处理呢?只记录了pending的状态,而没有记录pending的> 次数,所以只会而且一定会调用一次ISR。一般的情况都好理解,假设网卡收到一个包,发出中断,并把包> 存放在某处,继续接受下一个包,接收到之后,有发出中断。。。这样,调用ISR的时候,只需要去存包的> 地方取包就可以了,pending的包都可以取到。
> 我疑惑的是时钟中断丢失的情形,但是查资料发现,6.4.1 找回遗失的时钟中断>http://book.51cto.com/art/200810/93782.htm,说明,对于需要特殊处理的中断,内核是考虑到并> 做了处理的。

是的,网卡的例子应该适用许多设备对数据处理的情况,因为数据都是被缓冲的。而时间流逝过去就无法找回来,所以内核对它特别关照了。不论何种设备,办法似乎不是在从内核中断机制本身防止中断丢失,而是依靠具体的中断服务例程的补充。例如,时钟中断与TSC比照来做修正。网卡一个收多个包也可以认为是一种修正。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP