Linux zswap構架分析

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.

  1. 基本模型

  • zswap初始化流程

    1. 爲系統裏的每一個cpu core分配per cpu dst內存。

    2. 爲每個cpu core分配內核壓縮解壓縮的上下文。

    3. 創建zpool, 並根據用戶態模塊參數選擇zpool後端使用的內存分配器。創建
      zpool的時候需要給zpool註冊一個evict的回調函數,這個函數用於在zpool的
      後端內存分配器沒有內存的時候, 把zpool裏的壓縮內存向swap設備寫入。可以
      看到現在的evict在向swap設備寫數據的時候還要先把壓縮的數據解壓縮,如果寫
      入swap設備的數據將來被使用,重新加載回內存的代碼路徑是標準的缺頁流程,
      和zswap沒有關係。這個步驟整體上把創建出來的各種基礎數據結構封裝在一個
      struct zswap_pool的結構中, 上面步驟裏的per cpu壓縮解壓縮上下文也放在了
      zswap_pool。

    4. 註冊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接口的後端可以是不同的專用於存儲壓縮內存的內存分配器。

  • 對用戶態的接口

    1. zswap用多個模塊參數用來配置zswap的參數: zpool的後端內存分配器是可以選的
      (默認是zbud); 壓縮解壓算法(默認是LZO),測試硬件offload的時候,這裏要選
      則相應的算法; zpool佔內存的大小; 對相同頁的優化處理。

      這些參數在/sys/module/zswap/parameters/下也可以配置。

    2. 在/sys/kernel/debug/zswap/下有zswap的相關統計項。

  • 對內核crypto comp的接口

    1. 當前代碼使用的是內核crypto comp壓縮解壓縮接口,沒有使用crypto acomp接口。
  1. 實現細節

不清楚這裏的邏輯,爲什麼要一個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的內存裏。
發佈了154 篇原創文章 · 獲贊 18 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章