MBPOOL(9) | FreeBSD Kernel Developer's Manual | MBPOOL(9) |
名称
mbpool — ネットワークインタフェースのためのバッファプール書式
#include < sys/types.h>#include < machine/bus.h>
#include < sys/mbpool.h>
struct mbpool;
int
mbp_create( struct mbpool **mbp, const char *name, bus_dma_tag_t dmat, u_int max_pages, size_t page_size, size_t chunk_size);
void
mbp_destroy( struct mbpool *mbp);
void *
mbp_alloc( struct mbpool *mbp, bus_addr_t *pa, uint32_t *hp);
void
mbp_free( struct mbpool *mbp, void *p);
void
mbp_ext_free( void *, void *);
void
mbp_card_free( struct mbpool *mbp);
void
mbp_count( struct mbpool *mbp, u_int *used, u_int *card, u_int *free);
void *
mbp_get( struct mbpool *mbp, uint32_t h);
void *
mbp_get_keep( struct mbpool *mbp, uint32_t h);
void
mbp_sync( struct mbpool *mbp, uint32_t h, bus_addr_t off, bus_size_t len, u_int op);
MODULE_DEPEND( your_module, libmbpool, 1, 1, 1);
options LIBMBPOOL
解説
mbuf プールは、受信バッファの大量を必要とするインタフェースカードのためのドライバを助けることを目的として、さらに、これらのバッファと 32 ビットのハンドルの間のマッピングを提供します。これらのカードに関する例は Fore/Marconi ForeRunnerHE カードです。これらは、それぞれ 2 つのバッファプールで、それぞれ最大 8192 を含むことができる、最大 8 つの受信グループを採用しています。これは 100000 以上のバッファの総最大数を与えます。より適度の設定があっても、カードは数 1,000 のバッファを消費します。これらのバッファのそれぞれは、DMA のためにマップされなければなりません。 IOMMU のないマシンと 4GByte より少ないメモリのためとはいえ、これは問題ではありません、他のマシンに関して、これは、直ちにすべての利用可能な IOMMU アドレス空間と/または、バウンスバッファを消費します。 sparc64 では、デフォルトの I/O ページサイズが 16k であるので、簡単な mbuf のマッピングはアドレス空間の 31/32 が浪費されます。
これらのカードの別の問題の大部分は、物理アドレスと共にバッファ記述子に 32 ビットのハンドルを入れることをサポートすることです。このハンドルは、バッファが満たされるとき、ドライバに反映され、ホストメモリでバッファを見つけるドライバを助けます。 32 ビットのマシンのために、バッファの仮想アドレスは、通常、ハンドルとして使用されます。これは、明白な理由で 64 ビットのマシンのために動作していないので、マッピングがこれらのハンドルとバッファの間に必要です。リストや同様のものを検索しないて、このマッピングは可能であるべきです。
mbuf プールは、プールごとの設定可能なページサイズで賢明な DMA 可能なメモリページを割り付けることによって、両方の問題を克服します。各ページは多くの等しいサイズのチャンク (塊) に分割されます。チャンクの中の最後の MBPOOL_TRAILER_SIZE は、プールコード (4 バイト) によって使用されます。それぞれのチャンクの残りはバッファとして使用可能です。割り付けられたページには、プールごとの制限があります。
さらに、コードは各バッファのための 2 つのフラグを管理します: “on-card”と“used”です。バッファは次の 3 つの状態の 1 つです:
- free
- フラグは設定されていません。
- on-card
- 両方のフラグは設定されています。バッファは、カードに引き渡されていると仮定され、満たされるのを待ちます。
- used
- バッファは、カードによって返され、現在、システムを通して伝わります。
プールは mbp_create() で作成されます。この呼び出しは、 bus_dmamem_alloc(9) を通してメモリページを作成して、マップするために使用される DMA タグ dmat を指定します。 chunk_size はプールオーバヘッドを含んでいます。それは、5 つの ATM セル (240 バイト) のためのバッファを得るために、256 のチャンクサイズが指定されるべきであることを意味します。これはバッファと、4 バイトのプールオーバヘッドの間の未使用の 12 バイトをもたらします。プール中のバッファの総最大数は max_pages * ( page_size / chunk_size) です。 max_pages のための最大値は 2^14-1 (16383) です、 page_size / chunk_size の最大は 2^9 (512) です。呼び出しが成功したなら、新たに割り付けられた struct mbpool へのポインタは mpb によって指された変数に設定されます。
プールは mbp_destroy() で破壊されます。これはすべてのページとプール構造体自体を解放します。 DIAGNOSTICS を付けてコンパイルされるなら、コードは、すべてのバッファが解放されていることをチェックします。そうでなければ、警告メッセージがコンソールに出力されます。
バッファは mbp_alloc() で割り付けられます。これは、バッファの仮想アドレスを返し、物理アドレスを pa によって指された変数に格納します。ハンドルは hp によって指された変数に収納されます。ハンドルの 2 つの最上位ビットと 7 つの最下位ビットは、プールコードによって未使用であり、呼び出し側によって使用されるかもしれません。これらは、ハンドルを他の関数の 1 つに渡すとき、自動的に取り外されます。 (ページの最大数に達している、利用可能なメモリがないか、またはメモリがマップすることができないために) バッファを割り付けることができないなら NULL が返されます。バッファを割り付けることができるなら、それは“on-card”の状態になります。
バッファがカードによって返されるとき、ドライバは、ハンドルで mbp_get() を呼び出します。この関数は、バッファの仮想アドレスを返して、“on-card”ビットをクリアします。バッファは現在“used”状態になっています。関数 mbp_get_keep() は、“on-card”ビットをクリアしないという点において mbp_get() とは異なっています。これは、カードによって“部分的”に返されるバッファのために使用することができます。
バッファは、バッファの仮想アドレスで mbp_free() を呼び出すことによって解放されます。これは、“used”ビットをクリアして、プールのフリー (空き) リストにバッファを置きます。フリーバッファはシステムに返され「ない」ことに注意してください。関数 mbp_ext_free() は、解放関数として m_extadd() に与えることができます。 user 引数はプールへのポインタでなければなりません。
カードによって返されたバッファの内容を使用する前に、ドライバは、適切なパラメータで mbp_sync() をよびださなければなりません。これはバッファのための bus_dmamap_sync(9) への呼び出しをもたらします。
現在“on-card”状態になっているプール中のすべてのバッファは mbp_card_free() への呼び出しで解放することができます。これは、インタフェースを停止するとき、ドライバによって呼び出されるかもしれません。“used”状態のバッファはこの呼び出しによって解放されません。
デバッグのために、 mbp_count() を呼び出すこてゃ可能です。これは“used”と“on-card”状態のバッファの数とフリーリストのバッファの数を返します。
関連項目
mbuf(9)作者
<harti@FreeBSD.org>警告
bus_dmamap_sync(9) は、オフセットと長さのパラメータが失われているので、関数 mbp_sync() は、現在 no-op (操作不能) です。July 15, 2003 | FreeBSD |