EN JA
ZONE(9)
ZONE(9) FreeBSD Kernel Developer's Manual ZONE(9)

名称

uma_zcreate, uma_zalloc, uma_zalloc_arg, uma_zfree, uma_zfree_arg, uma_find_refcnt, uma_zdestroy, uma_zone_set_max, uma_zone_get_max, uma_zone_get_cur, uma_zone_set_warningゾーンアロケータ

書式

#include < sys/param.h>
#include < sys/queue.h>
#include < vm/uma.h>

uma_zone_t
uma_zcreate( char *name, int size, uma_ctor ctor, uma_dtor dtor, uma_init uminit, uma_fini fini, int align, uint16_t flags);

void *
uma_zalloc( uma_zone_t zone, int flags);

void *
uma_zalloc_arg( uma_zone_t zone, void *arg, int flags);

void
uma_zfree( uma_zone_t zone, void *item);

void
uma_zfree_arg( uma_zone_t zone, void *item, void *arg);

uint32_t *
uma_find_refcnt( uma_zone_t zone, void *item);

void
uma_zdestroy( uma_zone_t zone);

int
uma_zone_set_max( uma_zone_t zone, int nitems);

int
uma_zone_get_max( uma_zone_t zone);

int
uma_zone_get_cur( uma_zone_t zone);

void
uma_zone_set_warning( uma_zone_t zone, const char *warning);

解説

ゾーンアロケータ (zone allocator) は、同様のサイズの動的にサイズが決められる項目の収集を管理するための効率的なインタフェースを提供しています。ゾーンアロケータは、実行時に割り付けられたものと同様に、あらかじめ割り付けられたゾーンで動作することができ、そのため、他のメモリ管理ルーチンよりブート処理でより早期に利用可能です。

ゾーンは、同一のサイズの拡張可能な項目の収集です。ゾーンアロケータは、項目が使用中であるかそうでないかの経過を追い、ゾーンから項目を割り付けて、(それらを後で使用することを可能にする) それらを解放して元に戻すための関数を提供しています

項目の最初の割り付けの後に、それは、0 クリアされますが、その後の割り付けでは、最終の解放以後の内容のままです。

uma_zcreate() 関数は、次に項目が割り付けられる新しいゾーンを作成します。 name 引数は、デバッグとステータスのためのテキストのゾーン名です。このメモリは、ゾーンの割り付けが解放されるまでは、解放されるべきではありません。

ctordtor 引数は、それぞれ uma_zalloc() と uma_zfree() への呼び出しの時点で、uma サブシステムによって呼び出されるコールバック関数です。それらの目的は、リソースの割り付けまたは解放の時点で、行われる必要があるものを初期化するか、または破壊するためのフックを提供することです。 ctordtor コールバックのためのよい使用法は、割り付けられたオブジェクトの数のグローバルなカウントを調節することかもしれません。

uminitfini 引数は、ゾーンからのオブジェクトの割り付けを最適化するために使用されます。それらは、要求またはメモリ圧縮を満たすために、いくつかの項目を割り付けるか、または解放する必要があるときはいつでも、uma サブシステムによって呼び出されます。 uminitfini コールバックのためのよい使用法は、オブジェクト内に含まれるミューテックスを初期化し破壊することかもしれません。これによって、オブジェクトが uma サブシステムのオブジェクトのキャッシュから返されるとき、既に初期化されているミューテックスを再利用することができます。それらは、 uma_zalloc() と uma_zfree() への各呼び出しで呼び出されませんが、いくつかのオブジェクトに関してバッチモードで呼び出されます。

uma_zcreate() の flags 引数は、次のフラグの部分集合です:

UMA_ZONE_NOFREE
ゾーンのスラブ (slab) は、VM に決して返されません。
UMA_ZONE_REFCNT
ゾーンの各項目は、それに関連した内部の参照カウンタがあります。 uma_find_refcnt() を参照してください。
UMA_ZONE_NODUMP
ゾーンに属するページは、ミニダンプ (mini-dump) に含まれません。
UMA_ZONE_PCPU
ゾーンからの割り付けは、CPU にプライベートに割り当てられる、 mp_ncpu シャドウコピー (shadow copy) があります。 CPU は、基本的な割り付けアドレスに加えて現在の CPU ID の倍数と sizeof( struct pcpu): を使用してアドレスをプライベートにコピーすることができます:

foo_zone = uma_zcreate(..., UMA_ZONE_PCPU); 
 ... 
foo_base = uma_zalloc(foo_zone, ...); 
 ... 
