青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

那誰(shuí)的技術(shù)博客

感興趣領(lǐng)域:高性能服務(wù)器編程,存儲(chǔ),算法,Linux內(nèi)核
隨筆 - 210, 文章 - 0, 評(píng)論 - 1183, 引用 - 0
數(shù)據(jù)加載中……

linux內(nèi)核V2.6.11學(xué)習(xí)筆記(6)--中斷處理

每個(gè)中斷處理的函數(shù)存放在entry.S中的interrupt數(shù)組中,該數(shù)組有NR_IRQS個(gè)元素.
每個(gè)元素做的工作有:
ENTRY(irq_entries_start)
.rept NR_IRQS
    ALIGN
1:    pushl $vector-256
    jmp common_interrupt
.data
    .
long 1b
.text
vector
=vector+1
.endr

    ALIGN
common_interrupt:
    SAVE_ALL
    movl 
%esp,%eax
    call do_IRQ
    jmp ret_from_intr

首先將中斷向量- 256保存在棧中
其中的SAVE_ALL做的工作包括:
#define SAVE_ALL \
    cld; \
    pushl 
%es; \
    pushl 
%ds; \
    pushl 
%eax; \
    pushl 
%ebp; \
    pushl 
%edi; \
    pushl 
%esi; \
    pushl 
%edx; \
    pushl 
%ecx; \
    pushl 
%ebx; \
    movl $(__USER_DS), 
%edx; \
    movl 
%edx, %ds; \
    movl 
%edx, %es;

也就是保存一些寄存器, 然后調(diào)用do_IRQ函數(shù):

do_IRQ函數(shù)首先調(diào)用irq_enter()函數(shù):
#define irq_enter()                    \
    
do {                        \
        account_system_vtime(current);        \
        add_preempt_count(HARDIRQ_OFFSET);    \
    } 
while (0)

其中要注意的是函數(shù)add_preempt_count, 它改變的是當(dāng)前進(jìn)程中thread_info中的成員preempt_count,它是一個(gè)32位的字段,分為幾個(gè)部分,:
0-7位: 搶占計(jì)數(shù)器, 最大值255
8-15位: 軟中斷計(jì)數(shù)器, 最大值255
16-27位: 硬中斷計(jì)數(shù)器, 最大值4096
28位: PREEMPT_ACTIVE標(biāo)志

因此,在hardirq.h中定義了幾個(gè)宏:
#define PREEMPT_BITS    8
#define SOFTIRQ_BITS    8
#define HARDIRQ_BITS    12

#define PREEMPT_SHIFT    0
#define SOFTIRQ_SHIFT    (PREEMPT_SHIFT + PREEMPT_BITS)
#define HARDIRQ_SHIFT    (SOFTIRQ_SHIFT + SOFTIRQ_BITS)

#define PREEMPT_OFFSET    (1UL << PREEMPT_SHIFT)
#define SOFTIRQ_OFFSET    (1UL << SOFTIRQ_SHIFT)
#define HARDIRQ_OFFSET    (1UL << HARDIRQ_SHIFT)

因此, 函數(shù)調(diào)用add_preempt_count(HARDIRQ_OFFSET)是增加其中硬中斷的計(jì)數(shù).

回到do_IRQ函數(shù)調(diào)用中,接下來(lái):
#ifdef CONFIG_4KSTACKS

    curctx 
= (union irq_ctx *) current_thread_info();
    irqctx 
= hardirq_ctx[smp_processor_id()];

    
/*
     * this is where we switch to the IRQ stack. However, if we are
     * already using the IRQ stack (because we interrupted a hardirq
     * handler) we can't do that and just have to keep using the
     * current stack (which is the irq stack already after all)
     
*/
    
if (curctx != irqctx) {
        
int arg1, arg2, ebx;

        
/* build the stack frame on the IRQ stack */
        isp 
= (u32*) ((char*)irqctx + sizeof(*irqctx));
        irqctx
->tinfo.task = curctx->tinfo.task;
        irqctx
->tinfo.previous_esp = current_stack_pointer;

        asm 
volatile(
            
"       xchgl   %%ebx,%%esp      \n"
            
"       call    __do_IRQ         \n"
            
"       movl   %%ebx,%%esp      \n"
            : 
"=a" (arg1), "=d" (arg2), "=b" (ebx)
            :  
"0" (irq),   "1" (regs),  "2" (isp)
            : 
"memory""cc""ecx"
        );
    } 
