免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: albcamus
打印 上一主题 下一主题

level, edge, cli, disable_irq, PIT, LAPIC Timer ... 一次讨论个清楚吧! [复制链接]

论坛徽章:
0
31 [报告]
发表于 2008-04-08 16:45 |只看该作者
原帖由 albcamus 于 2008-4-8 16:37 发表



老大,是不是IO-APIC不需要ACK? 我看ioapic_chip的ack和eoi方法是:

ack_ioapic_irq
ack_ioapic_quirk_irq


quirk是不是只是处理有BUG的硬件?

IOAPIC没有ack,我想是因为它发MSI的时候vector已经在消息里了,所以不需要PIC中这种ACK的协商方式。
ack_ioapic_quirk_irq我没找到在哪儿哦

论坛徽章:
0
32 [报告]
发表于 2008-04-08 16:50 |只看该作者
原帖由 zx_wing 于 2008-4-8 16:45 发表

IOAPIC没有ack,我想是因为它发MSI的时候vector已经在消息里了,所以不需要PIC中这种ACK的协商方式。
ack_ioapic_quirk_irq我没找到在哪儿哦



有个问题比较怀疑, ACK是针对与i8259A的吗? 怎么感觉应该是针对edge中断呢? (handle_fasteoi_irq不调用chip->ack,而handle_edge_irq调用)

现在的ioapic_chip不包括MSI方式,后者有它自己的msi_chip结构。  咱们先把 普通情形讨论完吧

论坛徽章:
0
33 [报告]
发表于 2008-04-08 17:05 |只看该作者
原帖由 albcamus 于 2008-4-8 16:50 发表



有个问题比较怀疑, ACK是针对与i8259A的吗? 怎么感觉应该是针对edge中断呢? (handle_fasteoi_irq不调用chip->ack,而handle_edge_irq调用)

现在的ioapic_chip不包括MSI方式,后者有它自己的msi_c ...

我觉得首先要把硬件上的ack动作和linux中是实现的ack()函数区分开。
ack动作是针对8259,linux中的IOAPIC的ack()实际上就是EOI。
handle_fasteoi_irq()应该不是给x86平台用的。而handle_edge和handle_level都要调用ack方法去写EOI。

另外我说的MSI不是指软件上使用MSI的方式。而是说现在的IOAPIC在总线上通过MSI和LAPIC通讯,所以不需要像8259那样由CPU ack的协商方式。

论坛徽章:
0
34 [报告]
发表于 2008-04-08 17:17 |只看该作者

回复 #33 zx_wing 的帖子

>觉得首先要把硬件上的ack动作和linux中是实现的ack()函数区分开。
>ack动作是针对8259,linux中的IOAPIC的ack()实际上就是EOI。

这两句很关键,一下子就明白了,谢谢


> handle_fasteoi_irq()应该不是给x86平台用的。而handle_edge和handle_level都要调用ack方法去写EOI。
貌似 x86平·台就用这个handle_fasteoi_irq来处理IO-APIC上的level中断, 而用handle_level_irq来处理PIC上的level中断。


>另外我说的MSI不是指软件上使用MSI的方式。而是说现在的IOAPIC在总线上通过MSI和LAPIC通讯,所以不需要像8259那样由CPU ack的协商方式。

这个不太明白。 MSI不是专门于PCI/PCI-X/PCI-E的吗?  抛开这些BUS和Devices, 单论IOAPIC和LAPIC之间的通讯也是用发送MSI消息的方式?

论坛徽章:
0
35 [报告]
发表于 2008-04-08 17:26 |只看该作者
原帖由 albcamus 于 2008-4-8 17:17 发表
>觉得首先要把硬件上的ack动作和linux中是实现的ack()函数区分开。
>ack动作是针对8259,linux中的IOAPIC的ack()实际上就是EOI。

这两句很关键,一下子就明白了,谢谢


