c - disable_local_irq 和内核定时器

标签 c linux timer linux-kernel

在对我们的一些驱动程序进行 SMP 移植时(在 powerpc 目标)我们观察到一些行为,我需要你们 阐明一些光:

  1. 在 UP 系统上执行 local_irq_disable() 时,jiffies 倾向于 卡住即计数停止递增。这是预期的吗?我想 递减器中断是“内部的”,不应该得到 受 local_irq_disable() 类关闭调用的影响,因为我预计它会 禁用本地 IRQ 中断处理(外部中断)。这 系统当然也会在执行 local_irq_enable() 时卡住 jiffies 计数跳跃,它似乎在补偿“时间” 在 local_irq_disable()enable() 调用之间“失效”。

  2. 在 SMP 系统(具有 2 个 e500 内核的 P2020)上执行相同操作 结果令人惊讶。首先是要插入的模块 此测试始终在核心 1 上执行。此外,它有时会执行 没有看到“jiffies”计数器卡住,有时我们看到它 确实卡住了。同样,在计数卡住的情况下,它往往会跳跃 在执行 local_irq_enable() 之后。我不知道为什么会这样 正在发生。
    我们知道在 SMP 的情况下,两个内核都运行调度计时器吗? 在某些情况下,我们没有看到 jiffies 计数的卡住,或者是 就在核心 0 上?

此外,由于内核计时器依赖于“jiffies”——这意味着 如果 local_irq_disable() 已经关闭,我们的内核定时器都不会触发 完毕?如果这是在一个核心中的一个上完成的,那会是什么情况? SMP系统?

还有很多其他问题,但我想这些就足够了 开始关于相同的一般性讨论:)

TIA

自然科学

来自已完成实验的更多评论。

我目前的理解是,由于内核计时器依赖于“jiffies”来触发,所以当我发出 local_irq_save() 时,它们实际上不会在 UP 系统上触发。事实上,我们的一些代码是基于这样的假设,即当我发出 local_irq_save() 时,它也保证了对本地处理器和内核计时器的中断保护。

然而,在 SMP 系统上进行相同的实验,即使两个内核都执行 local_irq_save(),jiffies 也不会停止递增,系统也不会卡住。这怎么可能 ? LINUX 是否使用其他机制来触发 SMP 系统中的定时器中断或可能使用 IPI?这也打破了我们的假设,即 local_irq_disable() 将保护系统免受至少在同一内核上运行的内核计时器的影响。

我们如何着手编写对异步事件(即中断和内核计时器)安全并且对 UP 和 SMP 都有效的代码。

最佳答案

local_irq_disable 仅禁用当前内核上的中断,因此,当您是单核时,所有内容都被禁用(包括定时器中断),这就是 jiffies 不更新的原因。 在 SMP 上运行时,有时您会碰巧禁用更新 jiffies 的核心中断,有时则不会。 这通常不是问题,因为中断应该只在很短的时间内被禁用,并且所有计划的定时器都会在中断再次启用后触发。

你怎么知道你的模块总是在核心 1 上运行?在当前版本的内核中,它甚至可能同时在多个内核上运行(也就是说,如果您没有强制它不要这样做的话)。

关于c - disable_local_irq 和内核定时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6519663/

相关文章:

java - 如何获取 java.util.Timer 中的剩余时间?

c - 指针和函数

c - 必须有更好的方法来 substr

c - APUE的线程同步问题

C - 在非托管 DLL 中导入和访问函数

linux - 将当前的 firefox/chrome URL 存储在文件中

linux - Bash:从文本文件 VAR=VALUE 格式读取变量

c# - Windows服务中的多线程

Linux tcp 服务器无法绑定(bind)到 close_wait 端口

c# - 是什么让我的计时器运行不准确?