IAA 壓縮加速器加密驅動

Tom Zanussi <tom.zanussi@linux.intel.com>

IAA 加密驅動支援與 RFC 1951 中描述的 DEFLATE 壓縮標準相容的壓縮/解壓縮,這是此模組匯出的壓縮/解壓縮演算法。

IAA 硬體規格可以在這裡找到

iaa_crypto 驅動程式設計為在更高級別的壓縮裝置(如 zswap)下工作。

使用者可以透過在允許選擇壓縮演算法的任何工具中指定支援的 IAA 壓縮演算法之一來選擇 IAA 壓縮/解壓縮加速。

例如,zswap 裝置可以選擇 IAA “固定”模式,該模式透過選擇 “deflate-iaa” 加密壓縮演算法來表示

# echo deflate-iaa > /sys/module/zswap/parameters/compressor

這將告訴 zswap 為所有壓縮和解壓縮使用 IAA “固定” 壓縮模式。

目前,只有一個壓縮模式可用,即 “固定” 模式。

“固定” 壓縮模式實現了 RFC 1951 指定的壓縮方案,並被賦予加密演算法名稱 “deflate-iaa”。(由於 IAA 硬體具有 4k 歷史視窗限制,只有 <= 4k 的緩衝區,或者使用 <= 4k 歷史視窗壓縮的緩衝區,才在技術上符合 deflate 規範,該規範允許最多 32k 的視窗。由於此限制,IAA 固定模式 deflate 演算法被賦予自己的演算法名稱,而不是簡單的 “deflate”)。

配置選項和其他設定

IAA 加密驅動程式可以透過 menuconfig 使用以下路徑獲得

Cryptographic API -> Hardware crypto devices -> Support for Intel(R) IAA Compression Accelerator

在配置檔案中,呼叫 CONFIG_CRYPTO_DEV_IAA_CRYPTO 的選項。

IAA 加密驅動程式還支援統計資訊,可以透過 menuconfig 使用以下路徑獲得

Cryptographic API -> Hardware crypto devices -> Support for Intel(R) IAA Compression -> Enable Intel(R) IAA Compression Accelerator Statistics

在配置檔案中,呼叫 CONFIG_CRYPTO_DEV_IAA_CRYPTO_STATS 的選項。

還應啟用以下配置選項

CONFIG_IRQ_REMAP=y
CONFIG_INTEL_IOMMU=y
CONFIG_INTEL_IOMMU_SVM=y
CONFIG_PCI_ATS=y
CONFIG_PCI_PRI=y
CONFIG_PCI_PASID=y
CONFIG_INTEL_IDXD=m
CONFIG_INTEL_IDXD_SVM=y

IAA 是首批可以與 Intel IOMMU 協同工作的 Intel 加速器 IP 之一。存在多種用於測試的模式。根據 IOMMU 配置,有 3 種模式

- Scalable
- Legacy
- No IOMMU

可擴充套件模式

可擴充套件模式支援共享虛擬記憶體 (SVM 或 SVA)。當使用核心引導命令列時,它會被輸入

intel_iommu=on,sm_on

並且在 BIOS 中啟用了 VT-d。

在可擴充套件模式下,共享和專用工作佇列都可供使用。

對於可擴充套件模式,應啟用以下 BIOS 設定

Socket Configuration > IIO Configuration > Intel VT for Directed I/O (VT-d) > Intel VT for Directed I/O

Socket Configuration > IIO Configuration > PCIe ENQCMD > ENQCMDS

傳統模式

當使用核心引導命令列時,輸入傳統模式

intel_iommu=off

或者 BIOS 中未啟用 VT-d。

如果您已引導進入 Linux 並且不確定是否啟用了 VT-d,請執行 “dmesg | grep -i dmar”。如果您沒有看到列舉的許多 DMAR 裝置,則很可能未啟用 VT-d。

在傳統模式下,只有專用工作佇列可供使用。

無 IOMMU 模式

當使用核心引導命令列時,輸入無 IOMMU 模式

iommu=off.

在無 IOMMU 模式下,只有專用工作佇列可供使用。

用法

