Skip to content

iommu/riscv: add dma_wmb before cmpxchg_relaxed#309

Merged
sterling-teng merged 1 commit into
RVCK-Project:rvck-6.6from
zte-riscv:pr-iommu-dma_wmb
Jul 9, 2026
Merged

iommu/riscv: add dma_wmb before cmpxchg_relaxed#309
sterling-teng merged 1 commit into
RVCK-Project:rvck-6.6from
zte-riscv:pr-iommu-dma_wmb

Conversation

@GooTal

@GooTal GooTal commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

fixed: #308

drivers/iommu:riscv:add dma_wmb before cmpxchg_relaxed

driver inclusion
category: bugfix
bugzilla: #308


When using NVMe for PCIe peripherals on an RV multi-core CPU with IOMMU
enabled, the command fio --filename=/dev/nvme0n1 --ioengine=libaio --direct=1 --iodepth=256 --numjobs=8 --group_reporting=1 --bs=1M --time_based=1 --runtime=2 --rw=read --name=test_read_8 --thread=1
resulted a fault 15 exception during IOMMU testing.

When multiple cores modify iommu page talbe simultaneously, executing
riscv_iommu_map_pages or riscv_iommu_pte_alloc, an out-of-order iommu
page table clearing problem can occur due to a memory barrier missing.
It caused PTE being incorrectly cleared.

Setting dma_wmb ensures that all previous DMA write operations have
been completed before cmpxchg_relaxed.

This issue is relatively rare and may only occur during stress testing.

Signed-off-by: bailu bai.lu5@zte.com.cn
Signed-off-by: liuqingtao liu.qingtao2@zte.com.cn

@github-actions

github-actions Bot commented Jun 17, 2026

Copy link
Copy Markdown

开始测试 log: https://github.com/RVCK-Project/rvck/actions/runs/27664081160

参数解析结果
args value
repository RVCK-Project/rvck
head ref pull/309/head
base ref rvck-6.6
LAVA repo RVCK-Project/lavaci
LAVA hardware ['qemu']
LAVA Testcase path lava-testcases/common-test/ltp/ltp.yaml
need run job kunit-test,kernel-build,check-patch,lava-trigger

测试完成

详细结果:
check result
kunit-test success
kernel-build success
check-patch failure
lava-trigger-qemu success
lava-trigger-sg2042 skipped
lava-trigger-k1 skipped
lava-trigger-lpi4a skipped

Kunit Test Result

[03:42:15] Testing complete. Ran 482 tests: passed: 466, skipped: 16

Kernel Build Result

Check Patch Result

Total Errors 1
Total Warnings 1

LAVA Check (qemu)

args value
testcase_repo RVCK-Project/lavaci
lava_template lava-job-template/qemu/qemu-ltp.yaml
testcase_path lava-testcases/common-test/ltp/ltp.yaml
kernel_download_url http://10.30.190.110/openEuler-RISC-V/RVCK/OERV-RVCI/RVCK-Project/rvck/309_27664081160_1/Image
initramfs_download_url http://10.30.190.110/openEuler-RISC-V/RVCK/OERV-RVCI/RVCK-Project/rvck/309_27664081160_1/initramfs.img
rootfs_download_url https://fast-mirror.isrc.ac.cn/openeuler-sig-riscv/openEuler-RISC-V/RVCK/openEuler24.03-LTS-SP1/openeuler-rootfs.img.zst
testcase_ref main
testitem_name RVCK-Project_rvck_pull_request_target_309__common-test_qemu

result: Lava check done!

@github-actions

github-actions Bot commented Jun 17, 2026

Copy link
Copy Markdown

开始测试 log: https://github.com/RVCK-Project/rvck/actions/runs/27677458532

参数解析结果
args value
repository RVCK-Project/rvck
head ref pull/309/head
base ref rvck-6.6
LAVA repo RVCK-Project/lavaci
LAVA hardware ['qemu']
LAVA Testcase path lava-testcases/common-test/ltp/ltp.yaml
need run job kunit-test,kernel-build,check-patch,lava-trigger

测试完成

详细结果:
check result
kunit-test success
kernel-build success
check-patch success
lava-trigger-qemu success
lava-trigger-sg2042 skipped
lava-trigger-k1 skipped
lava-trigger-lpi4a skipped

Kunit Test Result

[08:58:23] Testing complete. Ran 482 tests: passed: 466, skipped: 16

Kernel Build Result

Check Patch Result

Total Errors 0
Total Warnings 0

LAVA Check (qemu)

args value
testcase_repo RVCK-Project/lavaci
lava_template lava-job-template/qemu/qemu-ltp.yaml
testcase_path lava-testcases/common-test/ltp/ltp.yaml
kernel_download_url http://10.30.190.110/openEuler-RISC-V/RVCK/OERV-RVCI/RVCK-Project/rvck/309_27677458532_1/Image
initramfs_download_url http://10.30.190.110/openEuler-RISC-V/RVCK/OERV-RVCI/RVCK-Project/rvck/309_27677458532_1/initramfs.img
rootfs_download_url https://fast-mirror.isrc.ac.cn/openeuler-sig-riscv/openEuler-RISC-V/RVCK/openEuler24.03-LTS-SP1/openeuler-rootfs.img.zst
testcase_ref main
testitem_name RVCK-Project_rvck_pull_request_target_309__common-test_qemu

result: Lava check done!

@fangyu0809

fangyu0809 commented Jun 18, 2026

Copy link
Copy Markdown

The real race here is CPU-CPU (concurrent pte_alloc callers), not CPU-to-DMA-device. dma_wmb fixes it functionally but is semantically misleading. Suggest using cmpxchg_release instead,— matching upstream generic_pt (pt_table_install64 uses try_cmpxchg64_release)

  • ret = cmpxchg_relaxed(ptep, 0ULL, pte);
  • ret = cmpxchg_release(ptep, 0ULL, pte);

Also, the CPU vs IOMMU-HW-walker race likely doesn't exist for new PDE installation,Please double-check whether this race is actually reachable in practice.

@king729

king729 commented Jun 22, 2026

Copy link
Copy Markdown

@fangyu0809
The trade-off of this modification come from the current ARM implementation:

/*
 * Ensure the table itself is visible before its PTE can be.
 * Whilst we could get away with cmpxchg64_release below, this
 * doesn't have any ordering semantics when !CONFIG_SMP.
 */
dma_wmb();

old = cmpxchg64_relaxed(ptep, curr, new);

As the comment explains, the introduction of dma_wmb() primarily addresses the lack of ordering guarantees for cmpxchg64_release on non‑SMP architectures.

The new version modifies this to:

if (!IS_ENABLED(CONFIG_SMP))
    dma_wmb();
ret = try_cmpxchg64_release(entryp, &old_entry, table_entry);

I believe this adjustment is also intended to maintain compatibility across both SMP and non‑SMP configurations.

Therefore, in my current modification, I have chosen to adopt the earlier approach — using dma_wmb() combined with cmpxchg64_relaxed — for consistency and to preserve the original ordering semantics.

@GooTal
GooTal force-pushed the pr-iommu-dma_wmb branch from b42cb3f to 26f0782 Compare June 26, 2026 01:02
@github-actions

github-actions Bot commented Jun 26, 2026

Copy link
Copy Markdown

开始测试 log: https://github.com/RVCK-Project/rvck/actions/runs/28210386797

参数解析结果
args value
repository RVCK-Project/rvck
head ref pull/309/head
base ref rvck-6.6
LAVA repo RVCK-Project/lavaci
LAVA hardware ['qemu']
LAVA Testcase path lava-testcases/common-test/ltp/ltp.yaml
need run job kunit-test,kernel-build,check-patch,lava-trigger

测试完成

详细结果:
check result
kunit-test success
kernel-build success
check-patch failure
lava-trigger-qemu success
lava-trigger-sg2042 skipped
lava-trigger-k1 skipped
lava-trigger-lpi4a skipped

Kunit Test Result

[01:07:04] Testing complete. Ran 482 tests: passed: 466, skipped: 16

Kernel Build Result

Check Patch Result

Total Errors 20
Total Warnings 1

LAVA Check (qemu)

args value
testcase_repo RVCK-Project/lavaci
lava_template lava-job-template/qemu/qemu-ltp.yaml
testcase_path lava-testcases/common-test/ltp/ltp.yaml
kernel_download_url http://10.30.190.110/openEuler-RISC-V/RVCK/OERV-RVCI/RVCK-Project/rvck/309_28210386797_1/Image
initramfs_download_url http://10.30.190.110/openEuler-RISC-V/RVCK/OERV-RVCI/RVCK-Project/rvck/309_28210386797_1/initramfs.img
rootfs_download_url https://fast-mirror.isrc.ac.cn/openeuler-sig-riscv/openEuler-RISC-V/RVCK/openEuler24.03-LTS-SP1/openeuler-rootfs.img.zst
testcase_ref main
testitem_name RVCK-Project_rvck_pull_request_target_309__common-test_qemu

result: Lava check done!

@GooTal
GooTal force-pushed the pr-iommu-dma_wmb branch from 26f0782 to 1b80137 Compare June 29, 2026 12:22
@github-actions

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown

开始测试 log: https://github.com/RVCK-Project/rvck/actions/runs/28371670607

参数解析结果
args value
repository RVCK-Project/rvck
head ref pull/309/head
base ref rvck-6.6
LAVA repo RVCK-Project/lavaci
LAVA hardware ['qemu']
LAVA Testcase path lava-testcases/common-test/ltp/ltp.yaml
need run job kunit-test,kernel-build,check-patch,lava-trigger

测试完成

详细结果:
check result
kunit-test success
kernel-build success
check-patch success
lava-trigger-qemu success
lava-trigger-sg2042 skipped
lava-trigger-k1 skipped
lava-trigger-lpi4a skipped

Kunit Test Result

[12:27:18] Testing complete. Ran 482 tests: passed: 466, skipped: 16

Kernel Build Result

Check Patch Result

Total Errors 0
Total Warnings 0

LAVA Check (qemu)

args value
testcase_repo RVCK-Project/lavaci
lava_template lava-job-template/qemu/qemu-ltp.yaml
testcase_path lava-testcases/common-test/ltp/ltp.yaml
kernel_download_url http://10.30.190.110/openEuler-RISC-V/RVCK/OERV-RVCI/RVCK-Project/rvck/309_28371670607_1/Image
initramfs_download_url http://10.30.190.110/openEuler-RISC-V/RVCK/OERV-RVCI/RVCK-Project/rvck/309_28371670607_1/initramfs.img
rootfs_download_url https://fast-mirror.isrc.ac.cn/openeuler-sig-riscv/openEuler-RISC-V/RVCK/openEuler24.03-LTS-SP1/openeuler-rootfs.img.zst
testcase_ref main
testitem_name RVCK-Project_rvck_pull_request_target_309__common-test_qemu

result: Lava check done!

@unicornx
unicornx self-requested a review June 30, 2026 08:57
@GooTal

GooTal commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

@fangyu0809 @sterling-teng Hi,两位老师,是否可以合入了

@sterling-teng

Copy link
Copy Markdown
Contributor

@fangyu0809 @sterling-teng Hi,两位老师,是否可以合入了

因为这个补丁29日push后才过ci,而且不是backport的补丁;稳妥起见,等今天rebase后我们评审测试之后再合并吧。

@fangyu0809

Copy link
Copy Markdown

Reviewed-by: Fangyu Yu fangyu.yu@linux.alibaba.com

@unicornx

unicornx commented Jul 1, 2026

Copy link
Copy Markdown

@GooTal 请问这个问题您是在什么硬件环境下发现的,可以复现吗?我想试试。

Comment thread drivers/iommu/riscv/iommu.c Outdated
* a barrier is required; additionally, the dma_wmb primitive is
* selected to avoid potential race conditions between
* the IOMMU and the CPU.
* An out-of-tree bugfix that may require future updates.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

“An out-of-tree bugfix that may require future updates.” 这种注释建议删掉,如果这个解决方案的确还有疑问的话可能放在个人的开发分支上会比较合适些。

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已删掉

Comment thread drivers/iommu/riscv/iommu.c Outdated
* a barrier is required; additionally, the dma_wmb primitive is
* selected to avoid potential race conditions between
* the IOMMU and the CPU.
* An out-of-tree bugfix that may require future updates.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

“An out-of-tree bugfix that may require future updates.” 同理

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已删掉

@unicornx

unicornx commented Jul 1, 2026

Copy link
Copy Markdown

ommit 的 title 中的前缀请遵守上游 patch 的习惯,采用 “iommu/riscv: ”,注意前缀和描述之间要加空格。

BTW:我看 rvck-6.6 已经重新 rebase 了,请你修改后也重新 rebase 一下,不然这个 PR 里改动看上去太多了。

谢谢

@GooTal GooTal changed the title drivers/iommu:riscv:add dma_wmb before cmpxchg_relaxed iommu/riscv: add dma_wmb before cmpxchg_relaxed Jul 1, 2026
@GooTal
GooTal force-pushed the pr-iommu-dma_wmb branch from 1b80137 to 0f12397 Compare July 1, 2026 08:30
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

开始测试 log: https://github.com/RVCK-Project/rvck/actions/runs/28504331254

参数解析结果
args value
repository RVCK-Project/rvck
head ref pull/309/head
base ref rvck-6.6
LAVA repo RVCK-Project/lavaci
LAVA hardware ['qemu']
LAVA Testcase path lava-testcases/common-test/ltp/ltp.yaml
need run job kunit-test,kernel-build,check-patch,lava-trigger

测试完成

详细结果:
check result
kunit-test success
kernel-build success
check-patch failure
lava-trigger-qemu success
lava-trigger-sg2042 skipped
lava-trigger-k1 skipped
lava-trigger-lpi4a skipped

Kunit Test Result

[08:35:09] Testing complete. Ran 482 tests: passed: 466, skipped: 16

Kernel Build Result

Check Patch Result

Total Errors 60694
Total Warnings 121935

LAVA Check (qemu)

args value
testcase_repo RVCK-Project/lavaci
lava_template lava-job-template/qemu/qemu-ltp.yaml
testcase_path lava-testcases/common-test/ltp/ltp.yaml
kernel_download_url http://10.30.190.110/openEuler-RISC-V/RVCK/OERV-RVCI/RVCK-Project/rvck/309_28504331254_1/Image
initramfs_download_url http://10.30.190.110/openEuler-RISC-V/RVCK/OERV-RVCI/RVCK-Project/rvck/309_28504331254_1/initramfs.img
rootfs_download_url https://fast-mirror.isrc.ac.cn/openeuler-sig-riscv/openEuler-RISC-V/RVCK/openEuler24.03-LTS-SP1/openeuler-rootfs.img.zst
testcase_ref main
testitem_name RVCK-Project_rvck_pull_request_target_309__common-test_qemu

result: Lava check done!

@GooTal
GooTal force-pushed the pr-iommu-dma_wmb branch from 0f12397 to 9db45c1 Compare July 1, 2026 08:41
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

开始测试 log: https://github.com/RVCK-Project/rvck/actions/runs/28504963822

参数解析结果
args value
repository RVCK-Project/rvck
head ref pull/309/head
base ref rvck-6.6
LAVA repo RVCK-Project/lavaci
LAVA hardware ['qemu']
LAVA Testcase path lava-testcases/common-test/ltp/ltp.yaml
need run job kunit-test,kernel-build,check-patch,lava-trigger

测试完成

详细结果:
check result
kunit-test success
kernel-build success
check-patch success
lava-trigger-qemu success
lava-trigger-sg2042 skipped
lava-trigger-k1 skipped
lava-trigger-lpi4a skipped

Kunit Test Result

[08:46:42] Testing complete. Ran 482 tests: passed: 465, skipped: 17

Kernel Build Result

Check Patch Result

Total Errors 0
Total Warnings 0

LAVA Check (qemu)

args value
testcase_repo RVCK-Project/lavaci
lava_template lava-job-template/qemu/qemu-ltp.yaml
testcase_path lava-testcases/common-test/ltp/ltp.yaml
kernel_download_url http://10.30.190.110/openEuler-RISC-V/RVCK/OERV-RVCI/RVCK-Project/rvck/309_28504963822_1/Image
initramfs_download_url http://10.30.190.110/openEuler-RISC-V/RVCK/OERV-RVCI/RVCK-Project/rvck/309_28504963822_1/initramfs.img
rootfs_download_url https://fast-mirror.isrc.ac.cn/openeuler-sig-riscv/openEuler-RISC-V/RVCK/openEuler24.03-LTS-SP1/openeuler-rootfs.img.zst
testcase_ref main
testitem_name RVCK-Project_rvck_pull_request_target_309__common-test_qemu

result: Lava check done!

@GooTal

GooTal commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

ommit 的 title 中的前缀请遵守上游 patch 的习惯,采用 “iommu/riscv: ”,注意前缀和描述之间要加空格。

BTW:我看 rvck-6.6 已经重新 rebase 了,请你修改后也重新 rebase 一下,不然这个 PR 里改动看上去太多了。

谢谢

已更新

@unicornx

