Linux zswap構架分析
-v0.1 2019.12.16 Sherlock init
簡介:本文簡單分析zswap的軟件構架,爲在zswap框架中添加crypto acomp的支持做準備。
關於zswap的基本介紹和使用可以參考:
https://blog.csdn.net/scarecrow_byr/article/details/103463101.
本文的分析基於Linux主線5.5-rc1.
- 基本模型
-
zswap初始化流程
-
爲系統裏的每一個cpu core分配per cpu dst內存。
-
爲每個cpu core分配內核壓縮解壓縮的上下文。
-
創建zpool, 並根據用戶態模塊參數選擇zpool後端使用的內存分配器。創建
zpool的時候需要給zpool註冊一個evict的回調函數,這個函數用於在zpool的
後端內存分配器沒有內存的時候, 把zpool裏的壓縮內存向swap設備寫入。可以
看到現在的evict在向swap設備寫數據的時候還要先把壓縮的數據解壓縮,如果寫
入swap設備的數據將來被使用,重新加載回內存的代碼路徑是標準的缺頁流程,
和zswap沒有關係。這個步驟整體上把創建出來的各種基礎數據結構封裝在一個
struct zswap_pool的結構中, 上面步驟裏的per cpu壓縮解壓縮上下文也放在了
zswap_pool。 -
註冊frontswap的回調函數。根據內核Documentation/vm/frontswap.rst,store
用於把swap頁存入zpool, load用於從zpool重新加載swap的頁,invalidate_*
用於把zpool裏存放的壓縮頁面釋放。
-
-
核心數據結構
struct zswap_pool
swap page ---> frontswap
.store
.load
.invalidate_page
.invalidate_area
.init
zswap初始化的時候註冊frontswap的一個實例,frontswap的各個回調中使用zpool接口
存儲壓縮的內存,zpool接口的後端可以是不同的專用於存儲壓縮內存的內存分配器。
-
對用戶態的接口
-
zswap用多個模塊參數用來配置zswap的參數: zpool的後端內存分配器是可以選的
(默認是zbud); 壓縮解壓算法(默認是LZO),測試硬件offload的時候,這裏要選
則相應的算法; zpool佔內存的大小; 對相同頁的優化處理。這些參數在/sys/module/zswap/parameters/下也可以配置。
-
在/sys/kernel/debug/zswap/下有zswap的相關統計項。
-
-
對內核crypto comp的接口
- 當前代碼使用的是內核crypto comp壓縮解壓縮接口,沒有使用crypto acomp接口。
- 實現細節
不清楚這裏的邏輯,爲什麼要一個zswap pool的鏈表。
__zswap_pool_create_fallback(void)
+-> zswap_pool_create(char *type, char *compressor)
+-> cpuhp_state_add_instance(CPUHP_MM_ZSWP_POOL_PREPARE, &pool->node)
list_add(&pool->list, &zswap_pools);
這裏選一個zswap_frontswap_store的實現分析:
zswap_frontswap_store
+-> entry = zswap_entry_cache_alloc(GFP_KERNEL)
分配一個zswap_entry, 用來描述要壓縮存儲的一個頁。
+-> crypto_comp_compress
調用crypto comp API做壓縮。
+-> zpool_malloc(entry->pool->zpool, hlen + dlen, gfp, &handle)
從zpool裏分配一段內存, 用來存壓縮的頁。
+-> zpool_map_handle(entry->pool->zpool, handle, ZPOOL_MM_RW)
+-> memcpy(buf, &zhdr, hlen)
+-> memcpy(buf + hlen, dst, dlen)
把壓縮後的swap頁存入zpool。
+-> zswap_rb_insert(&tree->rbroot, entry, &dupentry)
把對應的swap頁的entry插入一個紅黑樹,以後load,invalidate等可以從這個
紅黑樹查找對應的swap頁。
從上面store函數的分析中可以看到,因爲整個設計都是基於per cpu的,所以做
crypto_comp_compress的時候都是關閉搶佔的(是否要關閉調度), 這和acomp的基本
使用方式是不兼容的,在crypto testmgr.c裏acomp的test case是wait等待任務完成
的。還有一點,壓縮完的數據需要copy到zpool的內存裏。