accel-config

載入後,iaa_crypto 驅動程式會自動建立一個預設配置並啟用它,並分配預設驅動程式屬性。如果需要不同的配置或一組驅動程式屬性,則使用者必須首先停用 IAA 裝置和工作佇列,重置配置,然後透過刪除並重新插入 iaa_crypto 模組來向加密子系統重新註冊 deflate-iaa 演算法。

可以使用下面“用例”部分中的 IAA 停用指令碼 來停用預設配置。

有關預設配置的詳細資訊,請參見下面的 IAA 預設配置

然而,更有可能的是,並且由於加速器裝置的複雜性和可配置性,使用者將希望配置裝置並手動啟用所需的裝置和工作佇列。

幫助執行此操作的使用者空間工具稱為 accel-config。強烈建議使用 accel-config 配置裝置或載入以前儲存的配置。可以直接透過 sysfs 控制裝置,但帶有警告,即只有在您確切知道自己在做什麼的情況下才應這樣做。以下部分將不涵蓋 sysfs 介面,而是假定您將使用 accel-config。

如果感興趣,可以查閱附錄中的 IAA sysfs 配置介面 部分,以獲取 sysfs 介面詳細資訊。

可以在此處找到 accel-config 工具以及構建說明

典型用法

為了使 iaa_crypto 模組代表裝置實際執行任何壓縮/解壓縮工作,需要將一個或多個 IAA 工作佇列繫結到 iaa_crypto 驅動程式。

例如,這是配置 IAA 工作佇列並將其繫結到 iaa_crypto 驅動程式的示例(請注意,裝置名稱指定為 “iax” 而不是 “iaa” - 這是因為上游仍然使用舊的 “iax” 裝置命名)

# configure wq1.0

accel-config config-wq --group-id=0 --mode=dedicated --type=kernel --priority=10 --name="iaa_crypto" --driver-name="crypto" iax1/wq1.0

accel-config config-engine iax1/engine1.0 --group-id=0

# enable IAA device iax1

accel-config enable-device iax1

# enable wq1.0 on IAX device iax1

accel-config enable-wq iax1/wq1.0

每當新的工作佇列繫結到或從 iaa_crypto 驅動程式解繫結時,可用的工作佇列都會“重新平衡”,以便從特定 CPU 提交的工作被分配給最合適的工作佇列。當前的最佳實踐是為每個 IAA 裝置配置和繫結至少一個工作佇列,但只要系統中配置並繫結到任何 IAA 裝置的至少一個工作佇列,iaa_crypto 驅動程式就可以工作,儘管很可能效率不高。

在第一個 IAA 工作佇列成功繫結到 iaa_crypto 驅動程式後,IAA 加密演算法即可執行,並且壓縮和解壓縮操作已完全啟用。

同樣,在最後一個 IAA 工作佇列從 iaa_crypto 驅動程式解繫結後,IAA 加密演算法不可執行,並且壓縮和解壓縮操作被停用。

因此,只有在一個或多個工作佇列繫結到 iaa_crypto 驅動程式時,才能使用 IAA 加密演算法,從而使用 IAA 硬體。

當沒有 IAA 工作佇列繫結到驅動程式時,可以透過刪除模組來取消註冊 IAA 加密演算法。

驅動程式屬性

有幾個使用者可配置的驅動程式屬性可用於配置各種操作模式。 它們在下面列出,以及它們的預設值。 要設定任何這些屬性,請將適當的值回顯到位於 /sys/bus/dsa/drivers/crypto/ 下的屬性檔案。

在註冊 IAA 演算法時,屬性設定會捕獲在每個演算法的 crypto_ctx 中,並用於使用該演算法的所有壓縮和解壓縮。

可用的屬性是

  • verify_compress

    切換壓縮驗證。 如果設定,則每個壓縮將在內部解壓縮並驗證內容,如果失敗則返回錯誤程式碼。 可以使用 0/1 切換此選項

    echo 0 > /sys/bus/dsa/drivers/crypto/verify_compress
    

    預設設定為 “1” - 驗證所有壓縮。

  • sync_mode

    選擇用於等待每個壓縮和解壓縮操作完成的模式。

    iaa_crypto 實現的加密非同步介面支援提供了一個滿足介面的實現,但以同步方式執行 - 它填充並提交 IDXD 描述符,然後迴圈等待其完成,然後再返回。 這目前不是問題,因為所有現有的呼叫方(例如 zswap)都以同步包裝器包裝任何非同步被呼叫方。

    然而,iaa_crypto 驅動程式確實為可以使用它的呼叫方提供了真正的非同步支援。 在此模式下,它填充並提交 IDXD 描述符,然後立即返回 -EINPROGRESS。 然後,呼叫方可以輪詢自身完成情況,這需要呼叫方中的特定程式碼,當前上游核心中沒有任何實現,或者進入休眠狀態並等待中斷訊號完成。 後一種模式受到核心中當前使用者的支援,例如 zswap 透過同步包裝器。 儘管支援此模式,但它比先前所述的在 iaa_crypto 驅動程式中進行輪詢的同步模式慢得多。

    可以透過將 “async_irq” 寫入 sync_mode iaa_crypto 驅動程式屬性來啟用此模式

    echo async_irq > /sys/bus/dsa/drivers/crypto/sync_mode
    

    可以透過將 “async” 寫入它來啟用沒有中斷的非同步模式(呼叫方必須輪詢)(請參閱警告)

    echo async > /sys/bus/dsa/drivers/crypto/sync_mode
    

    可以透過將 “sync” 寫入它來啟用在 iaa_crypto 驅動程式中進行輪詢的模式

    echo sync > /sys/bus/dsa/drivers/crypto/sync_mode
    

    預設模式是 “sync”。

    警告:由於 iaa_crypto 當前實現的用於沒有中斷的非同步輪詢的唯一機制是透過前面描述的 “sync” 模式,因此將 “async” 寫入 “/sys/bus/dsa/drivers/crypto/sync_mode” 將在內部啟用 “sync” 模式。 這是為了確保在 iaa_crypto 中啟用真正的沒有中斷的非同步輪詢之前,iaa_crypto 的行為正確。

IAA 預設配置

載入 iaa_crypto 驅動程式時,每個 IAA 裝置都有一個為其配置的工作佇列,具有以下屬性

mode              "dedicated"
threshold         0
size              Total WQ Size from WQCAP
priority          10
type              IDXD_WQT_KERNEL
group             0
name              "iaa_crypto"
driver_name       "crypto"

裝置和工作佇列也被啟用,因此驅動程式可以在沒有任何其他配置的情況下使用。

驅動程式載入時生效的預設驅動程式屬性是

sync_mode         "sync"
verify_compress   1

為了更改裝置/工作佇列或驅動程式屬性,必須首先停用已啟用的裝置和工作佇列。為了使新配置應用於 deflate-iaa 加密演算法,需要透過刪除並重新插入 iaa_crypto 模組來重新註冊它。可以使用下面“用例”部分中的 IAA 停用指令碼 來停用預設配置。

統計資訊

如果啟用了可選的 debugfs 統計資訊支援,IAA 加密驅動程式將生成統計資訊,可以在 debugfs 中訪問這些統計資訊

# ls -al /sys/kernel/debug/iaa-crypto/
total 0
drwxr-xr-x  2 root root 0 Mar  3 07:55 .
drwx------ 53 root root 0 Mar  3 07:55 ..
-rw-r--r--  1 root root 0 Mar  3 07:55 global_stats
-rw-r--r--  1 root root 0 Mar  3 07:55 stats_reset
-rw-r--r--  1 root root 0 Mar  3 07:55 wq_stats

global_stats 檔案顯示自驅動程式載入或重置以來收集的一組全域性統計資訊

# cat global_stats
global stats:
  total_comp_calls: 4300
  total_decomp_calls: 4164
  total_sw_decomp_calls: 0
  total_comp_bytes_out: 5993989
  total_decomp_bytes_in: 5993989
  total_completion_einval_errors: 0
  total_completion_timeout_errors: 0
  total_completion_comp_buf_overflow_errors: 136

wq_stats 檔案顯示每個 wq 的統計資訊,每個 iaa 裝置和 wq 一組,以及一些全域性統計資訊

# cat wq_stats
iaa device:
  id: 1
  n_wqs: 1
  comp_calls: 0
  comp_bytes: 0
  decomp_calls: 0
  decomp_bytes: 0
  wqs:
    name: iaa_crypto
    comp_calls: 0
    comp_bytes: 0
    decomp_calls: 0
    decomp_bytes: 0

iaa device:
  id: 3
  n_wqs: 1
  comp_calls: 0
  comp_bytes: 0
  decomp_calls: 0
  decomp_bytes: 0
  wqs:
    name: iaa_crypto
    comp_calls: 0
    comp_bytes: 0
    decomp_calls: 0
    decomp_bytes: 0

iaa device:
  id: 5
  n_wqs: 1
  comp_calls: 1360
  comp_bytes: 1999776
  decomp_calls: 0
  decomp_bytes: 0
  wqs:
    name: iaa_crypto
    comp_calls: 1360
    comp_bytes: 1999776
    decomp_calls: 0
    decomp_bytes: 0

iaa device:
  id: 7
  n_wqs: 1
  comp_calls: 2940
  comp_bytes: 3994213
  decomp_calls: 4164
  decomp_bytes: 5993989
  wqs:
    name: iaa_crypto
    comp_calls: 2940
    comp_bytes: 3994213
    decomp_calls: 4164
    decomp_bytes: 5993989
  ...

寫入 “stats_reset” 會重置所有統計資訊,包括每個裝置和每個 wq 的統計資訊

# echo 1 > stats_reset
# cat wq_stats
  global stats:
  total_comp_calls: 0
  total_decomp_calls: 0
  total_comp_bytes_out: 0
  total_decomp_bytes_in: 0
  total_completion_einval_errors: 0
  total_completion_timeout_errors: 0
  total_completion_comp_buf_overflow_errors: 0
  ...

用例

簡單 zswap 測試

對於此示例,核心應根據上面描述的專用模式選項進行配置,並且還應啟用 zswap

CONFIG_ZSWAP=y

這是一個簡單的測試,它使用 iaa_compress 作為交換(zswap)裝置的壓縮器。它設定 zswap 裝置,然後使用下面列出的 memory_memadvise 程式強制交換出和交換入指定數量的頁面,從而演示壓縮和解壓縮。

zswap 測試期望系統上每個 IAA 裝置的工作佇列都正確配置為核心工作佇列,並且工作佇列 driver_name 為 “crypto”。

第一步是確保載入了 iaa_crypto 模組

modprobe iaa_crypto

如果 IAA 裝置和工作佇列以前未被停用和重新配置,那麼應啟用預設配置,並且無需進一步的 IAA 配置。有關預設配置的詳細資訊,請參見下面的 IAA 預設配置

如果預設配置已啟用,您應該看到 iaa 裝置和 wq0s 已啟用

# cat /sys/bus/dsa/devices/iax1/state
enabled
# cat /sys/bus/dsa/devices/iax1/wq1.0/state
enabled

為了演示以下步驟按預期工作,可以使用以下命令啟用除錯輸出

# echo -n 'module iaa_crypto +p' > /sys/kernel/debug/dynamic_debug/control
# echo -n 'module idxd +p' > /sys/kernel/debug/dynamic_debug/control

使用以下命令啟用 zswap

# echo 0 > /sys/module/zswap/parameters/enabled
# echo 50 > /sys/module/zswap/parameters/max_pool_percent
# echo deflate-iaa > /sys/module/zswap/parameters/compressor
# echo zsmalloc > /sys/module/zswap/parameters/zpool
# echo 1 > /sys/module/zswap/parameters/enabled
# echo 100 > /proc/sys/vm/swappiness
# echo never > /sys/kernel/mm/transparent_hugepage/enabled
# echo 1 > /proc/sys/vm/overcommit_memory

現在您可以執行要測量的 zswap 工作負載。例如,使用下面的 memory_memadvise 程式碼,以下命令將交換入和交換出 100 個頁面

