2.5.7 ハードウェアキャッシュとTLBの制御
◆ハードウェアキャッシュの制御
L1_CACHE_BYTES
キャッシュのヒット率最適化
= 構造体でもっとも頻繁に使用するメンバは、低いオフセットに集めて、同じラインにキャッシュ = 多数のデータ割り当ては全キャッシュラインを均等に使用する。 = プロセスの切り替えでは、切り替え前のプロセスと同じページテーブルの組を使用しているプロセスを 少し優先させる。[schedule()]
[質問]
Q1. 上記の実装はどうなっているのか?
◆TLBの制御
TLBエントリのフラッシュ=プロセス切り替え時にはプロセスが使用するページテーブルの組を切り替えるので、ページテーブルエントリに依存するTLBエントリもフラッシュする。
しかし以下の場合にはTLBエントリのフラッシュは省略される。
= カーネルスレッドとの切り替え = 同じページテーブルの組を使用している場合=>同じプロセスに所属するスレッド間での切り替え
◆TLBエントリの無効化に使われる関数とマクロ
include/asm/pgtable.h:# define __flush_tlb_one(addr)
# define __flush_tlb_one(addr) __flush_tlb_single(addr) #else # define __flush_tlb_one(addr) \ do { \ if (cpu_has_pge) \ __flush_tlb_single(addr); \ else \ __flush_tlb(); \ } while (0) #endif
flush_tlb
#define __flush_tlb() \ do { \ unsigned int tmpreg; \ \ __asm__ __volatile__( \ "movl %%cr3, %0; # flush TLB \n" \ "movl %0, %%cr3; \n" \ : "=r" (tmpreg) \ :: "memory"); \ } while (0)
flush_tlb_page
local_flush_tlb
__flush_tlb
flush_tlb_mm
flush_tlb_range
__flush_tlb_all
flush_tlb_all
◆無駄なTLBフラッシュを防止する技術=遅延TLBの概念と実装
TLBのフラッシュはコストがかかるために、なるべく遅延させる。
ではどんな場合に遅延させることができるのか ->
複数CPUが同じページテーブルを使用していて、TLBをフラッシュする必要がある。 このときカーネルスレッドを実行しているCPUのTLBフラッシュを延期させる。
なぜ遅延TLBが利用できるのか
カーネルスレッドではTLBエントリを参照していないため。
遅延TLBのプロセス
・カーネルスレッドの実行 ・遅延TLBモードに設定 ・遅延TLBモードが有効になっている間にはTLBフラッシュのリクエストがあっても実行しない、しかし TLB無効フラグをたてておく。 ・CPUが別のプロセスに切り替えられる。 ・TLB無効フラグがたっている場合には、TLBをフラッシュして非遅延TLBモードに移行する。
遅延TLBの実装
cpu_tlbstate->active_mm カレントプロセスのメモリディスクリプタ cpu_tlbstate->state TLBSTATE_OK or TLBSTATE_LAZY
128 struct tlb_state
129 {
130 struct mm_struct *active_mm;
131 int state;
132 char __cacheline_padding[L1_CACHE_BYTES-8];
133 };
各メモリディスクリプタ ->cpu_vm_mask プロセッサ間割り込みを受け付けるCPUのインデックス