亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
12下一頁
最近訪問板塊 發(fā)新帖
查看: 5326 | 回復: 16
打印 上一主題 下一主題

ULK第3版第4.6章中關(guān)于IRQ_REPLAY的問題 [復制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2008-06-10 14:18 |只看該作者 |倒序瀏覽
enable_irq時,如果發(fā)現(xiàn)還有IRQ_PENDING,就說明存在丟失的中斷,需要挽救。
但關(guān)于IRQ_REPLAY,書中說是為了防止多次產(chǎn)生一個丟失的中斷。
我的問題是:
即使不使用IRQ_REPLAY,在什么情況下會多次產(chǎn)生一個丟失的中斷呢?
代碼中,spin_lock已經(jīng)保護了整段代碼,并且hw_resend_irq是LAPIC發(fā)出的,會立即在本處理器上產(chǎn)生,也就是說,
執(zhí)行到最后的spin_unlock(這里書中寫錯了,不是spin_lock)時,根本沒有機會再次進入這段代碼,那么怎么會產(chǎn)生“多次產(chǎn)生一個丟失的中斷”的情況呢?
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
2 [報告]
發(fā)表于 2008-06-10 16:32 |只看該作者
__do_IRQ在ack的時候清掉REPLAY,但是如果由于關(guān)中斷了,do_IRQ在多個renable之間沒有得到運行,即ack在replay之后還沒有運行,那么沒有必要再replay了

論壇徽章:
0
3 [報告]
發(fā)表于 2008-06-10 16:38 |只看該作者
假如在執(zhí)行完enable后還未執(zhí)行中斷程序時,重新有一個disable之后enable的過程,是否會導致重復hw_resend_irq?我感覺是有可能的。IRQ_REPLY應該是為了避免這種情況設(shè)計的。

[ 本帖最后由 dengcainiao 于 2008-6-10 16:40 編輯 ]

論壇徽章:
0
4 [報告]
發(fā)表于 2008-06-10 18:31 |只看該作者
原帖由 dengcainiao 于 2008-6-10 16:38 發(fā)表
假如在執(zhí)行完enable后還未執(zhí)行中斷程序時,重新有一個disable之后enable的過程,是否會導致重復hw_resend_irq?我感覺是有可能的。IRQ_REPLY應該是為了避免這種情況設(shè)計的。

是這樣的哈。
剛才我沒注意到這是在關(guān)中斷情況下執(zhí)行的,這個時候IPI要等到開中斷時才會被LAPIC提交到CPU。所以其它CPU有機會在spin_lock_irqrestore(&(irq_desc[irq].lock), flags);之后再執(zhí)行一次disable/enable的過程,導致重復。

論壇徽章:
0
5 [報告]
發(fā)表于 2008-06-11 09:01 |只看該作者
原帖由 dengcainiao 于 2008-6-10 16:38 發(fā)表
假如在執(zhí)行完enable后還未執(zhí)行中斷程序時,重新有一個disable之后enable的過程,是否會導致重復hw_resend_irq?我感覺是有可能的。IRQ_REPLY應該是為了避免這種情況設(shè)計的。

謝謝!
因為發(fā)生中斷感覺是在enable中完成的(執(zhí)行spin_unlock的瞬間),我是否能把你的話理解成:假如在這次執(zhí)行到enable函數(shù)內(nèi)部,但還未執(zhí)行中斷程序時,重新有一個disable之后enable的過程...?

但我認為這時不存在重新的disable再enable。
因為這次的enable開始時已經(jīng)spin_lock了,再一次的enable無法執(zhí)行下去。
所以還是有些疑問。

[ 本帖最后由 OstrichFly 于 2008-6-11 09:32 編輯 ]

論壇徽章:
0
6 [報告]
發(fā)表于 2008-06-11 09:06 |只看該作者
中斷不是在enable中完成的,如ZX_WING兄弟說的IPI在開中斷以后才會被提交,即在spin_lock_irqrestore(&(irq_desc[irq].lock), flags);之后。所以說中斷完成應該是在enable函數(shù)外邊,在二者之間有機會插入一組diable/enable的過程。

[ 本帖最后由 dengcainiao 于 2008-6-11 09:07 編輯 ]

論壇徽章:
0
7 [報告]
發(fā)表于 2008-06-11 09:23 |只看該作者
原帖由 zx_wing 于 2008-6-10 18:31 發(fā)表

是這樣的哈。
剛才我沒注意到這是在關(guān)中斷情況下執(zhí)行的,這個時候IPI要等到開中斷時才會被LAPIC提交到CPU。所以其它CPU有機會在spin_lock_irqrestore(&(irq_desc.lock), flags);之后再執(zhí)行一次disable/enabl ...

謝謝!
這樣看來,中斷應該發(fā)生在spin_unlock_irqrestore的內(nèi)部,也就是執(zhí)行開中斷指令的瞬間,會立即進入中斷服務程序。
如果說會再一次發(fā)生disable/enable,只有在這一瞬間的空檔中發(fā)生,或者由于時間中斷引起搶占調(diào)度,請問是這樣的嗎?

論壇徽章:
0
8 [報告]
發(fā)表于 2008-06-11 09:32 |只看該作者
原帖由 flw2 于 2008-6-10 16:32 發(fā)表
__do_IRQ在ack的時候清掉REPLAY,但是如果由于關(guān)中斷了,do_IRQ在多個renable之間沒有得到運行,即ack在replay之后還沒有運行,那么沒有必要再replay了

謝謝!
你的意思是:如果關(guān)中斷的時候進行了renable,是不應該再次發(fā)生中斷的,replay是為了這個目的設(shè)置的?
但即使沒有replay,“關(guān)中斷”本身也能阻止再次發(fā)生中斷阿,那么replay的必要性在什么地方呢?

論壇徽章:
0
9 [報告]
發(fā)表于 2008-06-11 09:38 |只看該作者
原帖由 OstrichFly 于 2008-6-11 09:32 發(fā)表

謝謝!
你的意思是:如果關(guān)中斷的時候進行了renable,是不應該再次發(fā)生中斷的,replay是為了這個目的設(shè)置的?
但即使沒有replay,“關(guān)中斷”本身也能阻止再次發(fā)生中斷阿,那么replay的必要性在什么地方呢?

不是關(guān)中斷的時候進行enable,是enable的時候進行了關(guān)中斷,加鎖的同時關(guān)了中斷啊
spin_lock_irqsave(&desc->lock, flags);//這里加鎖并關(guān)中斷,同時保存中斷當前狀態(tài)
        switch (desc->depth) {
        case 0:
                WARN_ON(1);
                break;
        case 1: {
                unsigned int status = desc->status & ~IRQ_DISABLED;

                desc->status = status;
                if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
                        desc->status = status | IRQ_REPLAY;
                        hw_resend_irq(desc->handler,irq);
                }
                desc->handler->enable(irq);
                /* fall-through */
        }
        default:
                desc->depth--;
        }
        spin_unlock_irqrestore(&desc->lock, flags);//解鎖,同時恢復加鎖前的中斷狀態(tài)

[ 本帖最后由 dengcainiao 于 2008-6-11 10:33 編輯 ]

論壇徽章:
0
10 [報告]
發(fā)表于 2008-06-11 10:09 |只看該作者
原帖由 dengcainiao 于 2008-6-11 09:06 發(fā)表
中斷不是在enable中完成的,如ZX_WING兄弟說的IPI在開中斷以后才會被提交,即在spin_lock_irqrestore(&(irq_desc.lock), flags);之后。所以說中斷完成應該是在enable函數(shù)外邊,在二者之間有機會插入一組diable/ ...

謝謝!
我理解了你說的“IPI在開中斷以后才會被提交,即在spin_lock_irqrestore(&(irq_desc.lock), flags);之后”。
但嚴格來說,提交IPI應該是在spin_lock_irqrestore(&(irq_desc.lock), flags)內(nèi)部,中斷即被打開,然后控制路徑會立即進入中斷處理代碼,執(zhí)行完中斷處理代碼后,才會從spin_unlock_irqrestore函數(shù)中退出,然后繼續(xù)執(zhí)行enable函數(shù)的結(jié)尾部分。

謝謝你們的回答,以下我現(xiàn)在的理解,不知道對不對:
如果要發(fā)生多次的中斷,必須在上文中的這段執(zhí)行路徑中又一次發(fā)生disable/enable。
對于其他CPU,就需要在spin_unlock_irqrestore打開鎖之后,以遠遠超越當前這個CPU的速度飛快地完成disable->enable->中斷執(zhí)行的過程,而又不能快到執(zhí)行了_ _do_IRQ( )中的if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))。
而這段時間里這個CPU必須恰好不緊不慢的執(zhí)行"進入中斷->_ _do_IRQ( )"的過程,但又不能執(zhí)行到if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))。
(否則這2個中斷又可能被合并了)
然后,其中一個CPU以飛快的速度迅速完成if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))之后的全部中斷處理工作,而且必須趕在另一個CPU執(zhí)行if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))之前。這才能避免2個中斷被IRQ_INPROGRESS合并。

如果只考慮同一個CPU,感覺不太可能發(fā)生2次中斷,唯一要考慮的就是spin_unlock_irqrestore執(zhí)行中,但還沒有進入中斷服務之間這段時間可能發(fā)生的內(nèi)核搶占。但如果搶占了,搶占后會首先執(zhí)行中斷處理,直到irq_desc[irq].handler->end(irq);,等到回到原先的任務時,已經(jīng)沒有中斷了。

天哪,重看一便,感覺寫的好亂,但也沒辦法改得容易讀一些。

[ 本帖最后由 OstrichFly 于 2008-6-11 10:21 編輯 ]
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP