LINUX KERNEL DEVELOPMENT Ch.7 Interrupts and Interrupt Handlers Iori Mizutni [email protected] 1 Monday, June 17, 13 OSでのハードウェアマネジメント • ポーリング: 定期的にハードウェアの状態を取りに行く オーバーヘッドが生まれる • 割り込み: ハードウェアがカーネルにシグナルを送る仕 組み 無駄なオーバーヘッドが生まれない 2 Monday, June 17, 13 INTERRUPTS • 基本的に割り込みはハードウェアからの電気信号 • プロセッサのクロックと非同期でやってくる • IRQ(interrupt request): unique numeric value for distinction • IRQ0 - the timer interrupt • IRQ1 - the keyboard interrupt by zero” or “page fault” • Asynchronous interrupt from software • Synchronous interrupt from hardware … • “exception” from “divide 3 Monday, June 17, 13 INTERRUPT HANDLERS • ISR(interrupt service routine)とも呼ばれる • 割り込みにはそれぞれ対応したinterrupt • Interrupt handlerが存在する handlerはKernelのデバドラに含まれる • Kernelに実装されている他の関数と違うところ • 割り込みに呼応して呼ばれる • “interrupt context”上で実行される(=blockできない) • システムにかかる負荷をなるべく抑えることが重要 • ハードウェアにackを返すのも仕事の一つ 4 Monday, June 17, 13 TOP HALVES VS. BOTTOM HALVES • Interrupt handlerの宿命 • なるべく早く、たくさんの割り込みを捌く • 難しいので二つに分ける • TIme-critical: ハードウェアにackを返す等 • Differing work: あとでやってもいいもの(Ch8) 5 Monday, June 17, 13 TIME-CRITICALな割り込み (NICの場合) 1. パケットが送られてくる 2. カーネルにNICの状態を通知する 3. カーネルがNIC用のInterrupt handlerを実行する 4. カーネルからNICにackが帰る 5. パケットをメインメモリにコピーする • 割り込みによって瞬時に処理することでタイムアウトを防 ぎ、スループットとレイテンシを確保する 6 Monday, June 17, 13 NETWORK PACKET PROTOCOL PROCESSING • NICにパケットが届いたらその数毎にプロトコルスタック が呼び出される(= interrupt handler’s bottom half) Polling, NAPI, Interrupt Coalescing, GRO, GSO, etc... • iijlabセミナー #12 10GbE時代のネットワークI/O高速化 http://www.youtube.com/watch?v=F8ZKa3JMMF0 http://www.slideshare.net/syuu1228/10-gbeio 7 Monday, June 17, 13 REGISTERING AN INTERRUPT HANDLER • Interrupt handlerはデバイスドライバーが担保する • 一つのデバイスには必ず対応したデバイスドライバがある • デバイスから割り込みが入る場合(がほとんどであるが)、 デバドラはInterrupt handlerをregisterしなければならない • ドライバはrequet_irq関数でInterrupt 8 Monday, June 17, 13 handlerを実装する REGISTERING AN INTERRUPT HANDLER <linux/interrupt.h> 引数 • irq: 割り当てる“Interrupt number” System timerやキーボードはハードコードされている • handler: このInterrupt handlerへの関数ポインタ typedef irgreturn_t (*irq_handler_t) (int, void *); 9 Monday, June 17, 13 INTERRUPT HANDLER FLAGS • request_irqの第3引数はゼロかビットマスクになっている • 主なフラッグ • IRQ_DISABLED: 0x00000020 このIHを実行しているときすべての割り込みを無効化させる場合 • IRQF_TIMER: 0x00000200 System timerへの割り込みを行う場合 • IRQF_SHARED: 0x00000080 一つの割り込みから複数のIHが実行される場合 • 複数のフラッグを有効にする場合 IRQF_TIMER & IRQF_SHARED → 0x00000280 → 640 10 Monday, June 17, 13 request_irq() • 第4引数nameはデバイスの名前のASCIIテキスト • • /proc/irqや/proc/interruptsでユーザアクセスに使われる 第5引数devはポインタで複数のIHがひとつの割り込みから発生した 場合、このIHのユニークな識別子となる • • 多くの場合デバイスのstruct 戻り値 • • 0 on success ほかはすべてエラー • (例)-EBUSY: 既にこの割り込みが掛かっている 11 Monday, June 17, 13 request_irq()によるIHの登録 • “Interrupt context”上など、unblockableなところで呼ぶべき でない request_irq()はsleepすることが出来る • request_irq()が呼ばれると、/proc/irqにエントリが作成され る • /proc/mkdirがprocfsエントリを作成する proc_create()が呼ばれ、kmalloc()でメモリ割り当て が行われる • kmallocもsleepすることが出来る 12 Monday, June 17, 13 AN INTERRUPT EXAMPLE • 割り込みとIHはドライバの中で定義される • irqn: 割り込み • my_interrupt: Interrupt handler • インストール失敗の場合、エラーを出力し戻る 13 Monday, June 17, 13 FREEING AN INTERRUPT HANDLER • ドライバがunloadされるとき、IHをunregisterする必要がある • irqが複数のhandlerを持っている場合はdevに関連付けられている handlerのみを削除する • irqに割り当てられているIHが(最後の)一つの場合、そのIHと共に irqも削除する 14 Monday, June 17, 13 WRITING AN INTERRUPT HANDLER • request_irq()に渡されるhandlerの部分 • Linux Kernel 2.0以前ではdevはなかった • irq_return_tにはIRQ_NONEとIRQ_HANDLEDという戻り値 IRQ_RETVAL(val)というマクロでカーネルに割り込み状態を通知 すべての割り込みに対してIRQ_NONEだとエラー Linux Kernel 2.6以前にはこの機能はなく、ただのint型だった 15 Monday, June 17, 13 SHARED HANDLERS • request_irq()のflagにIRQF_SHAREDをセットする • devはユニークな値(NULLはダメ) • • デバイスの構造体へのポインタがよくつかわれる ある割り込みがどのデバイスから発生しているかを識別できなけれ ばならない • ハードウェアにstatus registerの様な仕組みが必要 • でなければ複数の割り込みに対して共通のIHを使うことは不可能 16 Monday, June 17, 13 IHの例(RTC: REAL-TIME CLOCK) <linux/drivers/char/rtc.c> 17 Monday, June 17, 13 IHの例(RTC: REAL-TIME CLOCK) <linux/drivers/char/rtc.c> 18 Monday, June 17, 13 INTERRUPT CONTEXT • Process context: カーネルがsystem call等のプロセスを動かしている ときの状態 currentマクロは実行中のタスクを指す blockable and reschedulable • Interrupt contextはIHが実行されている状態 currentマクロは割り込みされたタスクを指す unblockable and non-reschedulable • Interrupt contextでは他のプロセスに”割り込み”してしまうため、IHの 中身は限りなく小さく、早くしなければならない • IHが載るKernel stackは32bitシステムで8KB、64bitシステムで16KB しかない 19 Monday, June 17, 13 IMPLEMENTING INTERRUPT HANDLERS 20 Monday, June 17, 13 IMPLEMENTING INTERRUPT HANDLERS • IHの実装はプロセッサ、Interrupt controllerによって異なる • デバイスからプロセッサのInterruptピンへ電気信号が送られてくる と、プロセッサはいま行なっているタスクを止め、事前に定義され たメモリの箇所(entry point)へjumpする • • ここまでアセンブリ! Entry pointからdo_IRQ()が呼ばれ、それに呼ばれはIHが順に実行され ていく • このとき、はじめはirqと割り込みされたタスク中のレジスタの値 がKernel stackに保存される 21 Monday, June 17, 13 IMPLEMENTING INTERRUPT HANDLERS • ptregsにはIRQとその直前のタスク中のレジスタの値が入っている • do_IRQ()はまずハードウェアにackを返す • ackを返した後、そのIRQに登録されているIHがvalidかどうか、既に割 り込み中でないか等確かめる • OKだったらhandle_IRQ_event()を呼び出してIHを実行する 22 Monday, June 17, 13 23 Monday, June 17, 13 IHから戻るところ • ret_from_intr()によってIHからの復帰先を決定する • ユーザースペースに戻る場合 • • • schedule()が呼ばれる カーネルスペースに戻る場合 • preempt_countがゼロのときschedule()が呼ばれる • そうでないときはpreemptしない 両者ともschedule()が呼ばれた後は割り込みされた時点のレジストリ の値がresumeされ、もとのタスクをresumeする 24 Monday, June 17, 13 /proc/interrupts • ProcfsはKernelメモリに存在する仮想ファイルシステムで/procにmount されている • /proc/interruptsには割り込みに関する統計情報がストアされている 25 Monday, June 17, 13 /proc/interrupts IRQ IH called Interrupt Device name count controller (name in irq_request) 26 Monday, June 17, 13 INTERRUPT CONTROL • Linuxカーネルには割り込み状態を取得するためのインターフェース がある • プロセッサで現在実行中の割り込みを無効化させたりマスクするこ とができる(preemptの制御) • synchronization(ch.9-10)でよく使われる 27 Monday, June 17, 13 DISABLING AND ENABLING INTERRUPTS • x86のマシンではdisableがcli命令、enableがsti命令 • • allow_interruptsフラッグをset, clearしているだけ hoge 28 Monday, June 17, 13 DISABLING A SPECIFIC INTERRUPT LINE • hoge 29 Monday, June 17, 13 STATUS OF THE INTERRUPT SYSTEM • プロセッサがInterrupt contextで動いているかどうかを知るためには irqs_disabled()マクロをつかう<asm/system.h> • どのcontextで動いているかは更にin_interrupt(), in_irq()マクロをつかう <linux/hardirq.h> • in_interrupt(): nonzero for any IH • in_irq(): nonzero for a particular IH • もしin_interrupt()がゼロを返すとProcess contextにいることになる 30 Monday, June 17, 13 INTERRUPT CONTROL METHODS 31 Monday, June 17, 13 まとめ • 割り込みはハードウェアデバイスからの電気信号で発生する • OSへ割り込んで”Interrupt context”でIHが実行される • CH7はInterrupt handlerのTop halves(デバイスへのack)について • 各割り込みはIRQで区別する • KernelにはIRQ毎にIHをregister/unregisterするインターフェースがある • 割り込みは他のタスクへ”割り込む”ので、迅速に行われなければな らない 32 Monday, June 17, 13
© Copyright 2024