unicornx commented Jul 6, 2026

Copy link
Copy Markdown

@GooTal 你好,我尝试用 qemu 测试一下 iommu 的启动,我参考了 #114 但是没有成功,能否给个更详细的启动流程和命令说明参考一下?

另外,构建 rvck 内核时用默认的 defconfig 就可以吗,是否还需要其他额外配置?

@unicornx

unicornx commented Jul 6, 2026

Copy link
Copy Markdown

@GooTal 你好,我尝试用 qemu 测试一下 iommu 的启动,我参考了 #114 但是没有成功,能否给个更详细的启动流程和命令说明参考一下?

另外,构建 rvck 内核时用默认的 defconfig 就可以吗,是否还需要其他额外配置?

请忽略这个问题,我发现必须要写成 -device riscv-iommu-pci,vendor-id=0x1efd,device-id=0x8 才可以启动,原先我参考 qemu 的文档用的 -device riscv-iommu-pci,vendor-id=0x1efd,device-id=0xedf1。还没搞懂这个 device-id 为何有影响。

driver inclusion
category: bugfix
Link: RVCK-Project#308

--------------------------------

When using NVMe for PCIe peripherals on an RV multi-core CPU with IOMMU
enabled, the command `fio --filename=/dev/nvme0n1 --ioengine=libaio
--direct=1 --iodepth=256 --numjobs=8 --group_reporting=1 --bs=1M
--time_based=1 --runtime=2 --rw=read --name=test_read_8 --thread=1`
resulted a fault 15 exception during IOMMU testing.

When multiple cores modify iommu page talbe simultaneously, executing
riscv_iommu_map_pages or riscv_iommu_pte_alloc, an out-of-order iommu
page table clearing problem can occur due to a memory barrier missing.
It caused PTE being incorrectly cleared.

Setting dma_wmb ensures that all previous DMA write operations have
been completed before cmpxchg_relaxed.

This issue is relatively rare and may only occur during stress testing.

Signed-off-by: bailu <bai.lu5@zte.com.cn>
Signed-off-by: liuqingtao <liu.qingtao2@zte.com.cn>
@GooTal
GooTal force-pushed the pr-iommu-dma_wmb branch from 9db45c1 to a71ca51 Compare July 9, 2026 03:49
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

开始测试 log: https://github.com/RVCK-Project/rvck/actions/runs/28992666612

参数解析结果
args value
repository RVCK-Project/rvck
head ref pull/309/head
base ref rvck-6.6
LAVA repo RVCK-Project/lavaci
LAVA hardware ['qemu']
LAVA Testcase path lava-testcases/common-test/ltp/ltp.yaml
need run job kunit-test,kernel-build,check-patch,lava-trigger

测试完成

详细结果:
check result
kunit-test success
kernel-build success
check-patch success
lava-trigger-qemu success
lava-trigger-sg2042 skipped
lava-trigger-k1 skipped
lava-trigger-lpi4a skipped

Kunit Test Result

[03:54:20] Testing complete. Ran 482 tests: passed: 465, skipped: 17

Kernel Build Result

Check Patch Result

Total Errors 0
Total Warnings 0

LAVA Check (qemu)

args value
testcase_repo RVCK-Project/lavaci
lava_template lava-job-template/qemu/qemu-ltp.yaml
testcase_path lava-testcases/common-test/ltp/ltp.yaml
kernel_download_url http://10.30.190.110/openEuler-RISC-V/RVCK/OERV-RVCI/RVCK-Project/rvck/309_28992666612_1/Image
initramfs_download_url http://10.30.190.110/openEuler-RISC-V/RVCK/OERV-RVCI/RVCK-Project/rvck/309_28992666612_1/initramfs.img
rootfs_download_url https://fast-mirror.isrc.ac.cn/openeuler-sig-riscv/openEuler-RISC-V/RVCK/openEuler24.03-LTS-SP1/openeuler-rootfs.img.zst
testcase_ref main
testitem_name RVCK-Project_rvck_pull_request_target_309__common-test_qemu

result: Lava check done!

@sterling-teng

Copy link
Copy Markdown
Contributor

已经合并到rvck-6.6.

@sterling-teng
sterling-teng merged commit 6e2f72b into RVCK-Project:rvck-6.6 Jul 9, 2026
53 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

设置dma_wmb,确保在cmpxchg_relaxed前,所有之前的 DMA 写操作都已完成。

5 participants