英語

頁面片段

頁面片段是駐留在0或更高階複合頁面內的任意長度、任意偏移量的記憶體區域。 該頁面內的多個片段在頁面的引用計數器中被單獨引用計數。

page_frag 函式,page_frag_alloc 和 page_frag_free,為頁面片段提供了一個簡單的分配框架。 網路堆疊和網路裝置驅動程式使用它來提供一個後備記憶體區域,用作 sk_buff->head,或者用於 skb_shared_info 的“frags”部分。

為了使用頁面片段 API,需要一個後備頁面片段快取。 這為片段分配提供了一箇中心點,並跟蹤允許多次呼叫以使用快取的頁面。 這樣做的好處是可以避免多次呼叫 get_page,這在分配時可能會很昂貴。 然而,由於這種快取的性質,需要透過每個 CPU 的限制或每個 CPU 的限制來保護對快取的任何呼叫,並在執行片段分配時強制停用中斷。

網路堆疊為每個 CPU 使用兩個單獨的快取來處理片段分配。 netdev_alloc_cache 由使用 netdev_alloc_frag 和 __netdev_alloc_skb 呼叫的呼叫者使用。 napi_alloc_cache 由 __napi_alloc_frag 和 napi_alloc_skb 呼叫的呼叫者使用。 這兩個呼叫之間的主要區別在於可以呼叫它們的上下文。“netdev”字首的函式可以在任何上下文中使用,因為這些函式將停用中斷,而“napi”字首的函式只能在軟中斷上下文中使用。

許多網路裝置驅動程式使用類似的方法來分配頁面片段,但頁面片段快取在環或描述符級別。 為了啟用這些情況,有必要提供一種通用的方式來拆除頁面快取。 因此,實現了 __page_frag_cache_drain。 它允許透過一次呼叫釋放來自單個頁面的多個引用。 這樣做的好處是可以清理新增到頁面中的多個引用,以避免每次分配都呼叫 get_page。

Alexander Duyck, 2016 年 11 月 29 日。