preempt_disable() and cond_resched()

临界区保护函数通过抢占计数宏控制抢占,计数大于0,表示禁止内核抢占。 

 

首先确认一点,  如果使用了preempt_disable(), 是不允许调用cond_resched的, 如果调用, schedule()应该会打印出错信息.
这个很好理解, cond_resched()的目的是提高系统实时性, 主动放弃cpu供优先级更高的任务使用, 如果调用了preempt_disable(), 不允许抢占, 就不应该调用有cond_resched()的函数.

2.6.28内核, schedule()会在这里捕获这个错误:
asmlinkage void __sched schedule(void)
{
        struct task_struct *prev, *next;
        unsigned long *switch_count;
        struct rq *rq;
        int cpu;

need_resched:
        preempt_disable();
        cpu = smp_processor_id();
        rq = cpu_rq(cpu);
        rcu_qsctr_inc(cpu);
        prev = rq->curr;
        switch_count = &prev->nivcsw;

        release_kernel_lock(prev);
need_resched_nonpreemptible:

        schedule_debug(prev);
...

static inline void schedule_debug(struct task_struct *prev)
{
       /* 如果preempt值不等于1, 说明出错, 等于1而不是0是因为schedule()中要关闭抢占, 在上面有这句 */
        if (unlikely(in_atomic_preempt_off() && !prev->exit_state))
                __schedule_bug(prev);


怎么解决这个preempt_disable()和cond_resched()的冲突?
preempt_disable()是一个最底层的接口,  如果你要使用这个接口关抢占, 必须要熟悉会调用cond_resched()的函数, 或者知道如何调试这个bug, 这种bug发现和解决应该不难.
一般都是通过mutex, spinlock, 关中断, 关软中断等方法, 顺带关抢占. 如果是上面的几种情况, 最新的内核提供:
extern int cond_resched_lock(spinlock_t * lock);
extern int cond_resched_softirq(void);
static inline int cond_resched_bkl(void);
来代替cond_resched(), 使得在不同情况下使用更安全.

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值