else
#endif

這段代碼僅在線程棧大小是4K的情況下被調(diào)用, 有一個(gè)名為hardirq_ctx的數(shù)組保存硬中斷的請(qǐng)求棧,它的定義是:
union irq_ctx {
    
struct thread_info      tinfo;
    u32                     stack[THREAD_SIZE
/sizeof(u32)];
};

static union irq_ctx *hardirq_ctx[NR_CPUS];
static union irq_ctx *softirq_ctx[NR_CPUS];
也就是說(shuō), 這兩個(gè)數(shù)組的元素?cái)?shù)量由CPU數(shù)量來(lái)決定.
在系統(tǒng)初始化的時(shí)候, 調(diào)用函數(shù)irq_ctx_init, 分別把這兩個(gè)數(shù)組中的元素(irq_ctx *類型指針)指向hardirq_stack和softirq_stack:
static char softirq_stack[NR_CPUS * THREAD_SIZE]
        __attribute__((__aligned__(THREAD_SIZE)));

static char hardirq_stack[NR_CPUS * THREAD_SIZE]
        __attribute__((__aligned__(THREAD_SIZE)));
因此, 上面的那段do_IRQ函數(shù)中的代碼做的工作比較當(dāng)前thread_info描述符地址(通過(guò)調(diào)用current_thread_info()函數(shù))與hardirq_ctx
的內(nèi)容, 如果相同, 說(shuō)明內(nèi)核已經(jīng)在使用硬件中斷請(qǐng)求棧了, 否則如果不相等那么就要切換內(nèi)核棧,需要保存當(dāng)前進(jìn)程描述符指針和esp寄存器.

接著, do_IRQ函數(shù)調(diào)用__do_IRQ函數(shù),這個(gè)函數(shù)的主要工作有:
// 加鎖
spin_lock(&(irq_desc[irq].lock));
// 響應(yīng)
irq_desc[irq].handler->ack(irq);

// 當(dāng)前狀態(tài)既不是IRQ_REPLAY:The IRQ line has been disabled but the previous IRQ occurrence has not yet been acknowledged to the PIC
// 也不是IRQ_WAITING:The kernel is using the IRQ line while performing a hardware device probe; moreover, the corresponding interrupt has not been raised
irq_desc[irq].status &= ~(IRQ_REPLAY | IRQ_WAITING);

// 當(dāng)前狀態(tài)為IRQ_PENDING:An IRQ has occurred on the line; its occurrence has been acknowledged to the PIC, but it has not yet been serviced by the kernel
irq_desc[irq].status |= IRQ_PENDING;

if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)) // 如果當(dāng)前狀態(tài)不是IRQ_DISABLED 或者 IRQ_INPROGRESS
            && irq_desc[irq].action) {                            // action指針有效
        irq_desc[irq].status |= IRQ_INPROGRESS;                    // 設(shè)置當(dāng)前當(dāng)前狀態(tài)為IRQ_INPROGRESS: A handler for the IRQ is being executed
        do {
            irq_desc[irq].status 
&= ~IRQ_PENDING;                // 設(shè)置當(dāng)前當(dāng)前狀態(tài)不是IRQ_PENDING,因?yàn)橄旅嬉_始處理了
            spin_unlock(&(irq_desc[irq].lock));
            handle_IRQ_event(irq, regs, irq_desc[irq].action);    
// 處理事件
            spin_lock(&(irq_desc[irq].lock));
        } 
while (irq_desc[irq].status & IRQ_PENDING);            // 如果當(dāng)前狀態(tài)還是IRQ_PENDING循環(huán)繼續(xù)
        irq_desc[irq].status &= ~IRQ_INPROGRESS;                // 設(shè)置當(dāng)前狀態(tài)不是IRQ_INPROGRESS
}

irq_desc[irq].handler
->end(irq);
spin_unlock(
&(irq_desc[irq].lock));