./memory_madvise 100

Allocating 100 pages to swap in/out
Swapping out 100 pages
Swapping in 100 pages
Swapped out and in 100 pages

您應該在 dmesg 輸出中看到類似於以下內容

[  404.202972] idxd 0000:e7:02.0: iaa_comp_acompress: dma_map_sg, src_addr 223925c000, nr_sgs 1, req->src 00000000ee7cb5e6, req->slen 4096, sg_dma_len(sg) 4096
[  404.202973] idxd 0000:e7:02.0: iaa_comp_acompress: dma_map_sg, dst_addr 21dadf8000, nr_sgs 1, req->dst 000000008d6acea8, req->dlen 4096, sg_dma_len(sg) 8192
[  404.202975] idxd 0000:e7:02.0: iaa_compress: desc->src1_addr 223925c000, desc->src1_size 4096, desc->dst_addr 21dadf8000, desc->max_dst_size 4096, desc->src2_addr 2203543000, desc->src2_size 1568
[  404.202981] idxd 0000:e7:02.0: iaa_compress_verify: (verify) desc->src1_addr 21dadf8000, desc->src1_size 228, desc->dst_addr 223925c000, desc->max_dst_size 4096, desc->src2_addr 0, desc->src2_size 0
...

既然已經演示了基本功能,可以擦除預設值並用不同的配置替換。為此,首先停用 zswap

# echo lzo > /sys/module/zswap/parameters/compressor
# swapoff -a
# echo 0 > /sys/module/zswap/parameters/accept_threshold_percent
# echo 0 > /sys/module/zswap/parameters/max_pool_percent
# echo 0 > /sys/module/zswap/parameters/enabled
# echo 0 > /sys/module/zswap/parameters/enabled

然後執行下面“用例”部分中的 IAA 停用指令碼 以停用預設配置。

最後重新開啟交換

# swapon -a

完成所有操作後,現在可以根據需要重新配置和啟用 IAA 裝置以進行進一步測試。下面是一個示例。

zswap 測試期望系統上每個 IAA 裝置的工作佇列都正確配置為核心工作佇列,並且工作佇列 driver_name 為 “crypto”。

下面的指令碼會自動執行此操作

#!/bin/bash

echo "IAA devices:"
lspci -d:0cfe
echo "# IAA devices:"
lspci -d:0cfe | wc -l

#
# count iaa instances
#
iaa_dev_id="0cfe"
num_iaa=$(lspci -d:${iaa_dev_id} | wc -l)
echo "Found ${num_iaa} IAA instances"

#
# disable iaa wqs and devices
#
echo "Disable IAA"

for ((i = 1; i < ${num_iaa} * 2; i += 2)); do
    echo disable wq iax${i}/wq${i}.0
    accel-config disable-wq iax${i}/wq${i}.0
    echo disable iaa iax${i}
    accel-config disable-device iax${i}
done

echo "End Disable IAA"

echo "Reload iaa_crypto module"

rmmod iaa_crypto
modprobe iaa_crypto

echo "End Reload iaa_crypto module"

#
# configure iaa wqs and devices
#
echo "Configure IAA"
for ((i = 1; i < ${num_iaa} * 2; i += 2)); do
    accel-config config-wq --group-id=0 --mode=dedicated --wq-size=128 --priority=10 --type=kernel --name="iaa_crypto" --driver-name="crypto" iax${i}/wq${i}.0
    accel-config config-engine iax${i}/engine${i}.0 --group-id=0
done

echo "End Configure IAA"

#
# enable iaa wqs and devices
#
echo "Enable IAA"

for ((i = 1; i < ${num_iaa} * 2; i += 2)); do
    echo enable iaa iax${i}
    accel-config enable-device iax${i}
    echo enable wq iax${i}/wq${i}.0
    accel-config enable-wq iax${i}/wq${i}.0
done

echo "End Enable IAA"

當工作佇列繫結到 iaa_crypto 驅動程式時,如果啟用了除錯輸出(echo -n ‘module iaa_crypto +p’ > /sys/kernel/debug/dynamic_debug/control),您應該在 dmesg 輸出中看到類似於以下內容

