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的記憶體裡。