参考链接
Linux内核抢占机制(preempt)_Vance2016的博客-CSDN博客_preempt内核
linux 内核 禁止抢占,内核抢占实现(preempt)_weixin_39825322的博客-CSDN博客
为什么禁用中断会禁用内核抢占以及自旋锁如何禁用抢占
struct thread_info {
unsigned long flags; /* low level flags */
int preempt_count;
};
preempt_count可以用于禁止/开启内核抢占
上面的链接提到
禁止内核抢占的情况列出如下:
(1)内核执行中断处理例程时不允许内核抢占,中断返回时再执行内核抢占。
(2)当内核执行软中断或tasklet时,禁止内核抢占,软中断返回时再执行内核抢占。
(3)在临界区禁止内核抢占,临界区保护函数通过抢占计数宏控制抢占,计数大于0,表示禁止内核抢占。
抢占式内核实现的原理是在释放自旋锁时或从中断返回时,如果当前执行进程的 need_resched 被标记,则进行抢占式调度。
函数preempt_schedule_irq是出中断上下文时内核抢占调度的入口点,该函数被调用和返回时中断应关闭,保护此函数从中断递归调用
搜索函数preempt_schedule_irq发现如下代码:
#ifdef CONFIG_PREEMPT
get_thread_info tsk
ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
ldr r0, [tsk, #TI_FLAGS] @ get flags
teq r8, #0 @ if preempt count != 0
movne r0, #0 @ force flags to 0
tst r0, #_TIF_NEED_RESCHED
blne svc_preempt
感觉这段代码应该就是判断preempt count是否为0,如果不为就会跳转到svc_preempt
从而调用preempt_schedule_irq。
#endif
svc_exit r5, irq = 1 @ return from exception
否则就直接退出,不发生调度
UNWIND(.fnend )
ENDPROC(__irq_svc)
.ltorg
#ifdef CONFIG_PREEMPT
svc_preempt:
mov r8, lr
1: bl preempt_schedule_irq @ irq en/disable is done inside
ldr r0, [tsk, #TI_FLAGS] @ get new tasks TI_FLAGS
tst r0, #_TIF_NEED_RESCHED
moveq pc, r8 @ go again
b 1b
#endif
————————————————
版权声明:本文为CSDN博主「这个我好像学过」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_42693685/article/details/125754172