在循環(huán)處理IRQ請(qǐng)求的時(shí)候, 最開始要設(shè)置狀態(tài)為 IRQ_INPROGRESS同時(shí)不是IRQ_PENDING, 這個(gè)循環(huán)處理IRQ請(qǐng)求的過(guò)程在當(dāng)前狀態(tài)是IRQ_PENDING則一直進(jìn)行下去,
當(dāng)該循環(huán)處理完畢之后, 再將狀態(tài)設(shè)置為IRQ_INPROGRESS.

在從__do_IRQ函數(shù)返回后, 調(diào)用irq_exit函數(shù):
void irq_exit(void)
{
    account_system_vtime(current);
    sub_preempt_count(IRQ_EXIT_OFFSET);
    
if (!in_interrupt() && local_softirq_pending())
        invoke_softirq();
    preempt_enable_no_resched();
}

該函數(shù)首先調(diào)用sub_preempt_count減少搶占計(jì)數(shù), 然后如果當(dāng)前不在中斷狀態(tài)以及當(dāng)前有未處理的軟中斷(softirq)則調(diào)用invoke_softirq函數(shù)(其實(shí)就是do_softirq函數(shù))
處理軟中斷,最后調(diào)用preempt_enable_no_resched允許內(nèi)核搶占.

posted on 2009-05-03 16:09 那誰(shuí) 閱讀(4709) 評(píng)論(1)  編輯 收藏 引用 所屬分類: linux kernel

評(píng)論

# re: linux內(nèi)核V2.6.11學(xué)習(xí)筆記(6)--中斷處理  回復(fù)  更多評(píng)論   