> handle_fasteoi_irq( ...

> handle_fasteoi_irq()应该不是给x86平台用的。而handle_edge和handle_level都要调用ack方法去写EOI。
>貌似 x86平·台就用这个handle_fasteoi_irq来处理IO-APIC上的level中断, 而用handle_level_irq来处理PIC上的level中断。

我也记得我以前看过是在哪儿调用set_irq_handle什么的把handle_fasteoi_irq作为callback设上的,但现在就是找不到了,只在powerpc的代码里看到有。我再找找


>>这个不太明白。 MSI不是专门于PCI/PCI-X/PCI-E的吗?  抛开这些BUS和Devices, 单论IOAPIC和LAPIC之间的通讯也是用发送MSI>>消息的方式?

以前的架构有专门的APIC BUS来通讯。但应该是从奔腾4和xeon系列开始,IOAPIC就直接在前端总线上发MSI给LAPIC了。
MSI只是一种中断协议而已,PCI类设备的MSI是说他们可以不通过IOAPIC,直接发MSI给LAPIC。IOAPIC虽然不是PCI设备,但本身也是南桥上的一个设备。既然连南桥的PCI设备都可以发MSI,那么IOAPIC可以发MSI也就不奇怪了。

论坛徽章:
0
36 [报告]
发表于 2008-04-08 17:30 |只看该作者

回复 #35 zx_wing 的帖子

> 我也记得我以前看过是在哪儿调用set_irq_handle什么的把handle_fasteoi_irq作为callback设上的,但现在就是找不到了,只在powerpc的代码里看到有。我再找找

抄一段笔记:
===========
setup_IO_APIC()
         
         然后,setup_IO_APIC() > setup_IO_APIC_irqs()
                                  init_IO_APIC_traps()
         两个函数设置中断和陷阱。

         其中setup_IO_APIC_irqs() > ioapic_register_intr() :

                1275 static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
                1276 {
                1277         if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
                1278                         trigger == IOAPIC_LEVEL)
                1279                 set_irq_chip_and_handler_name(irq, &ioapic_chip,
                1280                                          handle_fasteoi_irq, "fasteoi");
                1281         else
                1282                 set_irq_chip_and_handler_name(irq, &ioapic_chip,
                1283                                          handle_edge_irq, "edge");
                1284         set_intr_gate(vector, interrupt[irq]);
                1285 }
                
                (从代码可以看出,对IO APIC上的中断来说,由于调用ioapic_register_intr时指定了IOAPIC_AUTO,所以
                其chip都是handle_fasteoi_irq)。



> 既然连南桥的PCI设备都可以发MSI,那么IOAPIC可以发MSI也就不奇怪了。

明白,谢谢!

论坛徽章:
0
37 [报告]
发表于 2008-06-05 21:26 |只看该作者

ULK第3版第4.6章中关于IRQ_REPLAY的问题

enable_irq时,如果发现还有IRQ_PENDING,就说明存在丢失的中断,需要挽救。
但关于IRQ_REPLAY,书中说是为了防止多次产生一个丢失的中断。
我的问题是:
即使不使用IRQ_REPLAY,在什么情况下会多次产生一个丢失的中断呢?
代码中,spin_lock已经保护了整段代码,并且hw_resend_irq是LAPIC发出的,会立即在本处理器上产生,也就是说,
执行到最后的spin_unlock(这里书中写错了,不是spin_lock)时,根本没有机会再次进入这段代码,那么怎么会产生“多次产生一个丢失的中断”的情况呢?
ULK 原文如下:
    spin_lock_irqsave(&(irq_desc[irq].lock), flags);
    if (--irq_desc[irq].depth == 0) {
        irq_desc[irq].status &= ~IRQ_DISABLED;
        if (irq_desc[irq].status & (IRQ_PENDING | IRQ_REPLAY))
               == IRQ_PENDING) {
            irq_desc[irq].status |= IRQ_REPLAY;
            hw_resend_irq(irq_desc[irq].handler,irq);
        }
        irq_desc[irq].handler->enable(irq);
    }
    spin_lock_irqrestore(&(irq_desc[irq].lock), flags);
