LINUX KERNEL DEVELOPMENT

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