IAA 压缩加速器加密驱动程序

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

IAA 加密驱动程序支持与 RFC 1951 中描述的 DEFLATE 压缩标准兼容的压缩/解压缩,这是此模块导出的压缩/解压缩算法。

IAA 硬件规范可以在这里找到

iaa_crypto 驱动程序旨在作为诸如 zswap 之类的高级压缩设备下方的层工作。

用户可以通过在任何允许选择压缩算法的工具中指定受支持的 IAA 压缩算法之一来选择 IAA 压缩/解压缩加速。

例如,zswap 设备可以通过选择 ‘deflate-iaa’ 加密压缩算法来选择 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 是首批可以与英特尔 IOMMU 协同工作的英特尔加速器 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 默认配置

加载 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 设备的工作队列都正确配置为内核工作队列,其工作队列驱动程序名称为“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 设备的工作队列都正确配置为内核工作队列,其工作队列驱动程序名称为“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 使用 'fixed' 压缩模式。

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