feat(kernel): Check interrupt-disabled context in RT_DEBUG_SCHEDULER_…#11315
feat(kernel): Check interrupt-disabled context in RT_DEBUG_SCHEDULER_…#11315wdfk-prog wants to merge 1 commit intoRT-Thread:masterfrom
Conversation
|
👋 感谢您对 RT-Thread 的贡献!Thank you for your contribution to RT-Thread! 为确保代码符合 RT-Thread 的编码规范,请在你的仓库中执行以下步骤运行代码格式化工作流(如果格式化CI运行失败)。 🛠 操作步骤 | Steps
完成后,提交将自动更新至 如有问题欢迎联系我们,再次感谢您的贡献!💐 |
|
这个 pr 要测试下,能否给个简单的测试用例,我压测一下 |
|
@BernardXiong 熊大也看看,不知道 smart 那边是否会有关闭中断后还允许调度的行为 |
rt_base_t irq_flag;
irq_flag = rt_hw_interrupt_disable();
//执行文件系统操作
rt_mutex_take
rt_mutex_release
rt_hw_interrupt_enable(irq_flag);
//会触发断言
if (mutex->owner == thread)
{
/**
* get mutex successfully
* Note: assert to avoid an unexpected resume
*/
RT_ASSERT(thread->error == RT_EOK);
} |
There was a problem hiding this comment.
Pull request overview
This PR strengthens RT-Thread kernel debug context checking by treating “thread context but globally interrupts disabled” as an invalid context for potentially blocking/scheduling code paths, via an added rt_hw_interrupt_is_disabled() check in RT_DEBUG_SCHEDULER_AVAILABLE().
Changes:
- Extend
RT_DEBUG_SCHEDULER_AVAILABLE()to also fail when global IRQs are disabled. - Tighten precondition checking for IPC/synchronization primitives that rely on
RT_DEBUG_SCHEDULER_AVAILABLE(...)to prevent entering suspend/schedule/timeout paths in an IRQ-disabled region.
Comments suppressed due to low confidence (2)
include/rtthread.h:880
- [bug/错误]: Semantics are now split between
RT_DEBUG_SCHEDULER_AVAILABLE()andrt_scheduler_is_available().
English: This macro now treats “IRQ globally disabled” as “scheduler not available”, but the inline helper rt_scheduler_is_available() in the same header still returns true when in thread context with interrupts disabled. Callers that rely on rt_scheduler_is_available() to decide whether it is safe to take mutexes or delay (e.g. SPI/ULog code paths) can still enter blocking APIs while IRQs are disabled. Consider aligning rt_scheduler_is_available() with the new definition (and updating the nearby comment to include the IRQ-enabled requirement) to keep a single, consistent notion of “scheduler available”.
中文:目前“调度器可用”的语义被拆成了两套:该调试宏新增了“全局关中断”判定,但同文件的 rt_scheduler_is_available() 仍可能在“线程上下文但已关中断”时返回真。依赖 rt_scheduler_is_available() 来决定是否可以 rt_mutex_take()/rt_thread_delay() 的代码路径(如 SPI/ULog)仍可能在关中断场景进入阻塞接口。建议同步更新 rt_scheduler_is_available()(并把上方注释也补充“需开中断”的条件),避免语义不一致。
if ((rt_critical_level() != 0) || rt_hw_interrupt_is_disabled()) \
{ \
rt_kprintf("Function[%s]: scheduler is not available\n", \
__FUNCTION__); \
RT_ASSERT(0) \
} \
RT_DEBUG_IN_THREAD_CONTEXT; \
} \
include/rtthread.h:880
- [maintainability/可维护性]: Check order may reduce diagnostic precision when scheduler hasn’t started or when in ISR.
English: RT_DEBUG_SCHEDULER_AVAILABLE() currently checks rt_critical_level()/rt_hw_interrupt_is_disabled() before RT_DEBUG_IN_THREAD_CONTEXT. If this macro is (mis)used before scheduler start or in interrupt context, it may now assert with “scheduler is not available” instead of the more specific messages from RT_DEBUG_IN_THREAD_CONTEXT (e.g., “shall not be used before scheduler start” / “shall not be used in ISR”). Consider calling RT_DEBUG_IN_THREAD_CONTEXT first, then checking critical/IRQ-disabled state, to keep the most actionable assertion message.
中文:该宏目前先检查 rt_critical_level()/rt_hw_interrupt_is_disabled(),再做 RT_DEBUG_IN_THREAD_CONTEXT。如果在调度器未启动或 ISR 中误用,可能会先触发“scheduler is not available”而不是更具体的报错信息。建议先执行 RT_DEBUG_IN_THREAD_CONTEXT,再检查 critical/关中断状态,以提升断言信息的可定位性。
if ((rt_critical_level() != 0) || rt_hw_interrupt_is_disabled()) \
{ \
rt_kprintf("Function[%s]: scheduler is not available\n", \
__FUNCTION__); \
RT_ASSERT(0) \
} \
RT_DEBUG_IN_THREAD_CONTEXT; \
} \
| if (need_check) \ | ||
| { \ | ||
| if (rt_critical_level() != 0) \ | ||
| if ((rt_critical_level() != 0) || rt_hw_interrupt_is_disabled()) \ |
There was a problem hiding this comment.
[bug/错误]: RT_DEBUG_SCHEDULER_AVAILABLE() now calls rt_hw_interrupt_is_disabled(), but include/rtthread.h does not include rthw.h (where it is declared) nor provide a forward declaration. This can break builds for translation units that use RT_DEBUG_SCHEDULER_AVAILABLE() without including <rthw.h> (e.g. components/drivers/ipc/condvar.c includes <rtthread.h> via <rtdevice.h> and calls this macro).
English: Please ensure rt_hw_interrupt_is_disabled() is visible wherever this macro can be used—either include <rthw.h> in rtthread.h (possibly gated by RT_DEBUGING_CONTEXT), or add an appropriate extern rt_bool_t rt_hw_interrupt_is_disabled(void); declaration in rtthread.h.
中文:RT_DEBUG_SCHEDULER_AVAILABLE() 新增了 rt_hw_interrupt_is_disabled() 调用,但 rtthread.h 既未包含声明它的 <rthw.h>,也未做前置声明。对于未显式包含 <rthw.h> 但使用该宏的编译单元(例如 components/drivers/ipc/condvar.c),这会导致编译失败。建议在 rtthread.h 中(可按 RT_DEBUGING_CONTEXT 条件编译)包含 <rthw.h> 或添加对应的 extern 声明。
| if (need_check) \ | ||
| { \ | ||
| if (rt_critical_level() != 0) \ | ||
| if ((rt_critical_level() != 0) || rt_hw_interrupt_is_disabled()) \ |
There was a problem hiding this comment.
[codebase_conventions/代码库规范]: PR title prefix format does not match the repo’s preferred [module][subsystem] ... style.
English: The current title uses feat(kernel): ..., while the documented convention (see .github/copilot-instructions.md) expects a lowercase bracket prefix like [kernel] ... or [kernel][sched] .... Please consider renaming the PR title to follow that format for consistency.
中文:当前 PR 标题使用了 feat(kernel): ...,但仓库约定(见 .github/copilot-instructions.md)更偏好小写的方括号前缀格式,如 [kernel] ... 或 [kernel][sched] ...。建议调整标题以保持一致性。
嗯,如果是这样的行为确实会有问题,关闭中断后尝试的 ipc 行为会导致无法进行上下文调度,这种行为也应该是在应用层要避免的😂 |
为什么提交这份PR (why to submit this PR)
修复
RT_DEBUG_SCHEDULER_AVAILABLE()对“调度器可用上下文”的判断不完整问题。当前实现仅检查:
rt_critical_level() == 0,即 scheduler lock 已释放;但它没有覆盖这样一种场景:
rt_hw_interrupt_disable()关闭。在这种情况下,代码路径表面上满足“线程上下文 + 非 scheduler lock”条件,但实际上已经不适合进入可能触发挂起、超时等待或调度切换的逻辑。对于
rt_mutex_take()、rt_sem_take()等阻塞型接口,这会放过一类非法调用场景,可能进一步导致状态不一致、异常断言或系统卡死。因此提交本 PR,在
RT_DEBUG_SCHEDULER_AVAILABLE()中补充rt_hw_interrupt_is_disabled()检查,使“scheduler available”的判定与实际运行约束保持一致。你的解决方案是什么 (what is your solution)
本 PR 仅做一处内核检查增强:
补充中断关闭状态检查
include/rtthread.h的RT_DEBUG_SCHEDULER_AVAILABLE()宏中,增加rt_hw_interrupt_is_disabled()判断;scheduler is not available。收紧阻塞型接口的上下文约束
RT_DEBUG_SCHEDULER_AVAILABLE(RT_TRUE)的 IPC / 同步原语接口,在“线程上下文但中断已关闭”的场景下尽早断言;提升问题定位效率
thread->error异常、owner 状态不一致或断言失败更容易定位。修改内容 (patch summary)
请提供验证的bsp和config (provide the config and bsp)
BSP:
bsp/stm32/...(请填写实际验证的 BSP 路径).config:
RT_USING_MUTEXRT_USING_SEMAPHORERT_DEBUGING_ASSERT建议验证场景:
rt_mutex_take(..., timeout),行为保持不变;rt_hw_interrupt_disable()保护区内调用可能阻塞的 IPC 接口,能够被前置断言及时捕获;timeout == 0的 try-take / 非阻塞路径是否符合预期;action:
当前拉取/合并请求的状态 Intent for your PR
必须选择一项 Choose one (Mandatory):
代码质量 Code Quality:
我在这个拉取/合并请求中已经考虑了 As part of this pull request, I've considered the following:
#if 0代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up.github/ALL_BSP_COMPILE.json