Download presentation
Presentation is loading. Please wait.
Published byしらん ねごろ Modified 約 7 年前
1
●マルチプロセッサ管理 □ スケジューリング ☆ 対称型マルチプロセッサシステム ☆ プロセススケジューラ ☆ スケジューリングポリシー □ ハードウェア割込み ☆ プロセッサ間割込み □ 時計 □ ソフトウェア割込みハンドラ □ 排他制御 ☆ スピンロック ☆ カーネル本体のロック ☆ スケジューラ資源 ☆ その他の資源 ☆ カーネルロック処理の流れ ☆ カーネルロック関数の動作詳細 ☆ 割り込み処理の排他 □ マルチプロセッサシステムの起動
2
(Interrupt Controller Communications)
■マルチプロセッサ管理 スケジューリング - 対称型マルチプロセッサシステム Linux v2.0 から、対称型マルチプロセッサシステム(SMP : Symmetric Multi Processing)が サポートされている。全てのCPUは対等に扱われ、システム上の全プロセスは、どのCPU上 でも実行可能である。また、システムに発生する割り込みに対応するハンドラについても、 どのCPUからも処理できる。 メモリシンメトリ 全てのプロセッサが同じメインメモリ を共有し、物理アドレスは全て同じ になる。プロセッサは全て同じカーネ ルを実行し、データとアプリケーション は全てのプロセッサで認識され、どの プロセッサでも使用、実行できる。 メインメモリ ブートプロセッサ アプリケーションプロセッサ CPU0 CPU1 割り込み コントローラー 割り込み コントローラー 入出力シンメトリ 全てのプロセッサが同じ入出力サブ システム(I/Oポート、割り込みコント ローラーを含む)を共有する。これに より、入出力でボトルネックが生じる 可能性が低くなる。 ICC バス (Interrupt Controller Communications) 割り込み 8259A I/O 割り込み コントローラー
3
CPU0 CPU1 スケジューリング - プロセススケジューラ current current
スケジューリング - プロセススケジューラ マルチプロセッサマシンでLinuxを動作させた場合、RUNキューに繋がっているプロセスのうち CPU数分のプロセスが同時に実行される(カレントプロセスはCPUの数だけ存在する)。 スケジューラは全てのCPU上で動作し、それぞれが勝手にプロセスを選びだす。 task_struct task_struct task_struct task_struct runqueue_head RUNNING has_cpu=OFF RUNNING has_cpu=ON RUNNING has_cpu=OFF RUNNING has_cpu=ON init_tasks[] task_struct init_task (idle) cpu 0 cpu 1 current current CPU0 CPU1 task_struct init_task (idle) プロセスの選択条件 ・実行可能なプロセス(stateがTASK_RUNNING) ・まだCPUを割り当てられていない(has_cpuがOFF) ・プライオリティが高いプロセス 実行するプロセスがない場合 CPU毎に用意されたアイドル プロセスに実行権を与える
4
スケジューリング - スケジューリングポリシー(1)
スケジューリング - スケジューリングポリシー(1) マルチプロセッサ動作時のスケジューラの動き(マルチプロセッサの為の追加) schedule () タスクキューtq_schedulerの実行 run_task_queue () ソフト割り込みハンドラ呼び出し do_softirq () プリエンプション要求をクリア if (呼び出し元プロセスがTASK_RUNNING以外) プロセスをRUNキューから外す del_from_runqueue () while (RUNキューの全プロセスに対して) { has_cpuがOFFのプロセスのうち プライオリティが最も高いプロセスを探す goodness () } while (システム上の全プロセスに対して) { プライオリティの再計算 選ばれたプロセスをCPU割り当て状態にする has_cpu = ON 選ばれたプロセスのtask_structにCPU番号を格納 processorメンバ メモリ空間の切り替え enter_lazy_tlb (), switch_mm () プロセスコンテキスト切り替え switch_to () if (まさに今、WAITするためCPUを放棄したプロセスにwake_upが行われた) カレントプロセスに再スケジューリング要求 CPUを放棄したプロセスのCPU割り当てを解除 has_cpu = OFF
5
・起床処理が動作した(reschedule_idle()を実行している)CPU)と 異なる場合は、プロ
スケジューリング - スケジューリングポリシー(2) スケジューラに再スケジューリング要求を出す reschedule_idle () も、マルチプロセッサを意識 した動作になった。CPU間通信はヘビーな為、 ほどほどのところで妥協した作りとなっている。 以下の方針でプリエンプト要求を出すCPUを選択する。 ※2CPUの場合でも優先順位の1番目と2番目のプロセスにCPUが割り当てられる訳ではない 1. 起床したプロセスがWAITする前に動作していたCPUが、idle状態であれば、 その CPUに対しプリエンプト要求を出す。 ・起床処理が動作した(reschedule_idle()を実行している)CPU)と 異なる場合は、プロ セッサ間通信を利用してCPUへ通知を行う 。(smp_send_reschedule()) 非常に重い 2. 起床したプロセスがWAITする前に動作していたCPUが上で 現在動作しているプロ セスとプライオリティを比較 (preemption_goodness())し、起床したほうのプロセスの プライオリティが高ければ、そのCPUへプリエンプト要求を出す。 3. idle状態のCPUを探し、そのCPUに対してプリエンプト要求を出す 4. インタラクティブな動作をするプロセス(shellなど)や、リアルタイム スケジューリング ポリシのプロセスなら、他CPU上への プロセスマイグレーションを試みる。ただし、 他CPU上で動作している プロセスからCPUを奪い取るためには、今起床したプロセ スの方が 遙に高いプライオリティを持っている必要がある。 (preemption_goodness()) 5. 現在起床したプロセスのプラオイリティより 他CPU上により低いプライオリティのプロ セスが存在しても、 プロセスマイグレーションまで行なわず、再スケジューリング さ れるするのを待つ。 (プロセスマイグレーション処理は非常に重く、スループットの面で逆に効率が悪くなる)
6
スケジューリング - スケジューリングポリシー(3)
スケジューリング - スケジューリングポリシー(3) v2.2では、「今起床されたプロセスが、現在このCPUのカレントプロセスから起床 されたもの であった場合、他のCPU上へ実行権を与えられても カーネルロック(後述lock_kernel())処理 でビジーウェイトする だけで無駄なのでこのままにしておく」という処理が行われていたが、 v2.4では原則Linuxカーネル内をカーネルロック(後述lock_kernel()) を行わずに走行できるよ うになったため、この処理は外された。
7
Global timer interrupt
■ハードウェア割り込み デバイスから発生したハードウェア割り込みは、どのCPUに通知されても動作することが 許されている。異なるレベルのIRQ割り込みであれば、複数のCPU上で並列に割り込み 処理を行うことができる。 ※ハードウェアが、CPU間割り込みとCPU固有のクロック割り込みを発生可能なことが前提 CPU間割り込み プロセッサ間の同期用 CPU固有のクロック割り込み CPU固有のクロック処理用 Local timer interrupt Local timer interrupt CPU0 CPU1 Inter-processor interrupt Interrupt Sceduling APIC Device interrupt Global timer interrupt
8
プロセッサ間割り込み 一方のCPUで発生したイベントを他のCPUに通知する手段であり、以下に利用されている。
ハードウェアでサポートされていることが前提 一方のCPUで発生したイベントを他のCPUに通知する手段であり、以下に利用されている。 再スケジューリング要求 smp_send_reschedule () ・指定CPUへ、プロセスの再スケジューリング要求を出す send_IPI_mask () ・割り込み受信CPU側では、smp_reschedule_interrupt () が呼び出される ※この関数は何もせずに即リターンするが、割り込み処理からの戻りで プリエンプション処理が自動的に動作するので目的は達成される TLBフラッシュ要求 flush_tlb_others () ・指定CPUの指定TLBに対してフラッシュを要求する send_IPI_mask () ※あるCPU上で仮想空間の状態を変更したとき、その空間を参照している CPUに通知しなければならない(PTEを変更してもCPU内のTLBは未更新) ・割り込み受信CPUではsmp_invalidate_interrupt ()が呼び出され、指定された 領域に対応するTLBをフラッシュする ・CPU間割り込みを利用したTLBフラッシュは非常に重いため、無駄に呼び出 さない。struct_mmのcpu_vm_maskメンバに参照元CPUを保持し、それに対し てのみCPU間割り込みを使用する TLBフラッシュ要求 flush_tlb_all () ・自分以外の全CPUにTLBフラッシュ要求を出す smp_call_function () TLBフラッシュが完了するまでビジーウェイトする ・割り込み受信CPUでは、flush_tlb_all_ipi () が呼び出され、TLBをフラッシュ
9
CPU停止要求 smp_send_stop ()
・自分以外の全CPUにCPU停止要求を行う smp_call_function () ・割り込み受信CPUでは、stop_this_cpu () が呼び出され、CPUに対する割り込 みを禁止し、CPUを停止する。 CPU起動要求 ・Intel CPUの場合、二つ目以降のCPU起動にプロセス間割り込みを利用 smp_call_function (), smp_call_function_interrupt () ・汎用のプロセッサ間割り込み処理関数。他CPUに実行させたい関数を渡す。 プロセッサ間割り込みハンドラの完了を待ち合わせることも可能。 send_IPI_allbutself () 自分以外の全CPUに対してプロセッサ間割り込みを送る。 send_IPI_mask () 指定したCPU群に対してプロセッサ間割り込みを送る。 send_IPI_self () ・自CPUに対してプロセッサ間割り込みを送る。 ・保留状態の割り込みに対応する割り込みハンドラを起動するときに利用 hw_resend_irq ()
10
■時計 マルチプロセッサマシンでは、カレントプロセスはCPU毎に存在するため、プロセスのプロファ
timer_bh ()とは別に、各CPU上に固有の時計を動かす。 timer_bh() task_struct task_struct do_timer() BH Handler profiling profiling Smp_local_timer_interrupt () Smp_local_timer_interrupt () current current CPU0 CPU1 マルチプロセッサシステムでは、 ・プロファイリング ・統計情報収集 ・再スケジューリング要求 はグローバル時計のdo_timer ()、 timer_bh () ではなく、ローカル時計の smp_local_timer_interrupt ()で行う Local timer interrupt Global timer interrupt Local timer interrupt
11
■ソフト割り込みハンドラ Linuxカーネルは割り込みの遅延実行メカニズムとしてソフトウェア割り込みメカニズムが
提供されているが、マルチプロセッサ時には各CPUで並列動作が可能な作りになっている。 (旧BHハンドラでは並列動作ができないため、書き換えられた) CPU0 CPU1 BH Handler (Old Type) bh_base [ ] tasklet_hi_action () softirq_action [ ] HI_SOFTIRQ TCP/PROTOCOL stack net_rx_action () net_tx_action () NET_TX_SOFTIRQ NET_RX_SOFTIRQ TASKLET_SOFTIRQ tasklet_let_action () execute task_letvec [ ] tasklet_struct tasklet_struct CPU 0 (*func)() (*func)() CPU 1 tasklet_struct tasklet_struct tasklet_struct tasklet_struct (*func)() (*func)() (*func)() (*func)()
12
TASKLET_SOFTIRQ HI_SOFTIRQソフトウェア割り込みレベル ・各CPU別にそれぞれハンドラをCPU毎に分類されたtask_letvect [ ]へ登録する ・ハードウェア割り込みとソフトウェア割り込みが同一CPUで処理ができるので、 処理の効率は高そう NET_TX_SOFTIRQ NET_RX_SOFTIRQソフトウェア割り込みレベル ・TCP/IPプロトコルスタック送受信処理用。各々のCPUで並列実行が可能である BHハンドラ ・TASKLET_SOFTIRQソフトウェア割り込みである tasklet_action () の延長で呼 び出される ※旧システムとの互換性のために、BHハンドラはシステム上に同時に一つし か存在できないようにロックを行っている(global_bh_lock変数)。 ・BHハンドラ実行前に、他CPU上でBHハンドラが実行されているかどうか調べ、 ロックされている場合は処理そのものをスキップする。 ※スキップした処理は次にCPUにTASKLET_SOFTIRQ割り込みが発生したタ イミングで処理される。
13
CPU0 CPU1 資源 ビジーウェイト ■排他制御 - スピンロック Linuxは、他のCPUとの資源排他にスピンロックを利用している。
■排他制御 - スピンロック Linuxは、他のCPUとの資源排他にスピンロックを利用している。 CPU0 資源 CPU1 スピンロック spin_lock () スピンロックが 解除されるまで 使用不可能 アクセス スピンロック解除 spin_unlock () ビジーウェイト 資源が解放されるまで 待ち状態 資源を利用する時間が短い場合には、CPU間通信を利用する排他制御より効率がよい。
14
スピンロック - スピンロック関数 spin_lock (&val) が成功すると、ロック変数 val で保護された資源に対して安全にアクセス することが可能になる。資源へのアクセスが終了したら、spin_unlock (&val) でロックの解除 を行う。実装上、ロック時間は最低限の時間にしなければならない。 spin_lock (&val) 変数 val のロックを行う。 ロックが失敗した場合は、ロックに成功するまでビジーウェイトになる。 spin_unlock (&val) 変数 val のロックを解除する。 spin_trylock (&val) 変数 val のロックを行う。即ロックできない場合はエラーとなる。 spin_lock_irq (&val) ローカルCPUの割り込みを禁止し、変数 val のロックを行う。 ロックが失敗した場合は、ロックに成功するまでビジーウェイトになる。 ※資源アクセスの可能性がある割り込みを抑制することができる。 spin_unlock_irq (&val) 変数 val のロックを解除し、ローカルCPUの割り込み禁止を解除する。
15
readロック、writeロックのメカニズムも提供されている。
参照頻度が高く、更新を伴わない資源に関しては、単純なスピンロックより、複数のプロセス からの同時アクセスを許可する以下の関数の方が効率がよい。 read_lock (&val) 変数 val のreadロックを行う。 val がwriteロックされている場合は、writeロックが解除されるまでビジーウェイト となる。複数のプロセスから多重にロックすることも可能 write_lock (&val) 変数 val のwriteロックを行う。 val がreadロックまたはwriteロックされている場合は、ロックが解除されるまで ビジーウェイトとなる。 write_trylock (&val) 変数 val のwriteロックを行う。 val がreadロックまたはwriteロックされている場合は、エラーとなる。 read_unlock (&val), write_unlock (&val) 変数 val のreadロックまたはwriteロックを解除する。
16
カーネル全体のロック Linux Kernel
V2.2 以前は、システムコール発行時点でカーネル全体をロックしていたが、V2.4 ではスピン ロックを用いるコードに書き直された(ネットワーク関連のコードはほぼ全て書き換え)。 preemption Interrupt network Linux Kernel scheduler runq device driver buffer Kernel lock resources vmem device driver timer Page fault System call Timer interrupt
17
ファイルI/Oに関しては、read/writeファイルI/Oに 関してはカーネルロックを行なわず、
スピンロックで実現できるよう コードが書き直されている。ただし、メタデータ(inode、間接ブ ロック、 ディレクトリ、フリーbitmapなど)を更新するときは、相変わらず カーネルロックを行っ ている。(資源間の依存関係が深く、 単純にはスピンロックに書き直せないものと思われる) 空間管理に関しては、ページフォルトのルートには カーネルロック処理が姿を消している。 しかし依然としてカーネルロックで保護されている 資源は多数残されている。 それらの資源 はこのカーネルロックを行ったプロセスからで ないとアクセスは許されていない。 複数のプ ロセスが同時にlock_kernel()行おうと すると、そのうちの一つのプロセスのみがロックに成 功し、 カーネルロックで保護されている資源を利用する権利を得る。 他のプロセスはカーネ ルロックが終了するのをlock_kernel ()内でビジーウェイトして待ち続ける。 CPU数の多いマルチプロセッサマシンでは、まだこのあたりが ネックになりそうであり、まだ まだ改善の余地がある。
18
スケジューラ資源 スケジューラはシステムコール処理と並行して動作が可能なように、独自の排他をしている。
これにより、一方のCPUでシステムコール実行中でも、他方のCPUでプロセスのスケジューリ ングが可能になった。 システムコール処理中からスケジューラが呼び出されると まずカーネルのロックを解除を行 い、その後でスケジューラ資源の ロックを行う。 これは、プロセスがCPUを放棄して待ちに入っている間は、 別のプロセスがカーネルロックを 行うことを可能であることを 意味している。 元のプロセスが起床し再スケジューリングされると、 スケジューラ内で再びこのプロセスに対 しカーネルロックを行なった後に、処理の続きを開始する。 もしこの時、他のCPU上でカーネルをロックしている プロセスがいれば、ここでスピンロック して待つことになる。 ※v2.4では、スケジューラ資源以外でも多くの資源がカーネルロックの対象外になり、 個々の資源ごとにスピンロックで保護されるようになった。 → 複数のCPU上で並行してシステムコール処理、割り込み処理が可能
19
カーネルロック処理の流れ 2個のCPU上のプロセスが、それぞれカーネルロックを発行した場合の典型的な動きは、
以下の通りである。通常のspin_lock () によるロックと異なるのは、ロックのネストを許可して いるところと、ロックした状態でスケジューラを呼び出すことができるところである。また、通常 のスピンロックと異なりカーネルロックを行った状態で他の資源のスピンロックを行う。 CPU 0 CPU 1 プロセスC プロセスA プロセスB ビジーウェイト中 lock_kernel () lock_kernel () scheduler sleep_on () カーネルロック期間 wake_up () lock_kernel () unlock_kernel () unlock_kernel ()
20
カーネルロック関数の動作詳細 kernel_flag Linuxカーネルをロックするためのフラグ。
lock_depth task_struct内のメンバで、ロックのネスト数を保持。 lock_kernel () カーネルの資源をロックする。 if (current->lock_depth++ >= 0) spin_lock(&kernel_flag); unlock_kernel () カーネルの資源をロックを解除する。 if (--current->lock_depth <= 0) spin_unlock(&kernel_flag); release_kernel_lock () スケジューラを呼び出してCPUを放棄する前に、一時的にカーネルロックを 解除する。 if (current->lock_depth >= 0) spin_unlock(&kernel_flag); reacquire_kernel_lock () 再スケジューリング後、再びカーネルロックを行う。カーネルロックの状態を release_kernel_lock () の呼び出し前に戻す。 if (current->lock_depth >= 0) spin_lock (&kernel_flag);
21
ICC(Interrupt Controller Communications)バス
割り込み処理の排他 Linuxは、デバイスからの割り込みがどのCPUに入っても問題ないように作られており、 複数の割り込みハンドラが別々のCPU上で動作することができる。 割り込みハンドラ間で共有資源がある場合は、ハンドラ間で割り込みの排他処理が必要。 CPU 0 CPU 1 割り込みA ハンドラ 資源 割り込みB ハンドラ 資源 共有資源 排他処理 割り込みA 割り込みB ICC(Interrupt Controller Communications)バス 割り込みA 割り込みB ※Linuxカーネル処理も複数のCPU上で並列動作するので、排他処理が必要
22
排他処理動作の基本方針 CPU 0 CPU1 interrupt IRQ2 interrupt IRQ2 irq_desc[2]
header2 interrupt IRQ2 irq_desc[2] *action *handler hw_resend_irq(IRQ2) *action *handler IRQ_PENDING CHECK *action *handler
23
●同じレベルのIRQ割り込みハンドラはシステム上に1つしか存在しないようにする。
・割り込みハンドラ中は irq_desc に IRQ_INPROGRESS フラグをセットする ・割り込みが発生した場合、 IRQレベルを調べ同じレベルの割り込みハンドラを実行中の CPUが存在している場合は割り込みハンドラの実行を委ねて、そのCPUは何もせずに割 り込みから復帰。(irq_desc に IRQ_PENDING フラグをセット) ・割り込み処理から復帰するとき、そのレベルの割り込み要求が保留されていれば、 再度、同じIRQレベル割り込みを強制的に発生( hw_resend_irq() )させる。 ●異なるIRQレベルの割り込みハンドラは別CPUで並列動作を許可し、同一CPU上での異な るIRQレベルの割り込みのネストも許可する。 ●異なるIRQレベルの割り込みハンドラ間で共有する資源、 および割り込みハンドラとLinux カーネル本体処理とで 共有される資源の排他処理ははスピンロックを利用する。 ・spin_lock_irq ()、spin_unlock_irq () を利用する。 ・排他対象である資源へアクセスしているのが、割り込みハンドラでもLinuxカーネルでも 区別しない。 ※Linuxカーネルはシステム全体のすべての割り込みを禁止する __global_cli () も提供す る。いずれかのCPUでこの関数が呼び出されると割り込みハンドラと旧BHハンドラの実行 が禁止される。他のCPUが割り込み禁止区間走行中に自CPUが割り込みを受けた場合、 他のCPU上の割り込み禁止区間終了を自CPUはビジーウェイトして待ち続ける。 逆に他の CPUで割り込みハンドラの実行中の時は、自CPUは割り込み禁止区間に 入ることはでき ず、自CPUはハンドラ終了を待ち続ける。
24
2つのCPUで割り込みハンドラと割り込み禁止区間が相互に同期をとりながら実行する 様子を以下に示す。
__global_cli () __global_cli () interrupt spin_lock... __global_sti () interrupt __global_sti () interrupt __global_cli () __global_sti ()
25
unsigned int global_irq_lock; unsigned int global_bh_lock; struct {
割り込み処理とソフトウェア割り込みの排他メカニズム 以下のフラグを使って、割り込み処理、ソフトウェア割り込みの排他を行う。 unsigned int global_irq_lock; unsigned int global_bh_lock; struct { unsigned int __local_irq_count; unsigned int __local_bh_count; : } irq_stat [NR_CPUS]
26
global_irq_lock 全割り込み禁止フラグ
・__global_cli () で全割り込み禁止時に設定する。__global_sti () で解除。 ・handle_IRQ_event () による割り込みハンドラ起動時に、上記変数がクリアされ るのを待ってirq_enter()でビジーウェイトする 。 ・旧BHハンドラのbh_action () では、上記フラグがセットされているときは、 hardirq_trylock () で起動をスキップする。 ・他CPUからの__global_cti () による全割り込み禁止要求時は、他CPUの __global_sti () による割り込み禁止処理が終了するのをビジーウェイトする。 local_irq_lock ローカルCPU上で動作している割り込みハンドラのネスト数 ・割り込みハンドラの起動時(handle_IRQ_event ())時に irq_enter () でカウントアップ、終了時にirq_exit () でカウントダウンする。 ・ソフトウェア割り込みハンドラ(do_softirq())では、上記フラグがセットされている 時(in_interrupt())は起動をスキップする。ローカルCPU上で割り込みハンドラが 動作しているときは起動しない。 ・旧BHハンドラ(bh_action())では、上記フラグがセットされているとき (hardirq_trylock())は起動をスキップする。 ・他CPUからの全割り込み禁止(__global_cti())を行う場合、全てのCPUの上記 変数がクリアされるまで終了を待ちあわせする。
27
global_bh_lock 旧BHハンドラ実行中を示すフラグ
・旧BHハンドラ起動時(bh_action())設定、処理終了後解除を行う。 (spin_trylock(global_bh_lock) ) ・旧BHハンドラを起動するときに、別のCPU上ですでに動作していたら処理を スキップする。 local_bh_count ローカルCPU上で動作しているソフトウェア割込みハンドラ実行中を 示すフラグ。 ・ソフトウェア割込み(do_softirq())起動時にlocal_bh_disable()でカウントアップ し、終了時にlocal_bh_enable()でカウントダウン。 ・do_softirq()ソフトウェア割込みハンドラでは、上記フラグがセットされているとき は起動をスキップ(in_interupt())。 (同じCPU上でソフトウェア割込みハンドラがネストするのを避ける) ・プロセッサ間割込み(smp_call_function())処理中もBHハンドラの起動を抑制 するためにカウントアップ。 ・他CPUからの全割込み禁止(__global_cti())でソフトウェア割込みハンドラ終了 を待ち合わせるために参照。
28
1.__global_cli() による割込み禁止状態と割込みハンドラまたはBHハンドラは、システム上 に共存できない。
今までの動きをまとめると 1.__global_cli() による割込み禁止状態と割込みハンドラまたはBHハンドラは、システム上 に共存できない。 2.割込みハンドラと旧BHハンドラは、システム上に共存できる。ただし、割込みハンドラを 優先的に動作させる。 3.旧BHハンドラはシステム上に1つだけ存在することができる。 4.ソフトウェア割込みハンドラは、1、2、3と完全に独立して動作する。ただし、割込み ハンドラを優先的に動作させる。 interrupt handler __global_cli () global_irq_lock local_irq_count [] global_bh_lock local_bh_count[] BH handler softirq handler update refer
29
その他の関数 ソースコードを読む上で役に立つ関数
local_irq_disable () ローカルCPUへの割込みを禁止する。__cli () と同じ。 local_irq_enable () ローカルCPUへの割込み禁止を解除する。__sti () と同じ。 local_bh_disable () ローカルCPU上でのソフトウェア割込みハンドラの実行を禁止する。 local_bh_enable () ローカルCPU上でのソフトウェア割込みハンドラの実行禁止を解除する。 __global_cli () マルチプロセッサシステムでは cli () がこの関数にマップされている ・ローカルCPUの割込みを禁止 ・get_irqlock () で、以下の全てのハンドラの待ち合わせを行う。 システム上の全割込みハンドラの終了 ローカルCPU上のソフトウェア割込みハンドラの終了 システム上の全ての旧BHハンドラの終了
30
・local_irq_countをカウントアップする。 ・グローバルな全割込み禁止の解除を、ビジーウェイトして待つ。
irq_enter () ・local_irq_countをカウントアップする。 ・グローバルな全割込み禁止の解除を、ビジーウェイトして待つ。 irq_exit () local_irq_countをカウントダウンする。 hardirq_trylock () ローカルCPUで割込みハンドラが動いていない状態で、かつ、グローバルに 割込みが禁止されていないことをチェックする。 (実際には何かをロックするわけではなく、名前は過去のコードの名残) in_interrupt () ローカルCPUで、割込みハンドラもしくはソフトウェア割込みハンドラが動作して いるかをチェックする。 【補足説明】 v2.2以前のマルチプロセッサ機能は原始的であり、Linuxカーネル処理全体をロックしていた ため、システムコール処理の大部分を占める用途では性能を発揮できなかった。 科学技術計算やGUIなどはマルチプロセッサの性能向上を来たい出来たが、ファイルI/O やネットワーク処理が主な仕事となるサーバなどには向いていなかった
Similar presentations
© 2024 slidesplayer.net Inc.
All rights reserved.