好底層哦 呵呵
2010-01-02 09:05 | 忘憂三毛
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精品免费一区豆花| 欧美韩国日本综合| 国产午夜精品一区二区三区视频 | 亚洲欧洲日产国产网站| 欧美激情按摩| 欧美色播在线播放| 亚洲综合导航| 久久久国产精品亚洲一区| 亚洲高清资源综合久久精品| 亚洲精品一区二区三区四区高清| 欧美性大战久久久久| 久久婷婷国产综合精品青草| 久久天天躁夜夜躁狠狠躁2022| 99成人在线| 亚洲欧美综合| 亚洲精品在线视频| 亚洲欧美一区二区精品久久久| 在线看片欧美| 亚洲小说欧美另类婷婷| 尹人成人综合网| 亚洲黄色av| 欧美激情一区二区三区不卡| 黄色成人精品网站| 亚洲精品日日夜夜| 狠狠色丁香婷婷综合影院| 欧美激情一区在线观看| 国产精品美女久久久久aⅴ国产馆| 久久手机免费观看| 欧美三级日韩三级国产三级| 麻豆成人在线播放| 国产精品久久婷婷六月丁香| 欧美激情一区二区三区在线视频观看 | 在线视频欧美一区| 91久久精品一区二区别| 亚洲欧美久久久| 一区二区三区欧美| 久久在线观看视频| 久久精品青青大伊人av| 欧美午夜宅男影院在线观看| 亚洲国产精品成人综合色在线婷婷| 国产欧美日韩在线观看| 999在线观看精品免费不卡网站| 曰韩精品一区二区| 欧美在线一级视频| 欧美在线观看视频| 国产精品久久久久久妇女6080| 欧美激情亚洲视频| 在线视频成人| 久久国产精品久久国产精品| 午夜影院日韩| 国产精品成人一区二区| 亚洲理论在线| 一本久久综合亚洲鲁鲁| 欧美成人综合一区| 欧美好吊妞视频| 亚洲高清精品中出| 裸体一区二区| 欧美二区在线| 亚洲日韩第九十九页| 久久综合综合久久综合| 免费观看日韩av| 尤物yw午夜国产精品视频明星| 久久精品99国产精品日本| 久久人人97超碰国产公开结果| 国产一区二区三区丝袜| 午夜日韩福利| 久久全球大尺度高清视频| 一区二区亚洲欧洲国产日韩| 久久久亚洲综合| 欧美激情精品久久久久| 亚洲日本一区二区| 欧美日韩亚洲综合一区| 在线亚洲自拍| 久久精品免费播放| 1204国产成人精品视频| 欧美国产视频日韩| 一本久道综合久久精品| 欧美一区二区女人| 在线播放日韩欧美| 欧美成人精品影院| 一个色综合av| 久久久久看片| 日韩系列在线| 国产欧美丝祙| 久久综合九色综合欧美就去吻| 欧美激情精品久久久久久久变态| 日韩视频在线观看免费| 亚洲在线观看免费视频| 国产精品入口日韩视频大尺度| 欧美在线不卡| 亚洲国产欧美日韩另类综合| 国产精品99久久久久久www| 国产日韩欧美日韩大片| 免费中文字幕日韩欧美| 亚洲视频1区| 欧美.www| 欧美亚洲一区| 日韩视频中文字幕| 国模大胆一区二区三区| 欧美全黄视频| 久久久久综合网| 一本色道久久综合一区| 欧美成年人网| 久久福利视频导航| 99在线|亚洲一区二区| 国产综合自拍| 国产精品久久久久久久7电影| 久久男人资源视频| 亚洲免费一在线| 91久久久久| 免费h精品视频在线播放| 亚洲欧美成人一区二区三区| 亚洲国产三级| 国产亚洲精品bv在线观看| 欧美破处大片在线视频| 久久精品一区二区三区四区| 亚洲少妇一区| 亚洲精品久久在线| 男女精品网站| 久久综合九色综合欧美狠狠| 午夜精品一区二区三区在线视| 日韩视频一区二区| 在线免费高清一区二区三区| 国产视频在线观看一区二区| 国产精品白丝av嫩草影院| 欧美国产精品劲爆| 另类国产ts人妖高潮视频| 久久久99免费视频| 久久国产一区二区三区| 欧美一区二区三区四区在线观看地址| 一本久久综合亚洲鲁鲁五月天| 亚洲精品欧洲| 亚洲精品久久久蜜桃| 亚洲欧洲日本在线| 亚洲激情网站| 亚洲毛片播放| 一区二区三区|亚洲午夜| 99精品视频免费观看视频| 最近中文字幕日韩精品 | 午夜在线播放视频欧美| 亚洲欧美国产视频| 亚洲欧美激情一区| 欧美一进一出视频| 久久av一区二区| 久久综合给合久久狠狠色| 久久综合狠狠综合久久综合88 | 久久久久久久综合| 久久男人av资源网站| 免费日韩av电影| 欧美激情1区2区| 欧美三级免费| 国产亚洲欧美日韩美女| 在线高清一区| 夜夜嗨av色一区二区不卡| 亚洲视频www| 欧美尤物一区| 欧美成人精品h版在线观看| 免费人成精品欧美精品| 欧美成人a∨高清免费观看| 欧美大片免费| 国产精品久久久久久久9999| 国产人久久人人人人爽| 在线观看欧美视频| 99精品国产一区二区青青牛奶| 一本大道久久a久久精品综合 | 亚洲国产精品专区久久| 亚洲精一区二区三区| 西西裸体人体做爰大胆久久久| 久久久精品久久久久| 欧美成人午夜激情| 中日韩视频在线观看| 久久激情中文| 欧美视频网址| 伊人成年综合电影网| 在线亚洲一区二区| 久久嫩草精品久久久久| 亚洲精品孕妇| 久久精品成人| 国产精品久久久久久久久久三级 | 久久久久久久久久看片| 91久久国产精品91久久性色| 亚洲欧美日韩精品久久久| 免费亚洲网站| 国产日产欧产精品推荐色| 日韩视频一区二区三区| 久久免费视频在线观看| 日韩亚洲视频在线| 美女图片一区二区| 国产日韩精品视频一区二区三区 | 黄色亚洲精品| 午夜在线精品偷拍| 亚洲欧洲精品一区二区三区不卡| 性高湖久久久久久久久| 欧美网站在线| 日韩视频一区二区三区| 欧美va亚洲va日韩∨a综合色| 亚洲欧美日韩中文视频| 欧美性天天影院| 日韩天堂在线视频| 亚洲成色最大综合在线|