[   60.752344] idxd 0000:f6:02.0: add_iaa_wq: added wq 000000004068d14d to iaa 00000000c9585ba2, n_wq 1
[   60.752346] iaa_crypto: rebalance_wq_table: nr_nodes=2, nr_cpus 160, nr_iaa 8, cpus_per_iaa 20
[   60.752347] iaa_crypto: rebalance_wq_table: iaa=0
[   60.752349] idxd 0000:6a:02.0: request_iaa_wq: getting wq from iaa_device 0000000042d7bc52 (0)
[   60.752350] idxd 0000:6a:02.0: request_iaa_wq: returning unused wq 00000000c8bb4452 (0) from iaa device 0000000042d7bc52 (0)
[   60.752352] iaa_crypto: rebalance_wq_table: assigned wq for cpu=0, node=0 = wq 00000000c8bb4452
[   60.752354] iaa_crypto: rebalance_wq_table: iaa=0
[   60.752355] idxd 0000:6a:02.0: request_iaa_wq: getting wq from iaa_device 0000000042d7bc52 (0)
[   60.752356] idxd 0000:6a:02.0: request_iaa_wq: returning unused wq 00000000c8bb4452 (0) from iaa device 0000000042d7bc52 (0)
[   60.752358] iaa_crypto: rebalance_wq_table: assigned wq for cpu=1, node=0 = wq 00000000c8bb4452
[   60.752359] iaa_crypto: rebalance_wq_table: iaa=0
[   60.752360] idxd 0000:6a:02.0: request_iaa_wq: getting wq from iaa_device 0000000042d7bc52 (0)
[   60.752361] idxd 0000:6a:02.0: request_iaa_wq: returning unused wq 00000000c8bb4452 (0) from iaa device 0000000042d7bc52 (0)
[   60.752362] iaa_crypto: rebalance_wq_table: assigned wq for cpu=2, node=0 = wq 00000000c8bb4452
[   60.752364] iaa_crypto: rebalance_wq_table: iaa=0
.
.
.

一旦啟用了工作佇列和裝置,IAA 加密演算法就會啟用並可用。成功啟用 IAA 加密演算法後,您應該看到以下 dmesg 輸出

[   64.893759] iaa_crypto: iaa_crypto_enable: iaa_crypto now ENABLED

現在執行以下 zswap 特定的設定命令,使 zswap 使用 “固定” 壓縮模式

echo 0 > /sys/module/zswap/parameters/enabled
echo 50 > /sys/module/zswap/parameters/max_pool_percent
echo deflate-iaa > /sys/module/zswap/parameters/compressor
echo zsmalloc > /sys/module/zswap/parameters/zpool
echo 1 > /sys/module/zswap/parameters/enabled

echo 100 > /proc/sys/vm/swappiness
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo 1 > /proc/sys/vm/overcommit_memory

最後,您現在可以執行要測量的 zswap 工作負載。例如,使用下面的程式碼,以下命令將交換入和交換出 100 個頁面

./memory_madvise 100

Allocating 100 pages to swap in/out
Swapping out 100 pages
Swapping in 100 pages
Swapped out and in 100 pages

如果啟用了除錯輸出(echo -n ‘module iaa_crypto +p’ > /sys/kernel/debug/dynamic_debug/control),您應該在 dmesg 輸出中看到類似於以下內容

[  404.202972] idxd 0000:e7:02.0: iaa_comp_acompress: dma_map_sg, src_addr 223925c000, nr_sgs 1, req->src 00000000ee7cb5e6, req->slen 4096, sg_dma_len(sg) 4096
[  404.202973] idxd 0000:e7:02.0: iaa_comp_acompress: dma_map_sg, dst_addr 21dadf8000, nr_sgs 1, req->dst 000000008d6acea8, req->dlen 4096, sg_dma_len(sg) 8192
[  404.202975] idxd 0000:e7:02.0: iaa_compress: desc->src1_addr 223925c000, desc->src1_size 4096, desc->dst_addr 21dadf8000, desc->max_dst_size 4096, desc->src2_addr 2203543000, desc->src2_size 1568
[  404.202981] idxd 0000:e7:02.0: iaa_compress_verify: (verify) desc->src1_addr 21dadf8000, desc->src1_size 228, desc->dst_addr 223925c000, desc->max_dst_size 4096, desc->src2_addr 0, desc->src2_size 0
[  409.203227] idxd 0000:e7:02.0: iaa_comp_adecompress: dma_map_sg, src_addr 21ddd8b100, nr_sgs 1, req->src 0000000084adab64, req->slen 228, sg_dma_len(sg) 228
[  409.203235] idxd 0000:e7:02.0: iaa_comp_adecompress: dma_map_sg, dst_addr 21ee3dc000, nr_sgs 1, req->dst 000000004e2990d0, req->dlen 4096, sg_dma_len(sg) 4096
[  409.203239] idxd 0000:e7:02.0: iaa_decompress: desc->src1_addr 21ddd8b100, desc->src1_size 228, desc->dst_addr 21ee3dc000, desc->max_dst_size 4096, desc->src2_addr 0, desc->src2_size 0
[  409.203254] idxd 0000:e7:02.0: iaa_comp_adecompress: dma_map_sg, src_addr 21ddd8b100, nr_sgs 1, req->src 0000000084adab64, req->slen 228, sg_dma_len(sg) 228
[  409.203256] idxd 0000:e7:02.0: iaa_comp_adecompress: dma_map_sg, dst_addr 21f1551000, nr_sgs 1, req->dst 000000004e2990d0, req->dlen 4096, sg_dma_len(sg) 4096
[  409.203257] idxd 0000:e7:02.0: iaa_decompress: desc->src1_addr 21ddd8b100, desc->src1_size 228, desc->dst_addr 21f1551000, desc->max_dst_size 4096, desc->src2_addr 0, desc->src2_size 0

為了取消註冊 IAA 加密演算法,並使用不同的引數註冊新的演算法,應停止當前演算法的任何使用者,並停用 IAA 工作佇列和裝置。

對於 zswap,刪除 IAA 加密演算法作為壓縮器並關閉交換(以刪除對 iaa_crypto 的所有引用)

echo lzo > /sys/module/zswap/parameters/compressor
swapoff -a

echo 0 > /sys/module/zswap/parameters/accept_threshold_percent
echo 0 > /sys/module/zswap/parameters/max_pool_percent
echo 0 > /sys/module/zswap/parameters/enabled

一旦 zswap 被停用並且不再使用 iaa_crypto,就可以停用 IAA wqs 和裝置。

IAA 停用指令碼

下面的指令碼會自動執行此操作

#!/bin/bash

echo "IAA devices:"
lspci -d:0cfe
echo "# IAA devices:"
lspci -d:0cfe | wc -l

#
# count iaa instances
#
iaa_dev_id="0cfe"
num_iaa=$(lspci -d:${iaa_dev_id} | wc -l)
echo "Found ${num_iaa} IAA instances"

#
# disable iaa wqs and devices
#
echo "Disable IAA"

for ((i = 1; i < ${num_iaa} * 2; i += 2)); do
    echo disable wq iax${i}/wq${i}.0
    accel-config disable-wq iax${i}/wq${i}.0
    echo disable iaa iax${i}
    accel-config disable-device iax${i}
done

echo "End Disable IAA"

最後,在這一點上,可以刪除 iaa_crypto 模組,這將取消註冊當前的 IAA 加密演算法

rmmod iaa_crypto

memory_madvise.c (gcc -o memory_memadvise memory_madvise.c)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <linux/mman.h>

#ifndef MADV_PAGEOUT
#define MADV_PAGEOUT    21      /* force pages out immediately */
#endif

#define PG_SZ           4096

