Page fragments

もともと、Linux Kernelのソースコードの一部なので、GPLv2扱いになる（はずの認識）。

> https://www.kernel.org/doc/html/latest/index.html
> 
> Licensing documentation
> 
> The following describes the license of the Linux kernel source code (GPLv2), how to properly mark the license of individual files in the source tree, as well as links to the full license text.
> 
> https://www.kernel.org/doc/html/latest/process/license-rules.html#kernel-licensing

https://www.kernel.org/doc/html/latest/vm/page_frags.html

---

# Page fragments

> A page fragment is an arbitrary-length arbitrary-offset area of memory which resides within a 0 or higher order compound page. Multiple fragments within that page are individually refcounted, in the page’s reference counter.

page fragmentは、任意の長さの、任意のオフセットを持つ、メモリのメモリの領域であり、0以上の複合page内に存在します。複数のfragmentsは、ページのリファレンスカウンターで、個別に参照カウントされます。

> The page_frag functions, page_frag_alloc and page_frag_free, provide a simple allocation framework for page fragments. This is used by the network stack and network device drivers to provide a backing region of memory for use as either an sk_buff->head, or to be used in the “frags” portion of skb_shared_info.

page_frag_allocとpage_frag_freeの、page_flag関数は、page fragmentに対する単純な確保フレームワークを提供します。これは、network stackやnetwork device driversが、sk_buff->headに対するメモリのbacking region を提供するために使います。また、skb_shared_infoの"frags"位置の中でも使われます。

> In order to make use of the page fragment APIs a backing page fragment cache is needed. This provides a central point for the fragment allocation and tracks allows multiple calls to make use of a cached page. The advantage to doing this is that multiple calls to get_page can be avoided which can be expensive at allocation time. However due to the nature of this caching it is required that any calls to the cache be protected by either a per-cpu limitation, or a per-cpu limitation and forcing interrupts to be disabled when executing the fragment allocation.

page fragment APIを使うためには、backing page fragment cacheが必要です；。これは、fragment allocationに対する中心位置を提供し、キャッシュされたページを複数回の呼び出しで利用できるようになります。この利点は、get_pageに対する複数回の呼び出しを回避できることです。れは、確保するための時間が非常にコストが高いです。しかし、このキャッシュの特性上、キャッシュへの呼び出しは、CPUごとの制限によるキャッシュの保護、あるいは、CPU毎の制限と、フラグメント割り当て実行時に、割り込みを強制的に無効化する必要があります。

> The network stack uses two separate caches per CPU to handle fragment allocation. The netdev_alloc_cache is used by callers making use of the __netdev_alloc_frag and __netdev_alloc_skb calls. The napi_alloc_cache is used by callers of the __napi_alloc_frag and __napi_alloc_skb calls. The main difference between these two calls is the context in which they may be called. The “netdev” prefixed functions are usable in any context as these functions will disable interrupts, while the “napi” prefixed functions are only usable within the softirq context.

network stackは、fragment allocationを制御するために、CPU毎に２つの異なるcacheを利用します。netdrv_alloc_cacheは、呼び出し元が __netdev_alloc_fragや__net_dev_alloc_skgを呼び出す呼び出し元によって利用されます。napi_alloc_cacheは、呼び出し元が__napi_alloc_fragと__napi_alloc_skb呼び出しするときに、呼び出し元が利用します。この２つの呼び出しの主な違いは、呼び出されるコンテクストです。"netdev" prefixの関数は、割り込みを無効化するため、どのようなコンテクストでも利用できます。一方、[napi」prefixの関数は、softirq コンテクスト内でのみ利用できます。

> Many network device drivers use a similar methodology for allocating page fragments, but the page fragments are cached at the ring or descriptor level. In order to enable these cases it is necessary to provide a generic way of tearing down a page cache. For this reason __page_frag_cache_drain was implemented. It allows for freeing multiple references from a single page via a single call. The advantage to doing this is that it allows for cleaning up the multiple references that were added to a page in order to avoid calling get_page per allocation.


多くのネットワークデバイスドライバーは、ページフラグメントの割り当てに同様の方法を使用します。ただし、page flagmentとは link または descriptor levelでキャッシュされまsう。これらのケースを有効にするには、ページキャッシュを破棄する一般的な手段を提供しなければなりません。

このため、__pagE_frag_cache_drainが導入されました。これは、一度の呼び出しで単独のpageから複数の参照を開放することができます。これを行うメリットは、割り当て事にget_pageを呼び出さないようにするため、ページに追加された複数の参照をクリーンアップできます。

Alexander Duyck, Nov 29, 2016.