日本語 man コマンド類 (ja-man-1.1j_5) と日本語 man ドキュメント (ja-man-doc-5.4 (5.4-RELEASE 用) など) をインストールすると、以下のような man コマンド閲覧、キーワード検索が コンソールからできるようになります。
4.11-RELEASE-K, 5.4-RELEASE-K, 5.5-RELEASE-K, 6.0-RELEASE-K から 6.4-RELEASE-K, 7.0-RELEASE-K から 7.4-RELEASE-K, 8.0-RELEASE-K から 8.4-RELEASE-K, 9.0-RELEASE-K から 9.3-RELEASE-K, 10.0-RELEASE-K から 10.3-RELEASE-K, 11.0-RELEASE-K から 11.4-RELEASE-K, 12.0-RELEASE-K, 12.1-RELEASE-K は、 プライベート版 (小金丸が編集してまとめたもの) ですが、 より多くの翻訳したファイルが含まれています。 (5.4-RELEASE-K から 6.4-RELEASE-K, 7.0-RELEASE-K から 7.4-RELEASE-K, 8.0-RELEASE-K から 8.4-RELEASE-K, 9.0-RELEASE-K から 9.3-RELEASE-K, 10.0-RELEASE-K から 10.3-RELEASE-K, 11.0-RELEASE-K から 11.4-RELEASE-K, 12.0-RELEASE-K から 12.3-RELEASE-K, 13.0-RELEASE-K から 13.2-RELEASE-K は、全翻訳済み)
13.3-STABLE-K, 15.0-CURRENT-K は現在、作成中で日々更新されています。
Table of Contents
UMA(9) FreeBSD カーネル開発者マニュアル UMA(9) 名称 UMA -- 汎用のカーネルオブジェクトのアロケータ 書式 #include <sys/param.h> #include <sys/queue.h> #include <vm/uma.h> options UMA_FIRSTTOUCH options UMA_XDOMAIN typedef int (*uma_ctor)(void *mem, int size, void *arg, int flags); typedef void (*uma_dtor)(void *mem, int size, void *arg); typedef int (*uma_init)(void *mem, int size, int flags); typedef void (*uma_fini)(void *mem, int size); typedef int (*uma_import)(void *arg, void **store, int count, int domain, int flags); typedef void (*uma_release)(void *arg, void **store, int count); typedef void *(*uma_alloc)(uma_zone_t zone, vm_size_t size, int domain, uint8_t *pflag, int wait); typedef void (*uma_free)(void *item, vm_size_t size, uint8_t pflag); uma_zone_t uma_zcreate(char *name, int size, uma_ctor ctor, uma_dtor dtor, uma_init zinit, uma_fini zfini, int align, uint16_t flags); uma_zone_t uma_zcache_create(char *name, int size, uma_ctor ctor, uma_dtor dtor, uma_init zinit, uma_fini zfini, uma_import zimport, uma_release zrelease, void *arg, int flags); uma_zone_t uma_zsecond_create(char *name, uma_ctor ctor, uma_dtor dtor, uma_init zinit, uma_fini zfini, uma_zone_t master); void uma_zdestroy(uma_zone_t zone); void * uma_zalloc(uma_zone_t zone, int flags); void * uma_zalloc_arg(uma_zone_t zone, void *arg, int flags); void * uma_zalloc_domain(uma_zone_t zone, void *arg, int domain, int flags); void * uma_zalloc_pcpu(uma_zone_t zone, int flags); void * uma_zalloc_pcpu_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); void uma_zfree_domain(uma_zone_t zone, void *item, void *arg); void uma_zfree_pcpu(uma_zone_t zone, void *item); void uma_zfree_pcpu_arg(uma_zone_t zone, void *item, void *arg); void uma_prealloc(uma_zone_t zone, int nitems); void uma_zone_reserve(uma_zone_t zone, int nitems); void uma_zone_reserve_kva(uma_zone_t zone, int nitems); void uma_zone_set_allocf(uma_zone_t zone, uma_alloc allocf); void uma_zone_set_freef(uma_zone_t zone, uma_free freef); int uma_zone_set_max(uma_zone_t zone, int nitems); int uma_zone_set_maxcache(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); void uma_zone_set_maxaction(uma_zone_t zone, void (*maxaction)(uma_zone_t)); void uma_reclaim(); #include <sys/sysctl.h> SYSCTL_UMA_MAX(parent, nbr, name, access, zone, descr); SYSCTL_ADD_UMA_MAX(ctx, parent, nbr, name, access, zone, descr); SYSCTL_UMA_CUR(parent, nbr, name, access, zone, descr); SYSCTL_ADD_UMA_CUR(ctx, parent, nbr, name, access, zone, descr); 解説 UMA (Universal Memory Allocator; 全体のメモリアロケータ) は、ゾーンとして 参照される、同一のサイズの項目の動的なサイズの収集を管理するための効率的 なインタフェースを提供しています。ゾーンは、項目が使用されている経過を追 い、項目が使用されていない経過を追い、UMA は、ゾーンから項目を割り付ける ため、それらをもとに解放するための関数を提供し、それらを、その後の割り付 け要求のために利用可能にします。ゾーンは、NUMA システムのためのラウンドロ ビンと最初のタッチのポリシと同様に SMP システムでリニアのスケーラビリティ で CPU ごとのキャッシュを維持します。CPU ごとのキャッシュされた項目の数 は、境界があり、各ゾーンは、さらに CPU ごとのキャッシュの割り付けミズを迅 速に満足するために使用される項目の境界のないキャッシュを維持します。 2 つのタイプのゾーンが存在します: 通常のゾーンとキャッシュゾーン。通常の ゾーンで、項目は、カーネルのページアロケータから割り付けられた 1 つ以上の 事実上連続しているメモリページである、slab から割り付けられます。内部的 に、slab は、slab を割り付けるために、1 つ以上のゾーンによってそれらの使 用法の経過を追うために責任がある、UMA keg によって管理されます。通常の使 用法で、ゾーンごとに 1 つの keg があるので、slab は、複数のゾーンで共用さ れません。 通常のゾーンは、keg からの項目をインポートし、要求されるなら、その keg へ の項目を解放します。キャッシュゾーンは、keg がなく、代わりに、カスタムの インポートを使用し、方法を解放します。例えば、カーネルオブジェクトのいく つかの収集は、ブート時に静的に割り付けられ、収集ののサイズは、変更されま せん。そのような収集のオブジェクトのための効率的なアロケータを実装するた めにキャッシュゾーンを使用することができます。 uma_zcreate() と uma_zcache_create() 関数は、それぞれ、新しい通常のゾーン とキャッシュゾーンを作成します。uma_zsecond_create() 関数は、master 引数 によって指定されたゾーンの keg を共有する通常ゾーンを作成します。name 引 数は、デバッグとステータスのためのテキストのゾーン名です。このメモリは、 ゾーンの割り付けが解放されるまでは、解放されるべきではありません。 ctor と dtor 引数は、それぞれ uma_zalloc() と uma_zfree() への呼び出しの 時点で、UMA サブシステムによって呼び出されるコールバック関数です。それら の目的は、リソースの割り付けまたは解放の時点で、行われる必要があるものを 初期化するか、または破壊するためのフックを提供することです。ctor と dtor コールバックのための良い使用法は、queue(3) ヘッドのような項目に組み込まれ たデータ構造を初期化することかもしれません。 zinit と zfini 引数は、ゾーンから項目の割り付けを最適化するために使用され ます。それらは、要求またはメモリの圧縮を満たすために項目を割り付けるか、 または解放する必要があるときはいつでも、UMA サブシステムに呼び出されま す。zinit と zfini コールバックのための良い使用法は、項目内に含まれている mutex を初期化し、破壊することかもしれません。これによって、項目が解放さ れて、再割り付けされるたびに、mutex を破壊し、再初期化することを避けるこ とができます。それらは、uma_zalloc() と uma_zfree() への各呼び出しで呼び 出しませんが、通常、メモリ圧縮への応答として、むしろ、項目がゾーンの キャッシュにインポートされるとき、とゾーンが slab アロケータに項目を解放 するときです。 uma_zcache_create(), のために、zimport と zrelease 関数は、それぞれ、ゾー ンに項目をインポートするために、ゾーンから項目を解放するために呼び出され ます。zimport 関数は、count エントリの最大を含んでいる、store 配列の項目 へのポインタを格納するべきです。関数は、最大より小さいかもしれない、イン ポートされた項目の数を返さなければなりません。同様に、zrelease 関数への store パラメータは、項目への count ポインタの配列を含んでいます。 uma_zcache_create() に渡された arg パラメータは、インポートと解放関数に提 供されます。zimport への domain パラメータは、割り付けのために要求された numa(4) ドメインを指定します。それは、NUMA ドメイン数か、または特別な値 UMA_ANYDOMAIN です。 uma_zcreate() と uma_zcache_create() の flags 引数は、次のフラグの部分集 合です: UMA_ZONE_NOFREE ゾーンの keg に割り付けられたスラブ (slab) は、VM に決して返されませ ん。 UMA_ZONE_NODUMP ゾーンに属するページは、ミニダンプ (minidump) に含まれません。 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); /* foo_pcpu で何かを行なう */ critical_exit(); PCPU ゾーンから項目を割り付けるとき、M_ZERO を使用することができるこ とに注意してください。PCPU ゾーンから 0 クリアされたメモリを取得する ために、代わりに、uma_zalloc_pcpu() 関数とその変異型を使用し、M_ZERO を渡します。 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_ZONE_NUMA ゾーンは、デフォルトのラウンドロビンではなく、first-touch NUMA ポリ シを使用するべきです。UMA_FIRSTTOUCH カーネルオプションが設定される なら、すべてのゾーンは、最初のタッチポリシを暗黙に使用し、 UMA_ZONE_NUMA フラグは、効果がありません。設定されるとき、 UMA_XDOMAIN カーネルオプションによって、UMA は、常に最初のタッチゾー ンからの割り付けが、常にローカルであることを保証するために、特別なト ラックを行ないます。そうでなければ、それが割り付けられたのと同じドメ インのメモリを解放しない消費者は、CPU キャッシュごとに混ぜられま す。、詳細については、numa(4) を参照してください。 ゾーンでキャッシュされるすべてのメモリを解放する uma_zdestroy() を使用し て、ゾーンを破壊することができます。ゾーンから割り付けられたすべての項目 は、ゾーンが安全に破壊される前に、ゾーンに解放されなければなりません。 ゾーンからの項目を割り付けるためには、そのゾーンへのポインタで単に uma_zalloc() を呼び出し、flags 引数を malloc(9) に文書化されるような選択 されたフラグに設定します。成功するなら、項目へのポインタを返すか、または ゾーン中のすべての項目が使用中であり、アロケータがゾーンを拡張することが できず、M_NOWAIT が指定されるまれな場合に、NULL を返します。 項目は、ゾーンへのポインタと項目へのポインタを付けて uma_zfree() を呼び出 すことによって、それらが割り付けられた元のゾーンに解放されます。item が NULL であるなら、uma_zfree() は、何もしません。 変異型 uma_zalloc_arg() と uma_zfree_arg() によって、呼び出し側は、それぞ れ、ゾーンの ctor と dtor 関数のための引数を指定できます。 uma_zalloc_domain() 関数によって、呼び出し側は、割り付けるために、固定さ れた numa(4) ドメインを指定することができます。これは、保証を使用します が、同時処理を減少するアロケータの遅いパスを使用します。 uma_zfree_domain() 関数は、この方法で割り付けられたメモリを返すために使用 されるべきです。この関数は、ポインタからドメインを推測し、引数としてそれ を必要としません。 uma_prealloc() 関数は、項目の要求された数のための slab を割り付け、通常、 ゾーンの初期の作成に従います。ゾーンからのその後の割り付けは、あらかじめ 割り付けられた slab を使用して満たされます。slab 割り付けは、M_WAITOK フ ラグで実行されるので、uma_prealloc() は、スリープすることに注意してくださ い。 uma_zone_reserve() 関数は、ゾーンのための予約された項目の数を設定します。 uma_zalloc() と変異型は、ゾーンが、少なくとも解放された項目の予約された数 を含んでいることを保証します。予約された項目は、割り付け要求フラグの M_USE_RESERVE を指定することによって割り付けられます。uma_zone_reserve() は、それ自体によって、あらゆる事前の割り付けを実行しません。 uma_zone_reserve_kva() 関数は、項目の要求された数のためのカーネル仮想アド レス空間を事前に割り付けます。ゾーンからのその後の割り付けは、あらかじめ 割り付けられたアドレス空間を使用して満たされます。uma_zone_reserve() と 違って、uma_zone_reserve_kva() は、M_USE_RESERVE 要求への事前の割り付けの 使用を制限しないことに注意してください。 uma_zone_set_allocf() と uma_zone_set_freef() 関数によって、ゾーンのデ フォルトの slab 割り付けと解放関数を上書きすることができます。これは、 ゾーンの項目が特別なメモリ割り付けの制約があるなら、役に立ちます。例え ば、マルチページオブジェクトが物理的に連続するように要求されるなら、カー ネルのページアロケータから連続するメモリ要求する allocf 関数が使用されま す。 uma_zone_set_max() 関数は、項目の数 (と、したがって、メモリ) を制限し、 zone を割り付けることができます。nitems 引数は、要求された上限の項目数を 指定します。結局、ゾーンに割り付けられたすべてのメモリページが、容量に利 用されることを保証するためにまとめられた実装のために要求されているものよ り高くなるように、有効な制限は、呼び出し側に返されます。制限は、割り付け られた項目、空きの項目、cpu ごとのキャッシュの空きの項目を含んで、ゾーン の項目の合計の数に適用されます。2 つ以上の CPU があるシステムにおいて、残 りのすべての解放されている項目が制限に達するとき、他の CPU のキャッシュに あるかもしれないので、メモリの不足がないときでさえ、指定された数の項目を 割り付けることができないかもしれません。 uma_zone_set_maxcache() 関数は、サイズの境界のある CPU キャッシュを除い て、ゾーンでキャッシュされる解放される項目の数を制限します。例えば、 `pure' (純粋な) CPU キャッシュごとに実装するために、キャッシュゾーンは、0 の最大のキャッシュサイズで設定されます。 uma_zone_get_max() 関数は、ゾーンための有効な上限の項目の数を返します。 uma_zone_get_cur() 関数は、ゾーンから現在割り付けられた項目の数の近似値を 返します。正確な値を決定する適切な同期が実装によって実行されないので、返 り値は、概算です。これは、計算に使用される潜在的に古いデータを犠牲にして 低いオーバヘッドを確実にします。 uma_zone_set_warning() 関数は、与えられたゾーンが満杯となり、項目を割り付 けることが失敗するとき、システムコンソールに印刷される警告を設定します。 警告は、5 分ごとに頻繁でなく印刷 (表示) されます。警告は、 vm.zone_warnings sysctl の調整変数を 0 に設定することによって全体的にオフ に切り替えることができます。 uma_zone_set_maxaction() 関数は、与えられたゾーンが満杯となり、項目を割り 付けることに失敗するとき、呼び出される関数を設定します。関数は、ロックさ れたゾーンを付けて呼び出されます。また、割り付けられた関数を呼び出す関数 は、追加のロックを保持します。したがって、この関数は、(シグナルのハンドラ と同様に) ほんの少しの作業を行うべきです。 SYSCTL_UMA_MAX(parent, nbr, name, access, zone, descr) マクロは、ゾーンの ための項目の効率的な上限の数をエクスポートする静的な sysctl(9) oid を宣言 します。zone 引数は、uma_zone_t へのポインタであるべきです。oid の読み込 みは、uma_zone_get_max() を通して取得された値を返します。oid への書き込み は、uma_zone_set_max() を通して新しい値を設定します。 SYSCTL_ADD_UMA_MAX(ctx, parent, nbr, name, access, zone, descr) マクロ は、このタイプの oid を動的に作成するために提供されています。 SYSCTL_UMA_CUR(parent, nbr, name, access, zone, descr) マクロは、ゾーンの 近似の現在の占有をエクスポートする静的な読み込み専用の sysctl(9) oid を宣 言します。zone 引数は、uma_zone_t へのポインタであるべきです。oid の読み 込みは、uma_zone_get_cur() によって取得された値を返します。 SYSCTL_ADD_UMA_CUR(ctx, parent, nbr, name, zone, descr) マクロは、このタ イプの oid を動的に作成するために提供されています。 実装に関する注 これらの割り付けがリターンを呼び出すメモリが、実行形式ではありません。 uma_zalloc() 関数は、実行形式のメモリを割り付けるために、M_EXEC フラグを サポートしません。すべてのプラットフォームが、実行形式と実行形式でないメ モリの区別を強制するわけではありません。 関連項目 numa(4), vmstat(8), malloc(9) Jeff Bonwick, The Slab Allocator: An Object-Caching Kernel Memory Allocator, 1994. 歴史 ゾーンアロケータは、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 のために変更されました。 FreeBSD 12.2 August 20, 2020 FreeBSD 12.2