critical_enter(); 
foo_pcpu = (foo_t *)zpcpu_get(foo_base); 
/* do something with foo_pcpu */ 
critical_exit();
UMA_ZONE_OFFPAGE
デフォルトで、スラブ内の項目の book-keeping は、スラブページ自体で行われます。このフラグは、book-keeping 構造体が特別の内部ゾーンとは別々に割り付けられるべきであることをサブシステムに明示的に伝えます。サブシステムが解放されている項目への book-keeping 構造体を見つけるメカニズムを要求するので、このフラグは、 UMA_ZONE_VTOSLAB または UMA_ZONE_HASH のいずれかを要求します。サブシステムは、暗黙に特定のゾーンのための offpage book-keeping の方を選ぶかもしれません。
UMA_ZONE_ZINIT
ゾーンは、新しく割り付けられたスラブをすべてゼロに初期化する内部メソッドを設定する uma_init メソッドがあります。 uma_ctor がある uma_init メソッドを間違えないでください。 UMA_ZONE_ZINIT フラグがあるゾーンは、すべての uma_zalloc() で、ゼロクリアされたメモリを返しません。
UMA_ZONE_HASH
ゾーンは、解放されている割り付けが属しているところで、スラブ book-keeping 構造体を見つけるために内部のハッシュテーブルを使用するべきです。
UMA_ZONE_VTOSLAB
ゾーンは、解放されている割り付けが属しているところで、スラブ book-keeping 構造体を見つけるために vm_page_t の特別のフィールドを使用するべきです。
UMA_ZONE_MALLOC
ゾーンは、 malloc(9) サブシステムのためのものです。
UMA_ZONE_VM
ゾーンは、VM サブシステムためのものです。

ゾーンからの項目を割り付けるためには、そのゾーンへのポインタで単に uma_zalloc() を呼び出し、 flags 引数を malloc(9) に文書化されるような選択されたフラグに設定します。成功するなら、項目へのポインタを返すか、またはゾーン中のすべての項目が使用中であり、アロケータがゾーンを拡張することができず、 M_NOWAIT が指定されるまれな場合に、 NULL を返します。

項目は、ゾーンへのポインタと項目へのポインタを付けて uma_zfree() を呼び出すことによって、それらが割り付けられた元のゾーンに解放されます。 itemNULL であるなら、 uma_zfree() は、何もしません。

変種 uma_zalloc_arg() と uma_zfree_arg() によって、それぞれ ctordtor 関数のための引数を指定できます。

ゾーンが UMA_ZONE_REFCNT フラグで作成されたなら、項目のための参照カウンタへのポインタを uma_find_refcnt() 関数の助けを借りて検索することができます。

ゾーンに割り付けられたすべてのメモリを解放して、 uma_zdestroy() を使用して、空である作成されたゾーンを破壊することができます。 uma_zalloc() でゾーンから割り付けられたすべての項目は、それ以前に uma_zfree() で解放されていなければなりません。

uma_zone_set_max() 関数は、項目の数 (と、したがって、メモリ) を制限し、 zone を割り付けることができます。 nitems 引数は、要求された上限の項目数を指定します。結局、ゾーンに割り付けられたすべてのメモリページが、容量に利用されることを保証するためにまとめられた実装のために要求されているものより高くなるように、有効な制限は、呼び出し側に返されます。制限は、割り付けられた項目、空きの項目、cpu ごとのキャッシュの空きの項目を含んで、ゾーンの項目の合計の数に適用されます。 2 つ以上の CPU があるシステムにおいて、残りのすべての解放されている項目が制限に達するとき、他の CPU のキャッシュにあるかもしれないので、メモリの不足がないときでさえ、指定された数の項目を割り付けることができないかもしれません。

uma_zone_get_max() 関数は、ゾーンための有効な上限の項目の数を返します。

uma_zone_get_cur() 関数は、ゾーンの概算の現在の占有を返します。正確な値を決定する適切な同期が実装によって実行されないので、返り値は、概算です。これは、計算に使用される潜在的に古いデータを犠牲にして低いオーバヘッドを確実にします。

uma_zone_set_warning() 関数は、与えられたゾーンが満杯となり、項目を割り付けることが失敗するとき、システムコンソールに印刷される警告を設定します。警告は、5 分ごとより頻繁でなく印刷されます。警告は、 vm.zone_warnings sysctl の調整変数を 0 に設定することによって全体的にオフに切り替えることができます。

戻り値

uma_zalloc() 関数は、項目へのポインタを返し、ゾーンが未使用の項目を使い果たし、 M_NOWAIT が指定されたなら、 NULL を返します。

関連項目

malloc(9)

歴史

ゾーンアロケータは、 FreeBSD 3.0 ではじめて登場しました。それは、スラブアロケータ (slab allocator) として機能するために、 FreeBSD 5.0 で根本的に変更されました。

作者

ゾーンアロケータは、 John S. Dyson によって書かれました。ゾーンアロケータは、スラブアロケータとして機能するために、 Jeff Roberson <jeff@FreeBSD.org>によって大部分を書き直されました。

このマニュアルページは、 Dag-Erling Smørgrav <des@FreeBSD.org>によって書かれました。 Jeroen Ruigrok van der Werven <asmodai@FreeBSD.org>によって UMA のために変更されました。

March 21, 2013 FreeBSD