Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Linuxカーネル解読室輪講@はてな 第6章

3,254 views

Published on

Linuxカーネル解読室輪講@はてな 第6章

Published in: Technology
  • Be the first to comment

Linuxカーネル解読室輪講@はてな 第6章

  1. 1. 「Linuxカーネル解読室」輪講@Hatena第6章「同期と排他」<br />松本一輝<br />@KazkiMatz<br />
  2. 2. 排他処理の主体<br />プロセスコンテキスト<br />システムコール処理<br />プロセススケジューリング<br />ハードウェア割り込みコンテキスト<br />割り込みハンドラ処理<br />プロセススケジューリング(P-82)<br />ソフト割り込みコンテキスト<br />割り込みハンドラ処理<br />ksoftirq<br />
  3. 3. 排他処理の主体と手法<br />先発<br /> (独占中)<br />プロセスコンテキスト<br />(プリエンプションあり)<br />ハードウェア<br />割り込みコンテクスト<br />ソフト<br />割り込みコンテクスト<br />後続<br /><ul><li>semaphore
  4. 4. Pre-emption禁止
  5. 5. スレッド同期</li></ul>プロセスコンテキスト<br />(プリエンプションあり)<br />Pre-emption禁止<br />Pre-emption禁止<br />ハードウェア<br />割り込みコンテクスト<br />N/A<br />(ハンドラはCPU固有)<br />N/A<br />(ソフト割り込みをやり直す)<br />CPUに対する<br />割り込みの禁止<br />N/A<br />(ソフト割り込みは<br />カーネルが逐次処理 P-75)<br />ソフト割り込みの<br />禁止<br />ソフト<br />割り込みコンテクスト<br />Pre-emption禁止<br />
  6. 6. 排他処理の手法<br />割り込み抑制系<br />semaphore<br />スレッド同期<br />
  7. 7. 割り込み抑制系(1)<br />CPUに対する割り込みの禁止<br />semaphoreが使えない場合に有効<br />CPUで割り込みをマスクする(P-66、P-120)<br />CPU依存資源の排他処理に利用される<br />プロセスRUNキュー<br />空きページ管理用リスト<br />スラブキャッシュ空きリスト<br />
  8. 8. 割り込み抑制系(2)<br />ソフト割り込みの禁止<br />irq_enter() & irq_exit() (P-66、P-121)<br />
  9. 9. semaphore<br />POSIXsemaphoreとして、システムコールで提供される<br />カーネル内部でも独自に利用される<br />待っている間、プロセスはsleepしている<br />比較的時間を要する処理の排他に向いている<br />プロセス間の同期に向いている<br />#include <sys/types.h><br />#include <sys/ipc.h><br />#include <sys/sem.h><br />
  10. 10. スレッド同期<br />システムコール(API)としては提供されない??<br />カーネル内部では随所で使われている<br />プロセスはsleepしない(busy wait)<br />色々ある<br />Spin lock<br />seqlock<br />RCU<br />
  11. 11. Spin lock<br />いわゆる悲観的ロック<br />CPUのアトミックな操作命令に依存<br />HTに配慮した実装<br />OoOEへの配慮が必要(メモリバリア)<br />ロック取得のたびに、キャッシュラインのフラッシュが発生する<br />
  12. 12. Spin lock 実装例(from Wikipedia)<br />lock: # ロック変数。1 = ロック済み, 0 = ロックされていない<br />dd 0<br />spin_lock:<br />moveax, 1 # EAX レジスタに 1 をセット<br />loop:<br />xchgeax, [lock] # アトミックにEAXレジスタとロック変数の値を交換<br /># ロックには常に 1 が格納され、以前の値が EAX レジスタに格納される。 <br />test eax, eax # EAX 自身をチェック。EAX がゼロならば プロセッサのゼロフラグがセットされる。<br /># EAX が 0 なら、ロックは解放状態から新たに確保されたとみなせる。<br /># そうでなければ、EAX は 1 であり、ロックを獲得できていない。<br />jnz loop # ゼロフラグがセットされていないときは XCHG 命令に戻る。<br /># これはロックが既に他に獲得されていた場合で、スピンする必要がある。<br />ret # ロックを獲得できたので、呼び出した関数へ戻る。<br />spin_unlock:<br />moveax, 0 # EAX レジスタに 0 をセット<br />xchgeax, [lock] # アトミックに EAX レジスタとロック変数を交換<br />ret # ロックを解放<br />出典: http://ja.wikipedia.org/wiki/スピンロック<br />
  13. 13. Spin lockのコスト<br />CPU#0<br />L2<br />L3<br />L1<br />CPU#2<br />L2<br />L1<br />CPU#1<br />L2<br />L1<br />CPU#3<br />L2<br />L1<br />Main memory<br />
  14. 14. seqlock<br />いわゆる楽観的ロック<br />参照時にキャッシュラインのフラッシュは生じない(->スケーラビリティ向上)<br />更新処理はspin lock等を用いて排他処理する<br />更新の手順<br />Spin lockを発動し<br />シーケンスカウンタに1を加え<br />更新処理を行い<br />シーケンスカウンタに再度1を加え<br />Spin lockを解除する<br />参照の手順<br />シーケンスカウンタ値を記録し(奇数の場合はretry)<br />参照処理を行い<br />シーケンスカウンタを再度確認する(最初と違う値の場合はretry)<br />
  15. 15. RCU<br />Read-Copy-Update<br />リソースにロック変数を準備しない手法(->参照時の変数チェックが必要ない)<br />更新の遅延処理が可能<br />コピーGCの発想に近い?<br />更新処理はspin lock等を用いて排他処理する<br />更新の手順:<br />Read&Copy 元データの構造体をコピーして新しいデータを作る<br />Update 元データへの参照(ポインタ)を新しいデータに向ける<br />元データを参照しているスレッドが無くなったと判断されたら(※)元データをGCする<br />ルール<br />「読み手はRCUクリティカルセクションでは絶対にコンテキストスイッチしてはいけない」<br />IP routing tableの更新等に利用<br />更新には(かなり)時間がかかる(全プロセスが一通り起床するまで?)<br />※各CPUがRCUクリティカルセクションを抜けたかどうかは、カーネル内のCPUビットマップにより管理されている。<br />スケジューラからRCUがコールバックされるので、各CPUがビットマップ上のRCU状態フラグを都度更新する。<br />
  16. 16. 以上<br />

×