EN JA
MBPOOL(9)
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 Brandt <harti@FreeBSD.org>

警告

bus_dmamap_sync(9) は、オフセットと長さのパラメータが失われているので、関数 mbp_sync() は、現在 no-op (操作不能) です。
July 15, 2003 FreeBSD