int main(int argc, char **argv)
{
      int i, nr_pages = 1;
      int64_t *dump_ptr;
      char *addr, *a;
      int loop = 1;

      if (argc > 1)
              nr_pages = atoi(argv[1]);

      printf("Allocating %d pages to swap in/out\n", nr_pages);

      /* allocate pages */
      addr = mmap(NULL, nr_pages * PG_SZ, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
      *addr = 1;

      /* initialize data in page to all '*' chars */
      memset(addr, '*', nr_pages * PG_SZ);

       printf("Swapping out %d pages\n", nr_pages);

      /* Tell kernel to swap it out */
      madvise(addr, nr_pages * PG_SZ, MADV_PAGEOUT);

      while (loop > 0) {
              /* Wait for swap out to finish */
              sleep(5);

              a = addr;

              printf("Swapping in %d pages\n", nr_pages);

              /* Access the page ... this will swap it back in again */
              for (i = 0; i < nr_pages; i++) {
                      if (a[0] != '*') {
                              printf("Bad data from decompress!!!!!\n");

                              dump_ptr = (int64_t *)a;
                               for (int j = 0; j < 100; j++) {
                                      printf("  page %d data: %#llx\n", i, *dump_ptr);
                                      dump_ptr++;
                              }
                      }

                      a += PG_SZ;
              }

              loop --;
      }

     printf("Swapped out and in %d pages\n", nr_pages);

附錄

IAA sysfs 配置介面

下面是 IAA sysfs 介面的描述,正如在主要文件中提到的那樣,只有在您確切知道自己在做什麼的情況下才應使用它。 即使這樣,也沒有令人信服的理由直接使用它,因為 accel-config 可以完成 sysfs 介面可以做的所有事情,事實上,accel-config 是在它之下構建的。

“IAA 配置路徑”是 /sys/bus/dsa/devices,其中包含表示每個 IAA 裝置、工作佇列、引擎和組的子目錄。 請注意,在 sysfs 介面中,IAA 裝置實際上是使用 iax 命名的,例如 iax1、iax3 等。(請注意,IAA 裝置是奇數裝置;偶數裝置是 DSA 裝置,可以忽略 IAA)。

“IAA 裝置繫結路徑”是 /sys/bus/dsa/drivers/idxd/bind,它是用於啟用 IAA 裝置的檔案。

“IAA 工作佇列繫結路徑”是 /sys/bus/dsa/drivers/crypto/bind,它是用於啟用 IAA 工作佇列的檔案。

類似地,/sys/bus/dsa/drivers/idxd/unbind 和 /sys/bus/dsa/drivers/crypto/unbind 用於停用 IAA 裝置和工作佇列。

設定 IAA 裝置和工作佇列所需的基本命令序列是

對於每個裝置:
  1. 停用裝置上啟用的任何工作佇列。 例如,要停用 IAA 裝置 3 上的工作佇列 0 和 1

    # echo wq3.0 > /sys/bus/dsa/drivers/crypto/unbind
    # echo wq3.1 > /sys/bus/dsa/drivers/crypto/unbind
    
  2. 停用裝置。 例如,要停用 IAA 裝置 3

    # echo iax3 > /sys/bus/dsa/drivers/idxd/unbind
    
  3. 配置所需的工作佇列。 例如,要在 IAA 裝置 3 上配置工作佇列 3

    # echo dedicated > /sys/bus/dsa/devices/iax3/wq3.3/mode
    # echo 128 > /sys/bus/dsa/devices/iax3/wq3.3/size
    # echo 0 > /sys/bus/dsa/devices/iax3/wq3.3/group_id
    # echo 10 > /sys/bus/dsa/devices/iax3/wq3.3/priority
    # echo "kernel" > /sys/bus/dsa/devices/iax3/wq3.3/type
    # echo "iaa_crypto" > /sys/bus/dsa/devices/iax3/wq3.3/name
    # echo "crypto" > /sys/bus/dsa/devices/iax3/wq3.3/driver_name
    
  4. 啟用裝置。 例如,要啟用 IAA 裝置 3

    # echo iax3 > /sys/bus/dsa/drivers/idxd/bind
    
  5. 啟用裝置上所需的工作佇列。 例如,要啟用 IAA 裝置 3 上的工作佇列 0 和 1

    # echo wq3.0 > /sys/bus/dsa/drivers/crypto/bind
    # echo wq3.1 > /sys/bus/dsa/drivers/crypto/bind