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