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

那誰(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>
            久久久综合激的五月天| 免费欧美高清视频| 国产精品美女久久久久av超清| 欧美成人综合一区| 欧美成人按摩| 欧美日韩国产免费| 欧美午夜一区二区| 国产网站欧美日韩免费精品在线观看 | 亚洲人屁股眼子交8| 日韩亚洲不卡在线| 亚洲欧美日韩一区在线| 久久成人18免费观看| 美女网站在线免费欧美精品| 欧美激情91| 亚洲精品乱码久久久久久日本蜜臀| 亚洲另类春色国产| 欧美在线观看一区| 欧美日韩国产成人在线| 久久精品99久久香蕉国产色戒| 久久免费观看视频| 欧美高清在线观看| 国产精自产拍久久久久久| 亚洲福利久久| 亚洲午夜国产一区99re久久| 欧美亚洲专区| 亚洲精品黄网在线观看| 久久国产精彩视频| 国产精品福利网站| 亚洲人成网站在线播| 久久精品视频播放| 在线视频日韩精品| 欧美久久电影| 亚洲承认在线| 久久久久久欧美| 亚洲午夜一区| 欧美日韩国产一级| 亚洲国产美女精品久久久久∴| 欧美一级在线播放| 一本色道久久| 欧美日韩第一区日日骚| 国产日韩亚洲欧美| 午夜电影亚洲| 亚洲欧洲综合另类在线| 久久女同精品一区二区| 国产精品一区久久久| 亚洲一区尤物| 99v久久综合狠狠综合久久| 六月婷婷久久| 在线播放日韩欧美| 久久―日本道色综合久久| 亚洲免费在线精品一区| 国产精品久久久久毛片软件 | 欧美不卡在线视频| 黄色成人片子| 久久综合国产精品| 久久精品99久久香蕉国产色戒| 国产精品资源| 香蕉国产精品偷在线观看不卡| 日韩一级黄色av| 国产精品www994| 亚洲欧美日韩国产一区| 亚洲天天影视| 国产精品福利影院| 先锋资源久久| 久久国产手机看片| 永久免费视频成人| 欧美成人免费一级人片100| 久久精品欧美| 影音先锋日韩有码| 欧美电影免费观看高清完整版| 久久精品成人| 亚洲精品黄色| 一区二区欧美视频| 国产一区二区按摩在线观看| 久久久久久自在自线| 久久久久青草大香线综合精品| 伊人蜜桃色噜噜激情综合| 亚洲福利专区| 欧美精品1区| 亚洲影院一区| 欧美怡红院视频| 亚洲国产清纯| 亚洲视频福利| 影音先锋久久久| 夜色激情一区二区| 国产综合色产在线精品| 亚洲国产日韩一区| 国产精品欧美日韩| 欧美高清在线一区| 国产精品视频你懂的| 欧美成人免费播放| 国产精品久久久亚洲一区| 免费观看亚洲视频大全| 欧美日韩国产综合新一区| 久久免费偷拍视频| 欧美日韩在线视频首页| 久久成人一区二区| 欧美人与性动交cc0o| 可以看av的网站久久看| 欧美一区二区三区免费在线看| 亚洲高清一区二区三区| 亚洲午夜av在线| 亚洲黄色成人久久久| 亚洲一区二区在线| 亚洲毛片在线看| 久久久国产精品一区二区三区| 亚洲精品一区久久久久久| 香蕉免费一区二区三区在线观看| 亚洲乱码精品一二三四区日韩在线| 亚洲免费视频在线观看| 亚洲精品老司机| 久久精品五月| 久久电影一区| 国产精品狠色婷| 亚洲国产精品v| 国内成+人亚洲+欧美+综合在线| 亚洲黄色免费电影| 亚洲福利视频网| 久久精品在这里| 久久人人97超碰国产公开结果| 国产精品福利网| 一区二区三区日韩在线观看| 亚洲精品在线免费| 麻豆乱码国产一区二区三区| 久久香蕉国产线看观看网| 国产日韩精品一区二区三区| 夜夜嗨av色一区二区不卡| 一本一本久久a久久精品综合妖精| 久久中文字幕导航| 美女图片一区二区| 亚洲国产成人不卡| 久久久无码精品亚洲日韩按摩| 久久精品中文字幕一区| 国产乱人伦精品一区二区| 亚洲一二三四区| 欧美一级成年大片在线观看| 国产精品国产精品| 亚洲深夜福利| 欧美亚洲系列| 国产亚洲福利| 久久不见久久见免费视频1| 久久久激情视频| 在线成人h网| 欧美交受高潮1| 一区二区91| 久久精品国产一区二区三区免费看 | 亚洲第一区在线| 欧美成人免费一级人片100| 亚洲国产成人精品视频| 亚洲精品国产无天堂网2021| 欧美多人爱爱视频网站| 亚洲另类自拍| 欧美一区二区三区的| 国产一区二区三区在线观看网站| 久久av资源网站| 亚洲国产精品www| 亚洲午夜在线观看| 国产欧美一区在线| 另类综合日韩欧美亚洲| 亚洲精品黄网在线观看| 亚洲欧美成人一区二区三区| 亚洲免费av片| 黑丝一区二区三区| 蜜臀av性久久久久蜜臀aⅴ| 欧美国产日本韩| 亚洲天堂网站在线观看视频| 国产精品视频最多的网站| 久久精品亚洲一区二区| 亚洲黄色成人久久久| 欧美一区二区三区四区在线 | 99精品国产99久久久久久福利| 欧美激情综合色综合啪啪| 亚洲小视频在线观看| 蜜臀久久99精品久久久久久9| 日韩午夜中文字幕| 国产欧美大片| 欧美精品亚洲精品| 欧美影院在线播放| 日韩午夜激情电影| 女人色偷偷aa久久天堂| 欧美一区二区日韩一区二区| 亚洲精品一区二区三区av| 国产亚洲一本大道中文在线| 欧美日韩国产区| 久久中文在线| 欧美在线观看天堂一区二区三区| 亚洲久久视频| 欧美激情视频在线免费观看 欧美视频免费一 | 欧美在线视屏| 亚洲一区二区三区视频| 亚洲欧洲日韩在线| 欧美成人精品一区| 久久九九精品99国产精品| 国产精品99久久久久久人| 91久久一区二区| 在线观看欧美日本| 很黄很黄激情成人| 国内久久精品| 国产亚洲欧美激情| 国产欧美一区二区白浆黑人|