其实内核源码对此也有明确的注释:might_sleep - annotation for functions that can sleep。所以对于release版的kernel image而言,might_sleep的作用仅仅是一个annotation,提醒使用者,一个使用might_sleep的函数在其后的代码执行中可能会sleep。 不过如果有调试需求介入的话,比如你的系统莫名其妙地随机性地crash掉,在经过...
这里首先会调用might_sleep()一直睡眠,进行减少检查sem->count,如果当前sem->count的值是负数(说明减少前是0或者负数)就挂起,这时并没有真正获得信号量,会调用__down函数; 如果检查没问题之后,在汇编上调用__down_failed,即指令call __down_failed。 fastcall void __down_failed(void /* special register calli...
这里的might_sleep说明调用mutex_lock函数有可能会因为未能获取到mutex锁而进入阻塞状态。在原子上下文中(中断上下文、软中断上下文、持有自旋锁、禁止抢占等),我们不能调用可以引起阻塞的函数,因此在might_sleep函数中嵌入了这个检查,当原子上下文中调用mutex_lock函数的时候,内核会打印出内核栈的信息,从而定位这个异常。
如果使能CONFIG_PREEMPT,那么CPU运行于内核态运行的时候也是能抢占的(也并非所有内核代码处都能被抢占,临界区是不能被抢占的),当从中断处理返回的时候会触发一次重新调度。 如果编译的时候使能了CONFIG_PREEMPT_VOLUNTARY宏,那么在内核中调用might_sleep的时候就会调用到_cond_resched。 自愿抢占是介于CONFIG_PREEMPT与CON...
自愿内核抢占模型使用宏might_sleep()在内核里面增加抢占点,例如在函数mutex_lock()里面增加抢占点,如下。 kernel/locking/mutex.c void __sched mutex_lock(struct mutex *lock) { might_sleep(); if (!__mutex_trylock_fast(lock)) __mutex_lock_slowpath(lock); ...
mutex_lock()函数调用might_sleep()函数判断锁的状态,调用__mutex_trylock_fast()函数尝试快速获取mutex锁,如果失败,则调用__mutex_lock_slowpath()函数获取mutex锁 void__schedmutex_lock(structmutex *lock){ might_sleep();if(!__mutex_trylock_fast(lock)) ...
void__schedmutex_lock(structmutex*lock) {might_sleep();__mutex_fastpath_lock(&lock->count,__mutex_lock_slowpath);mutex_set_owner(lock); } 我们可以从include/linux/kernel.h头文件的mutex_lock函数开头看到might_sleep宏被调用。该宏的实现取决于CONFIG_DEBUG_ATOMIC_SLEEP内核配置选项,如果这个选项被启...
might_sleep; /*fastpath*/ if(!__mutex_trylock_fast(lock)) /*midpath and slowpath*/ __mutex_lock_slowpath(lock); } __mutex_trylock_fast(lock) -> atomic_long_try_cmpxchg_acquire(&lock->owner, &zero, curr) -> atomic64_try_cmpxchg_acquire(v, (s64 *)old,new); ...
/*不可中断的获取锁*/void__schedmutex_lock(struct mutex*lock){might_sleep();/*fastpath*/if(!__mutex_trylock_fast(lock))/*midpath and slowpath*/__mutex_lock_slowpath(lock);}__mutex_trylock_fast(lock)->atomic_long_try_cmpxchg_acquire(&lock->owner,&zero,curr)->atomic64_try_cmpxchg_ac...
其中lockdep_trace_alloc()需要CONFIG_TRACE_IRQFLAGS和CONFIG_PROVE_LOCKING同时定义的时候,才起作用,否则为空函数;如果申请页面传入的gfp_mask掩码携带__GFP_WAIT标识,表示允许页面申请时休眠,则会进入might_sleep_if()检查是否需要休眠等待以及重新调度;由于未设置CONFIG_FAIL_PAGE_ALLOC,则should_fail_alloc_page(...