The function detects that an interrupt was lost by checking the value of the IRQ_PENDING flag. The flag is always cleared when leaving the interrupt handler; therefore, if the IRQ line is disabled and the flag is set, then an interrupt occurrence has been acknowledged but not yet serviced. In this case the hw_resend_irq( ) function raises a new interrupt. This is obtained by forcing the local APIC to generate a self-interrupt (see the later section "Interprocessor Interrupt Handling").
***The role of the IRQ_REPLAY flag is to ensure that exactly one self-interrupt is generated. ***
Remember that the _ _do_IRQ( ) function clears that flag when it starts handling the interrupt.

论坛徽章:
0
38 [报告]
发表于 2008-06-06 12:54 |只看该作者
原帖由 zx_wing 于 2008-3-28 12:16 发表
最近正在认真学习这个部分,al老大就发起话题了,正好也讨论一下

1 )level 和 edge这两种类型的中断, 谁能简要的说一下区别?   

   附加疑问: 为什么MSI中断被当成edge中断?

区别嘛,汗 ...


MSI本质上是message,没必要做成level的。
当然PCI INTX也是message,但是有两个 INTx_UP/INTx_down(原理说明,不见得spec里面也是这个名字)。
别的俺都不懂。

论坛徽章:
2
CU十二周年纪念徽章
日期:2013-10-24 15:41:34处女座
日期:2013-12-27 22:22:41
39 [报告]
发表于 2011-11-07 16:33 |只看该作者
老大,我看到的跟你说的正好相反啊。

IRR相当于一个锁存器,来一个电压跳变锁存一次,将IRR对应位置1。
motalelf 发表于 2008-03-28 16:24


我之前一直也是这么想的。对于8259,内核的ack就是mask本根中断线并写EOI,这主要是为了实现无优先级中断模型。我之前以为,如果这期間这个中断再次出现,IRR会记得。但是8259的手册里有这么一张图:



从这张图上看,只有第一次INTA之后,内部freeze信号才有效,IRR才会去锁存IRQ信号。手册里也说了中断处理的第二步:
2 The 8259A evaluates these requests and sends an INT to the CPU if appropriate

这个appropriate应该是说,同等优先级及低优先级IRQ产生的中断不会向CPU发出INT,mask掉的IRQ产生的中断也不会向CPU发出INT。既然不向CPU发出INT,那就不谈接下来的INTA了,按照那张图,IRR也没有机会去锁存那个IRQ信号了。对于edge-triggered中断,按照Linux的做法,处理一个中断时,相同中断再度来临就会丢失?如果实现带优先级中断模型时,不需要软件的ack,按照上面的假设,处理一个中断时,低优先级中断也丢失了?好像不太能可能呀。

到了APIC,有了些变化 ... ... 但对于edge,就有了问题。屏蔽中断线后,跳变总不会自己保持,又无法象PIC一样,硬件可以自动保存这个IRQ。


Intel手册里:
If more than one interrupt is generated with the same vector number, the local APIC
can set the bit for the vector both in the IRR and the ISR. This means that for the
Pentium 4 and Intel Xeon processors, the IRR and ISR can queue two interrupts for
each interrupt vector: one in the IRR and one in the ISR. Any additional interrupts
issued for the same interrupt vector are collapsed into the single bit in the IRR.


这好像才是之前期待8259具有的功能。

论坛徽章:
2
CU十二周年纪念徽章
日期:2013-10-24 15:41:34处女座
日期:2013-12-27 22:22:41
40 [报告]
发表于 2011-11-07 17:15 |只看该作者
回复 39# tempname2

C,原来freeze有效时不再锁存IRR。那8259跟APIC就没区别了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP