Skip to content

fix(aarch64): remove redundant pending clear in GIC ack - #11860

Open
Xenithya wants to merge 1 commit into
RT-Thread:masterfrom
Xenithya:fix/aarch64-gic-ack
Open

Xenithya wants to merge 1 commit into
RT-Thread:masterfrom
Xenithya:fix/aarch64-gic-ack

Conversation

@Xenithya

@Xenithya Xenithya commented Oct 9, 2026

Copy link
Copy Markdown

拉取/合并请求描述:(PR description)

[

为什么提交这份PR (why to submit this PR)

arm_gic_ack() currently clears the interrupt pending state through GIC_DIST_PENDING_CLEAR before writing the interrupt ID to GIC_CPU_EOI.

This change removes the explicit pending-clear operation and its now-unused mask variable, leaving the CPU interface EOI write as the interrupt acknowledgment operation.

你的解决方案是什么 (what is your solution)

Remove the GIC_DIST_PENDING_CLEAR write and the unused mask variable from arm_gic_ack().

请提供验证的bsp和config (provide the config and bsp)

  • BSP:
  • .config:
  • action:

]

当前拉取/合并请求的状态 Intent for your PR

必须选择一项 Choose one (Mandatory):

  • 本拉取/合并请求是一个草稿版本 This PR is for a code-review and is intended to get feedback
  • 本拉取/合并请求是一个成熟版本 This PR is mature, and ready to be integrated into the repo

代码质量 Code Quality:

我在这个拉取/合并请求中已经考虑了 As part of this pull request, I've considered the following:

  • 已经仔细查看过代码改动的对比 Already check the difference between PR and old code
  • 代码风格正确,包括缩进空格,命名及其他风格 Style guide is adhered to, including spacing, naming and other styles
  • 没有垃圾代码,代码尽量精简,不包含#if 0代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up
  • 所有变更均有原因及合理的,并且不会影响到其他软件组件代码或BSP All modifications are justified and not affect other components or BSP
  • 对难懂代码均提供对应的注释 I've commented appropriately where code is tricky
  • 代码是高质量的 Code in this PR is of high quality
  • 已经使用clang-format 源码格式化工具确保格式符合RT-Thread代码规范 This PR has been formatted with clang-format and complies with RT-Thread code specification
  • 如果是新增bsp, 已经添加ci检查到.github/ALL_BSP_COMPILE.json 详细请参考链接BSP自查

@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown

👋 感谢您对 RT-Thread 的贡献!Thank you for your contribution to RT-Thread!

为确保代码符合 RT-Thread 的编码规范,请在你的仓库中执行以下步骤运行代码格式化工作流(如果格式化CI运行失败)。
To ensure your code complies with RT-Thread's coding style, please run the code formatting workflow by following the steps below (If the formatting of CI fails to run).


🛠 操作步骤 | Steps

  1. 前往 Actions 页面 | Go to the Actions page
    点击进入工作流 → | Click to open workflow →

  2. 点击 Run workflow | Click Run workflow

  • Use workflow from 保持默认分支(通常为 master)
    Keep the default branch (usually master) in Use workflow from
  • 在 branch 输入框填写 PR 分支 fix/aarch64-gic-ack
    Enter PR branch fix/aarch64-gic-ack in the branch field
  • 设置需排除的文件/目录(目录请以"/"结尾)
    Set files/directories to exclude (directories should end with "/")
  1. 等待工作流完成 | Wait for the workflow to complete
    格式化后的代码将作为独立提交推送至你的分支。
    The formatting changes will be pushed to your branch as a separate commit.

完成后,提交将自动更新至 fix/aarch64-gic-ack 分支,关联的 Pull Request 也会同步更新。
Once completed, commits will be pushed to the fix/aarch64-gic-ack branch automatically, and the related Pull Request will be updated.

如有问题欢迎联系我们,再次感谢您的贡献!💐
If you have any questions, feel free to reach out. Thanks again for your contribution!

@github-actions github-actions Bot added Arch: ARM/AArch64 BSP related with arm libcpu labels Oct 9, 2026
@GuEe-GUI

Copy link
Copy Markdown
Contributor

意思是都 EOI 了就没必要 ACK 了么?

@Xenithya

Copy link
Copy Markdown
Author

这个 PR 删的不是 ACK,也不是 EOI,而是旧 arm_gic_ack 在 EOI 之前多写的一笔 GICD_ICPENDR(清 pending)。这笔写是错的:处理期间若同一边沿中断源又来了新事件(典型如 NPU 先报 AXI 错误、紧接着报 done),GIC 会重新锁存 pending,这笔 ICPENDR 会把它抹掉,导致新中断永久丢失。实测:删掉它,纯中断路径 48 万次推理 0 失败;加上它,1933 次推理必现一次完成中断丢失。

@GuEe-GUI

Copy link
Copy Markdown
Contributor

看了一下,arm_gic_ack 是对的,rt_hw_interrupt_ack 的用法不对,在 ISR 之后再调用会出问题,那还是建议改 traps.c 中的用法。

@Xenithya

Copy link
Copy Markdown
Author

arm_gic_ack() 这个名字其实有误导性——它做的是 EOI(写 GICC_EOIR),不是 ACK。GIC 的中断处理是两件事:

  • ACK(读 GICC_IAR):在 ISR 之前,拿中断号、把 pending 转 active。这在 rt_hw_interrupt_get_irq() → arm_gic_get_active_irq() 里,已经做了,本 PR 未改动。
  • EOI(写 GICC_EOIR):在 ISR 之后,把 active 清掉。arm_gic_ack() 在 ISR 之后被调用是正确的,EOI 本就应该在这里,不能挪到 ISR 之前。

真正的问题是:arm_gic_ack() 除了写 EOI,还多写了一笔 GICD_ICPENDR(清 pending)。这笔写个人认为既没必要(读 IAR 时 pending 已被硬件清除),又有害——ISR 执行期间若同一边沿中断源又来了新事件,GIC 会重新锁存 pending,这笔 ICPENDR 会把它抹掉,导致新中断永久丢失。

@GuEe-GUI

GuEe-GUI commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

是 ACK 的意思,只是 GIC 有两种模式,一个 EOI 模式,一个是非 EOI,RTOS通常用非 EOI 模式,所以看上去语义很奇怪,你可以看看其他操作系统比如Linux的写法。
当然这块如果修改trap.c得写法能解决问题我还是建议改trap.c的(ISR 之前 ACK 试试看是否还会有问题):

ir = rt_hw_interrupt_get_irq();
if (ir == 1023)
{
/* Spurious interrupt */
return;
}
/* bit 10~12 is cpuid, bit 0~9 is interrupt id */
ir_self = ir & 0x3ffUL;
/* get interrupt service routine */
isr_func = isr_table[ir_self].handler;
#ifdef RT_USING_INTERRUPT_INFO
isr_table[ir_self].counter++;
#ifdef RT_USING_SMP
isr_table[ir_self].cpu_counter[rt_hw_cpu_id()]++;
#endif
#endif
if (isr_func)
{
/* Interrupt for myself. */
param = isr_table[ir_self].param;
/* turn to interrupt service routine */
isr_func(ir_self, param);
}
/* end of interrupt */
rt_hw_interrupt_ack(ir);

@Xenithya

Copy link
Copy Markdown
Author

稍等,这两天再测试一下trap.c的改法

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Arch: ARM/AArch64 BSP related with arm libcpu

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants