zswap¶
概述¶
Zswap 是用於交換頁面的輕量級壓縮快取。它獲取正在被換出的頁面,並嘗試將它們壓縮到動態分配的基於 RAM 的記憶體池中。 zswap 基本上是用 CPU 週期來換取可能減少的交換 I/O。如果從壓縮快取讀取比從交換裝置讀取更快,那麼這種權衡也會帶來顯著的效能提升。
一些潛在的好處
具有有限 RAM 容量的桌面/筆記型電腦使用者可以減輕交換帶來的效能影響。
過度分配的虛擬機器可以共享一個通用的 I/O 資源,從而顯著降低它們的交換 I/O 壓力,避免虛擬機器管理程式進行嚴厲的 I/O 節流。這使得更多的工作能夠完成,同時對虛擬機器工作負載和共享 I/O 子系統的虛擬機器的影響更小。
使用 SSD 作為交換裝置的使用者可以透過大幅減少縮短壽命的寫入來延長裝置的使用壽命。
當壓縮池達到其大小限制時,Zswap 會以 LRU 為基礎從壓縮快取中逐出頁面到後備交換裝置。 此要求已在先前的社群討論中確定。
Zswap 是否在啟動時啟用取決於是否啟用了 CONFIG_ZSWAP_DEFAULT_ON Kconfig 選項。 然後可以透過提供核心命令列 zswap.enabled= 選項來覆蓋此設定,例如 zswap.enabled=0。 也可以在執行時使用 sysfs 介面啟用和停用 Zswap。 在執行時啟用 zswap 的示例命令,假設 sysfs 安裝在 /sys,是
echo 1 > /sys/module/zswap/parameters/enabled
在執行時停用 zswap 時,它將停止儲存正在被換出的頁面。 但是,它_不會_立即寫出或錯誤地將其中的頁面恢復到記憶體中。 儲存在 zswap 中的頁面將保留在壓縮池中,直到它們失效或錯誤地恢復到記憶體中。 為了強制所有頁面退出壓縮池,對交換裝置執行 swapoff 將錯誤地將所有換出的頁面(包括壓縮池中的頁面)恢復到記憶體中。
設計¶
Zswap 從交換子系統接收用於壓縮的頁面,並且能夠以 LRU 為基礎從其自身的壓縮池中逐出頁面,並在壓縮池已滿的情況下將它們寫回到後備交換裝置。
Zswap 使用 zpool 來管理壓縮記憶體池。 zpool 中的每個分配都不能直接透過地址訪問。 相反,分配例程返回一個控制代碼,並且必須先對映該控制代碼才能被訪問。 壓縮記憶體池按需增長,並隨著壓縮頁面的釋放而縮小。 該池不是預先分配的。 預設情況下,會建立在 CONFIG_ZSWAP_ZPOOL_DEFAULT Kconfig 選項中選擇型別的 zpool,但可以透過設定 zpool 屬性在啟動時覆蓋它,例如 zswap.zpool=zsmalloc。 也可以使用 sysfs zpool 屬性在執行時更改它,例如
echo zsmalloc > /sys/module/zswap/parameters/zpool
zsmalloc 型別的 zpool 具有複雜的壓縮頁面儲存方法,它可以實現很大的儲存密度。
當交換頁面從換出傳遞到 zswap 時,zswap 會維護交換條目的對映(交換型別和交換偏移量的組合)到引用該壓縮交換頁面的 zpool 控制代碼。 此對映是透過每個交換型別的紅黑樹實現的。 交換偏移量是樹節點的搜尋鍵。
在作為交換條目的 PTE 上的頁面錯誤期間,交換程式碼呼叫 zswap 載入函式以將頁面解壓縮到頁面錯誤處理程式分配的頁面中。
一旦沒有 PTE 引用儲存在 zswap 中的交換頁面(即,swap_map 中的計數變為 0),交換程式碼就會呼叫 zswap 失效函式來釋放壓縮條目。
Zswap 尋求在策略上保持簡單。 Sysfs 屬性允許一個使用者控制的策略
max_pool_percent - 壓縮池可以佔用記憶體的最大百分比。
預設壓縮器在 CONFIG_ZSWAP_COMPRESSOR_DEFAULT Kconfig 選項中選擇,但可以透過設定 compressor 屬性在啟動時覆蓋它,例如 zswap.compressor=lzo。 也可以使用 sysfs “compressor” 屬性在執行時更改它,例如
echo lzo > /sys/module/zswap/parameters/compressor
當在執行時更改 zpool 和/或壓縮器引數時,任何現有的壓縮頁面都不會被修改; 它們保留在它們自己的 zpool 中。 當請求舊 zpool 中的頁面時,它會使用其原始壓縮器進行解壓縮。 一旦從舊 zpool 中刪除了所有頁面,zpool 及其壓縮器就會被釋放。
zswap 中的一些頁面是相同值填充頁面(即,頁面的內容具有相同的值或重複的模式)。 這些頁面包括零填充頁面,它們的處理方式不同。 在儲存操作期間,在壓縮頁面之前檢查頁面是否為相同值填充頁面。 如果為真,則頁面的壓縮長度設定為零,並存儲模式或相同填充值。
為了防止 zswap 在 zswap 已滿並且交換壓力很高時縮小池(這將導致頁面在 zswap 池中進出翻轉,沒有任何實際好處,但會導致系統性能下降),引入了一個特殊引數來實現一種滯後效應,以拒絕將頁面放入 zswap 池,直到它有足夠的空間,如果已達到限制。 要設定 zswap 在已滿後將再次開始接受頁面的閾值,請使用 sysfs accept_threshold_percent 屬性,例如
echo 80 > /sys/module/zswap/parameters/accept_threshold_percent
將此引數設定為 100 將停用滯後效應。
一些使用者無法容忍伴隨 zswap 儲存失敗和 zswap 寫回的交換。 可以按 cgroup 停用交換(無需停用 zswap 本身),如下所示
echo 0 > /sys/fs/cgroup/<cgroup-name>/memory.zswap.writeback
請注意,如果儲存失敗反覆出現(例如,如果頁面不可壓縮),使用者可能會在停用寫回後觀察到回收效率低下(因為相同的頁面可能會一次又一次地被拒絕)。
當 zswap 池中存在大量冷記憶體時,主動將這些冷頁面寫入交換空間並回收記憶體以供其他用例使用可能是有利的。 預設情況下,zswap 收縮器已停用。 使用者可以按如下方式啟用它
echo Y > /sys/module/zswap/parameters/shrinker_enabled
如果選擇了 CONFIG_ZSWAP_SHRINKER_DEFAULT_ON,則可以在啟動時啟用此功能。
提供了一個 debugfs 介面,用於顯示有關池大小、儲存的頁面數、相同值填充頁面以及頁面被拒絕的各種原因的各種統計資訊。