【问题标题】:ARM GIC Interrupt starvationARM GIC 中断饥饿
【发布时间】:2016-05-16 07:20:34
【问题描述】:

不确定是否有类似的问题。我试图回读但找不到任何内容,所以在这里。

在我使用 ARM Cortex-A9(带 GIC 的双核)的裸机应用程序中,一些中断源是 4 个 FPGA 中断(比如 IRQ ID 58、59、60、61),它们具有相同的优先级和这个想法是所有同时在运行时连续触发。我可以说中断处理程序可能符合条件,但不会很长。

所有中断都会触发并被 GIC 检测到,并且都标记为 PENDING。问题是,只有两个较高 ID 的中断(58、59)由 CPU 处理,而其他两个中断。一旦 58 或 59 完成,它们的源将再次触发并一遍又一遍地抢占 CPU。我的其他中断无限期地被饿死了。

我玩弄了优先级,将更高的中断分配给 60 和 61。果然,60 和 61 触发并由 CPU 处理,但 58 和 59 被饿死了。所以这确实是一个饥饿的问题。

有没有办法离开这里,使得其他两个仍然会被处理,因为它们的触发率?

【问题讨论】:

    标签: arm interrupt interrupt-handling


    【解决方案1】:

    假设 GIC 实现是 ARM 的设计之一,那么相同优先级的多个中断的仲裁方案固定为“调度最低编号的中断”,所以如果您希望它可以更改为某种轮-robin 计划你可能不走运。

    也就是说,如果这些中断或多或少是永久断言的,并且您将它们背靠背地使用,那么这表明您可能不需要使用中断,或者至少不需要使用您的代码设计是不合适的。根据任务的具体性质,我会考虑以下一些想法:

    • 只需运行一个连续轮询循环,依次循环通过每个设备。如果有 个时段,每个设备可能不需要服务,并且不容易判断,请保留一个简单的中断处理程序,它只是以原子方式设置标志/序列号/等。通知循环谁准备好了。
    • 在一个内核上处理所有中断,在另一个内核上进行实际处理。处理程序只是抓取必要的数据,将其放入队列中,然后尽快返回,而其他人只是稳定地浏览队列。
    • 如果捕获每一个中断不如平均获得“足够”的每一个中断重要,那么在处理它之后让每一个中断都禁用一个合适的超时。或者,通过一次仅启用一个来破坏您自己的循环调度,并且处理程序重新启用 下一个 中断而不是刚刚发生的中断。

    【讨论】:

      【解决方案2】:

      在我使用 ARM Cortex-A9(带 GIC 的双核)的裸机应用程序中...


      有没有办法离开这里,使得其他两个在触发率下仍然会被处理?

      当然有很多方法。

      1. 您有一个双 CPU,因此您可以将一组路由到每个 CPU; 58/59 到 CPU0 和 60/61 到 CPU1。目前尚不清楚您是如何处理分发器或每个 CPU 接口的事情的。
      2. 第 2nd 方法是仅读取 60/61 的 58/59 处理程序中的状态并完成工作。即,您始终可以从 IRQ 处理程序中读取另一个中断的状态。
      3. 您还可以在确认原始源之前为 IRQ 开始处记录的每个挂起的中断提供服务。在 IRQ 控制器层实现的“2”的变体。

      我相信这些解决方案中的大多数都避免了不必要的上下文保存/恢复,并且应该更有效。

      当然,如果您要求 CPU 完成超出其处理能力的工作,优先级无关紧要。问题可能是您的代码效率不高;裸机中断基础设施或您的 FPGA IRQ 处理程序。 FPGA到CPU的接口也很可能设计得不好。您可能需要在 FPGA 中添加 FIFO 来缓冲数据,以便 CPU 一次可以处理更多数据。我曾与几位 FPGA 设计师合作过。他们有很大的灵活性,通常如果你要求一些可以提高 IRQ 处理程序效率的东西,他们可以实现它。

      【讨论】:

        猜你喜欢
        • 2017-12-15
        • 2017-01-07
        • 2010-11-12
        • 2012-07-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多