Buddy Systemとの間に入り、メモリの確保/解放を効率化する。
Slabから取得するバッファはBuddy Systemから取得しており、
以下の特徴がある。
・仮想アドレスに対して物理ページが割り当て済み(アクセスしてPageFaultになることはない)
・物理的に連続ページ
struct kmem_cache_s cache_cache
+-------------+ next +-------------+
|"kmem_cache" |----------->|"fib6_nodes" |
| | | |
|slabs_full | | |
|slabs_partial|---+ | |
|slabs_free | | | |
+-------------+ | +-------------+
|
V slab_t
+-----+ next +-----+
| |----->| |----->
| | | |
+-----+ +-----+
| | objectのリスト(次のIndexを格納)
+-----+
:
+-----+
| | BUFCTL_END (リスト終端)
+-----+
|s_mem
V
+-----+-----+-----+--------+
| obj | | | ... |
| | | | |
+-----+-----+-----+--------+
slabs_full: 全objectが割り当て済みのSlabがチェーンされる。
slabs_partial: 割り当て済みと解放されているobjectが混在しているSlabがチェーンされる。
slabs_free: 全objectが解放されているSlabがチェーンされる。
上図はoff-slabの場合。
通常はobjectはsalb内にある。slab_t->s_memはslab内のobjectを指す。
[キャッシュ作成]
kmem_cache_create()
kmem_cache_alloc()でキャッシュを自分自身から取得する。
Slabが必要とするページ数(cachep->gfporder)
Slabあたりのobject数(cachep->num)を計算する。
:
objectサイズが大きい場合はCFLGS_OFF_SLABを立てる。
:
この時点ではまだ、Slab/Objectは作成しない。
alloc時にobject取得に失敗してkmem_cache_grow()で作成される。
[オブジェクト確保]
kmem_cache_alloc()
__kmem_cache_alloc()
指定キャッシュのslabs_partial/freeからobjectを割り当てる。
objectが無ければ
kmem_cache_grow()
:
object用にkmem_getpages()でBuddy Systemからページを取得する。
(仮想<->物理アドレスのマッピングは既に済んでいる。「物理メモリ管理.txt」参照)
:
kmem_cache_slabmgmt()
off-slabの場合はkmem_cache_alloc()でslabも取得
:
Slabとobjectを初期化
[汎用メモリ確保]
kmalloc()
size-32,64,128,..のslabからバッファを確保する。
[/proc/slabinfo]
slabinfo - version: 1.1
kmem_cache 61 68 112 2 2 1 <-- cache_cache
fib6_nodes 10 113 32 1 1 1
ip6_dst_cache 8 20 192 1 1 1
ndisc_cache 3 30 128 1 1 1
:
:
左から順番に。。。
キャッシュ名
割り当て済みのオブジェクト数
オブジェクト総数
オブジェクトサイズ
full/partial Slab数
Slab総数
Slab一つのページ数